* [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode
@ 2013-05-29 6:10 Rajeshwari Shinde
2013-05-29 6:10 ` [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes Rajeshwari Shinde
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Rajeshwari Shinde @ 2013-05-29 6:10 UTC (permalink / raw)
To: u-boot
This patch set enables PREAMBLE Mode for EXYNOS SPI.
Changes in v2:
- Remove preamable_count variable which is not really needed
- Fix checkpatch warning (multiple assignments)
Changes in V3:
- Modified the if logic in spi_rx_tx function
- Added blank lines as suggested by Minkyu Kang.
- Removed in_bytes check in while loop.
- Added a error check.
Changes in V4:
- Corrected a if condition.
Changes in V5:
- In commit message header changed
SPI to spi
EXYNOS: SPI: to spi: exynos:
Rajeshwari Shinde (2):
spi: Add support for preamble bytes
spi: exynos: Support SPI_PREAMBLE mode
drivers/spi/exynos_spi.c | 69 +++++++++++++++++++++++++++++++++++++++------
include/spi.h | 5 +++
2 files changed, 64 insertions(+), 10 deletions(-)
--
1.7.4.4
^ permalink raw reply [flat|nested] 14+ messages in thread* [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes 2013-05-29 6:10 [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode Rajeshwari Shinde @ 2013-05-29 6:10 ` Rajeshwari Shinde 2013-06-02 17:24 ` Jagan Teki ` (2 more replies) 2013-05-29 6:10 ` [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode Rajeshwari Shinde 2013-05-30 4:38 ` [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode Simon Glass 2 siblings, 3 replies; 14+ messages in thread From: Rajeshwari Shinde @ 2013-05-29 6:10 UTC (permalink / raw) To: u-boot A SPI slave may take time to react to a request. For SPI flash devices this time is defined as one bit time, or a whole byte for 'fast read' mode. If the SPI slave is another CPU, then the time it takes to react may vary. It is convenient to allow the slave device to tag the start of the actual reply so that the host can determine when this 'preamble' finishes and the actual message starts. Add a preamble flag to the available SPI flags. If supported by the driver then it will ignore any received bytes before the preamble on each transaction. This ensures that reliable communication with the slave is possible. Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> --- Changes in V2: - None Changes in V3: - None. Changes in V4: - None. Changes in V5: - In commit message header changed SPI to spi. include/spi.h | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/include/spi.h b/include/spi.h index 3fe2e1e..1638b50 100644 --- a/include/spi.h +++ b/include/spi.h @@ -37,11 +37,16 @@ #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ #define SPI_3WIRE 0x10 /* SI/SO signals shared */ #define SPI_LOOP 0x20 /* loopback mode */ +#define SPI_SLAVE 0x40 /* slave mode */ +#define SPI_PREAMBLE 0x80 /* Skip preamble bytes */ /* SPI transfer flags */ #define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */ #define SPI_XFER_END 0x02 /* Deassert CS after transfer */ +/* Header byte that marks the start of the message */ +#define SPI_PREAMBLE_END_BYTE 0xec + /*----------------------------------------------------------------------- * Representation of a SPI slave, i.e. what we're communicating with. * -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes 2013-05-29 6:10 ` [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes Rajeshwari Shinde @ 2013-06-02 17:24 ` Jagan Teki 2013-06-02 17:55 ` Simon Glass 2013-06-02 18:19 ` [U-Boot] [U-Boot,1/2,V5] " Jagan Teki 2013-06-02 18:38 ` Jagan Teki 2 siblings, 1 reply; 14+ messages in thread From: Jagan Teki @ 2013-06-02 17:24 UTC (permalink / raw) To: u-boot On Wed, May 29, 2013 at 11:40 AM, Rajeshwari Shinde <rajeshwari.s@samsung.com> wrote: > A SPI slave may take time to react to a request. For SPI flash devices > this time is defined as one bit time, or a whole byte for 'fast read' > mode. > > If the SPI slave is another CPU, then the time it takes to react may > vary. It is convenient to allow the slave device to tag the start of > the actual reply so that the host can determine when this 'preamble' > finishes and the actual message starts. > > Add a preamble flag to the available SPI flags. If supported by the > driver then it will ignore any received bytes before the preamble > on each transaction. This ensures that reliable communication with > the slave is possible. > > Signed-off-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > --- > Changes in V2: > - None > Changes in V3: > - None. > Changes in V4: > - None. > Changes in V5: > - In commit message header changed SPI to spi. > include/spi.h | 5 +++++ > 1 files changed, 5 insertions(+), 0 deletions(-) > > diff --git a/include/spi.h b/include/spi.h > index 3fe2e1e..1638b50 100644 > --- a/include/spi.h > +++ b/include/spi.h > @@ -37,11 +37,16 @@ > #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ > #define SPI_3WIRE 0x10 /* SI/SO signals shared */ > #define SPI_LOOP 0x20 /* loopback mode */ > +#define SPI_SLAVE 0x40 /* slave mode */ > +#define SPI_PREAMBLE 0x80 /* Skip preamble bytes */ > > /* SPI transfer flags */ > #define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */ > #define SPI_XFER_END 0x02 /* Deassert CS after transfer */ > > +/* Header byte that marks the start of the message */ > +#define SPI_PREAMBLE_END_BYTE 0xec I think this 0xec is a value of rx_data what does it indicates and does this value specific to hw? -- Thanks, Jagan. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes 2013-06-02 17:24 ` Jagan Teki @ 2013-06-02 17:55 ` Simon Glass 2013-06-02 18:00 ` Jagan Teki 0 siblings, 1 reply; 14+ messages in thread From: Simon Glass @ 2013-06-02 17:55 UTC (permalink / raw) To: u-boot Hi, On Sun, Jun 2, 2013 at 10:24 AM, Jagan Teki <jagannadh.teki@gmail.com>wrote: > On Wed, May 29, 2013 at 11:40 AM, Rajeshwari Shinde > <rajeshwari.s@samsung.com> wrote: > > A SPI slave may take time to react to a request. For SPI flash devices > > this time is defined as one bit time, or a whole byte for 'fast read' > > mode. > > > > If the SPI slave is another CPU, then the time it takes to react may > > vary. It is convenient to allow the slave device to tag the start of > > the actual reply so that the host can determine when this 'preamble' > > finishes and the actual message starts. > > > > Add a preamble flag to the available SPI flags. If supported by the > > driver then it will ignore any received bytes before the preamble > > on each transaction. This ensures that reliable communication with > > the slave is possible. > > > > Signed-off-by: Simon Glass <sjg@chromium.org> > > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > > --- > > Changes in V2: > > - None > > Changes in V3: > > - None. > > Changes in V4: > > - None. > > Changes in V5: > > - In commit message header changed SPI to spi. > > include/spi.h | 5 +++++ > > 1 files changed, 5 insertions(+), 0 deletions(-) > > > > diff --git a/include/spi.h b/include/spi.h > > index 3fe2e1e..1638b50 100644 > > --- a/include/spi.h > > +++ b/include/spi.h > > @@ -37,11 +37,16 @@ > > #define SPI_LSB_FIRST 0x08 /* per-word > bits-on-wire */ > > #define SPI_3WIRE 0x10 /* SI/SO signals > shared */ > > #define SPI_LOOP 0x20 /* loopback mode > */ > > +#define SPI_SLAVE 0x40 /* slave mode */ > > +#define SPI_PREAMBLE 0x80 /* Skip preamble > bytes */ > > > > /* SPI transfer flags */ > > #define SPI_XFER_BEGIN 0x01 /* Assert CS before > transfer */ > > #define SPI_XFER_END 0x02 /* Deassert CS after > transfer */ > > > > +/* Header byte that marks the start of the message */ > > +#define SPI_PREAMBLE_END_BYTE 0xec > > I think this 0xec is a value of rx_data what does it indicates and > does this value specific to hw? > We have a later change which generalises this using the device tree, but it is dependent on various other patches and adjusts the generic SPI interface. If we can get this one in then I'm sure Vadim will supply a new patch for consideration. > -- > Thanks, > Jagan. > Regards, Simon ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes 2013-06-02 17:55 ` Simon Glass @ 2013-06-02 18:00 ` Jagan Teki 2013-06-02 18:03 ` Simon Glass 0 siblings, 1 reply; 14+ messages in thread From: Jagan Teki @ 2013-06-02 18:00 UTC (permalink / raw) To: u-boot On Sun, Jun 2, 2013 at 11:25 PM, Simon Glass <sjg@chromium.org> wrote: > Hi, > > On Sun, Jun 2, 2013 at 10:24 AM, Jagan Teki <jagannadh.teki@gmail.com> > wrote: >> >> On Wed, May 29, 2013 at 11:40 AM, Rajeshwari Shinde >> <rajeshwari.s@samsung.com> wrote: >> > A SPI slave may take time to react to a request. For SPI flash devices >> > this time is defined as one bit time, or a whole byte for 'fast read' >> > mode. >> > >> > If the SPI slave is another CPU, then the time it takes to react may >> > vary. It is convenient to allow the slave device to tag the start of >> > the actual reply so that the host can determine when this 'preamble' >> > finishes and the actual message starts. >> > >> > Add a preamble flag to the available SPI flags. If supported by the >> > driver then it will ignore any received bytes before the preamble >> > on each transaction. This ensures that reliable communication with >> > the slave is possible. >> > >> > Signed-off-by: Simon Glass <sjg@chromium.org> >> > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> >> > --- >> > Changes in V2: >> > - None >> > Changes in V3: >> > - None. >> > Changes in V4: >> > - None. >> > Changes in V5: >> > - In commit message header changed SPI to spi. >> > include/spi.h | 5 +++++ >> > 1 files changed, 5 insertions(+), 0 deletions(-) >> > >> > diff --git a/include/spi.h b/include/spi.h >> > index 3fe2e1e..1638b50 100644 >> > --- a/include/spi.h >> > +++ b/include/spi.h >> > @@ -37,11 +37,16 @@ >> > #define SPI_LSB_FIRST 0x08 /* per-word >> > bits-on-wire */ >> > #define SPI_3WIRE 0x10 /* SI/SO signals >> > shared */ >> > #define SPI_LOOP 0x20 /* loopback mode >> > */ >> > +#define SPI_SLAVE 0x40 /* slave mode */ >> > +#define SPI_PREAMBLE 0x80 /* Skip preamble >> > bytes */ >> > >> > /* SPI transfer flags */ >> > #define SPI_XFER_BEGIN 0x01 /* Assert CS before >> > transfer */ >> > #define SPI_XFER_END 0x02 /* Deassert CS after >> > transfer */ >> > >> > +/* Header byte that marks the start of the message */ >> > +#define SPI_PREAMBLE_END_BYTE 0xec >> >> I think this 0xec is a value of rx_data what does it indicates and >> does this value specific to hw? > > > We have a later change which generalises this using the device tree, but it > is dependent on various other patches and adjusts the generic SPI interface. > If we can get this one in then I'm sure Vadim will supply a new patch for > consideration. Means this value is specific to exynos is it? -- Thanks, Jagan. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes 2013-06-02 18:00 ` Jagan Teki @ 2013-06-02 18:03 ` Simon Glass 0 siblings, 0 replies; 14+ messages in thread From: Simon Glass @ 2013-06-02 18:03 UTC (permalink / raw) To: u-boot Hi Jagan, On Sun, Jun 2, 2013 at 11:00 AM, Jagan Teki <jagannadh.teki@gmail.com>wrote: > On Sun, Jun 2, 2013 at 11:25 PM, Simon Glass <sjg@chromium.org> wrote: > > Hi, > > > > On Sun, Jun 2, 2013 at 10:24 AM, Jagan Teki <jagannadh.teki@gmail.com> > > wrote: > >> > >> On Wed, May 29, 2013 at 11:40 AM, Rajeshwari Shinde > >> <rajeshwari.s@samsung.com> wrote: > >> > A SPI slave may take time to react to a request. For SPI flash devices > >> > this time is defined as one bit time, or a whole byte for 'fast read' > >> > mode. > >> > > >> > If the SPI slave is another CPU, then the time it takes to react may > >> > vary. It is convenient to allow the slave device to tag the start of > >> > the actual reply so that the host can determine when this 'preamble' > >> > finishes and the actual message starts. > >> > > >> > Add a preamble flag to the available SPI flags. If supported by the > >> > driver then it will ignore any received bytes before the preamble > >> > on each transaction. This ensures that reliable communication with > >> > the slave is possible. > >> > > >> > Signed-off-by: Simon Glass <sjg@chromium.org> > >> > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > >> > --- > >> > Changes in V2: > >> > - None > >> > Changes in V3: > >> > - None. > >> > Changes in V4: > >> > - None. > >> > Changes in V5: > >> > - In commit message header changed SPI to spi. > >> > include/spi.h | 5 +++++ > >> > 1 files changed, 5 insertions(+), 0 deletions(-) > >> > > >> > diff --git a/include/spi.h b/include/spi.h > >> > index 3fe2e1e..1638b50 100644 > >> > --- a/include/spi.h > >> > +++ b/include/spi.h > >> > @@ -37,11 +37,16 @@ > >> > #define SPI_LSB_FIRST 0x08 /* per-word > >> > bits-on-wire */ > >> > #define SPI_3WIRE 0x10 /* SI/SO > signals > >> > shared */ > >> > #define SPI_LOOP 0x20 /* loopback > mode > >> > */ > >> > +#define SPI_SLAVE 0x40 /* slave mode > */ > >> > +#define SPI_PREAMBLE 0x80 /* Skip > preamble > >> > bytes */ > >> > > >> > /* SPI transfer flags */ > >> > #define SPI_XFER_BEGIN 0x01 /* Assert CS before > >> > transfer */ > >> > #define SPI_XFER_END 0x02 /* Deassert CS after > >> > transfer */ > >> > > >> > +/* Header byte that marks the start of the message */ > >> > +#define SPI_PREAMBLE_END_BYTE 0xec > >> > >> I think this 0xec is a value of rx_data what does it indicates and > >> does this value specific to hw? > > > > > > We have a later change which generalises this using the device tree, but > it > > is dependent on various other patches and adjusts the generic SPI > interface. > > If we can get this one in then I'm sure Vadim will supply a new patch for > > consideration. > > Means this value is specific to exynos is it? > Yes, it is actually specific to snow, a particular board. We are working on generalising this using device tree, and moving this logic to the generic spi code, but these patches will come later, and sit on top of this one. These patches have now been outstanding on the list for a very long time, and have been thoroughly reviewed and tested. > > -- > Thanks, > Jagan. > Regards, Simon ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [U-Boot,1/2,V5] spi: Add support for preamble bytes 2013-05-29 6:10 ` [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes Rajeshwari Shinde 2013-06-02 17:24 ` Jagan Teki @ 2013-06-02 18:19 ` Jagan Teki 2013-06-02 18:38 ` Jagan Teki 2 siblings, 0 replies; 14+ messages in thread From: Jagan Teki @ 2013-06-02 18:19 UTC (permalink / raw) To: u-boot On 29-05-2013 01:40, Rajeshwari Shinde wrote: > A SPI slave may take time to react to a request. For SPI flash devices > this time is defined as one bit time, or a whole byte for 'fast read' > mode. > > If the SPI slave is another CPU, then the time it takes to react may > vary. It is convenient to allow the slave device to tag the start of > the actual reply so that the host can determine when this 'preamble' > finishes and the actual message starts. > > Add a preamble flag to the available SPI flags. If supported by the > driver then it will ignore any received bytes before the preamble > on each transaction. This ensures that reliable communication with > the slave is possible. > > Signed-off-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > > --- > Changes in V2: > - None > Changes in V3: > - None. > Changes in V4: > - None. > Changes in V5: > - In commit message header changed SPI to spi. > include/spi.h | 5 +++++ > 1 files changed, 5 insertions(+), 0 deletions(-) > > diff --git a/include/spi.h b/include/spi.h > index 3fe2e1e..1638b50 100644 > --- a/include/spi.h > +++ b/include/spi.h > @@ -37,11 +37,16 @@ > #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ > #define SPI_3WIRE 0x10 /* SI/SO signals shared */ > #define SPI_LOOP 0x20 /* loopback mode */ > +#define SPI_SLAVE 0x40 /* slave mode */ > +#define SPI_PREAMBLE 0x80 /* Skip preamble bytes */ > > /* SPI transfer flags */ > #define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */ > #define SPI_XFER_END 0x02 /* Deassert CS after transfer */ > > +/* Header byte that marks the start of the message */ > +#define SPI_PREAMBLE_END_BYTE 0xec > + > /*----------------------------------------------------------------------- > * Representation of a SPI slave, i.e. what we're communicating with. > * Reviewed-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com> -- Thanks, Jagan. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [U-Boot,1/2,V5] spi: Add support for preamble bytes 2013-05-29 6:10 ` [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes Rajeshwari Shinde 2013-06-02 17:24 ` Jagan Teki 2013-06-02 18:19 ` [U-Boot] [U-Boot,1/2,V5] " Jagan Teki @ 2013-06-02 18:38 ` Jagan Teki 2 siblings, 0 replies; 14+ messages in thread From: Jagan Teki @ 2013-06-02 18:38 UTC (permalink / raw) To: u-boot On 29-05-2013 01:40, Rajeshwari Shinde wrote: > A SPI slave may take time to react to a request. For SPI flash devices > this time is defined as one bit time, or a whole byte for 'fast read' > mode. > > If the SPI slave is another CPU, then the time it takes to react may > vary. It is convenient to allow the slave device to tag the start of > the actual reply so that the host can determine when this 'preamble' > finishes and the actual message starts. > > Add a preamble flag to the available SPI flags. If supported by the > driver then it will ignore any received bytes before the preamble > on each transaction. This ensures that reliable communication with > the slave is possible. > > Signed-off-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > Reviewed-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com> > > --- > Changes in V2: > - None > Changes in V3: > - None. > Changes in V4: > - None. > Changes in V5: > - In commit message header changed SPI to spi. > include/spi.h | 5 +++++ > 1 files changed, 5 insertions(+), 0 deletions(-) > > diff --git a/include/spi.h b/include/spi.h > index 3fe2e1e..1638b50 100644 > --- a/include/spi.h > +++ b/include/spi.h > @@ -37,11 +37,16 @@ > #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ > #define SPI_3WIRE 0x10 /* SI/SO signals shared */ > #define SPI_LOOP 0x20 /* loopback mode */ > +#define SPI_SLAVE 0x40 /* slave mode */ > +#define SPI_PREAMBLE 0x80 /* Skip preamble bytes */ > > /* SPI transfer flags */ > #define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */ > #define SPI_XFER_END 0x02 /* Deassert CS after transfer */ > > +/* Header byte that marks the start of the message */ > +#define SPI_PREAMBLE_END_BYTE 0xec > + > /*----------------------------------------------------------------------- > * Representation of a SPI slave, i.e. what we're communicating with. > * Applied to u-boot-spi/master -- Thanks, Jagan. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode 2013-05-29 6:10 [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode Rajeshwari Shinde 2013-05-29 6:10 ` [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes Rajeshwari Shinde @ 2013-05-29 6:10 ` Rajeshwari Shinde 2013-06-02 17:41 ` Jagan Teki ` (2 more replies) 2013-05-30 4:38 ` [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode Simon Glass 2 siblings, 3 replies; 14+ messages in thread From: Rajeshwari Shinde @ 2013-05-29 6:10 UTC (permalink / raw) To: u-boot Support interfaces with a preamble before each received message. We handle this when the client has requested a SPI_XFER_END, meaning that we must close of the transaction. In this case we read until we see the preamble (or a timeout occurs), skipping all data before and including the preamble. The client will receive only data bytes after the preamble. Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> --- Changes in V2: - Remove preamable_count variable which is not really needed - Fix checkpatch warning (multiple assignments) Changes in V3: - Modified the if logic in spi_rx_tx function - Added blank lines as suggested by Minkyu Kang. - Removed in_bytes check in while loop. - Added a error check. Changes in V4: - Corrected a if condition. Changes in V5: - In commit message header changed EXYNOS: SPI: to spi:exynos. drivers/spi/exynos_spi.c | 69 +++++++++++++++++++++++++++++++++++++++------ 1 files changed, 59 insertions(+), 10 deletions(-) diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index 607e1cd..01378d0 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -51,6 +51,7 @@ struct exynos_spi_slave { unsigned int mode; enum periph_id periph_id; /* Peripheral ID for this device */ unsigned int fifo_size; + int skip_preamble; }; static struct spi_bus *spi_get_bus(unsigned dev_index) @@ -105,6 +106,8 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, else spi_slave->fifo_size = 256; + spi_slave->skip_preamble = 0; + spi_slave->freq = bus->frequency; if (max_hz) spi_slave->freq = min(max_hz, spi_slave->freq); @@ -217,17 +220,23 @@ static void spi_request_bytes(struct exynos_spi *regs, int count) writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); } -static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, - void **dinp, void const **doutp) +static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, + void **dinp, void const **doutp, unsigned long flags) { struct exynos_spi *regs = spi_slave->regs; uchar *rxp = *dinp; const uchar *txp = *doutp; int rx_lvl, tx_lvl; uint out_bytes, in_bytes; + int toread; + unsigned start = get_timer(0); + int stopping; out_bytes = in_bytes = todo; + stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) && + !(spi_slave->mode & SPI_SLAVE); + /* * If there's something to send, do a software reset and set a * transaction size. @@ -238,6 +247,8 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, * Bytes are transmitted/received in pairs. Wait to receive all the * data because then transmission will be done as well. */ + toread = in_bytes; + while (in_bytes) { int temp; @@ -248,15 +259,43 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, writel(temp, ®s->tx_data); out_bytes--; } - if (rx_lvl > 0 && in_bytes) { + if (rx_lvl > 0) { temp = readl(®s->rx_data); - if (rxp) - *rxp++ = temp; - in_bytes--; + if (spi_slave->skip_preamble) { + if (temp == SPI_PREAMBLE_END_BYTE) { + spi_slave->skip_preamble = 0; + stopping = 0; + } + } else { + if (rxp || stopping) + *rxp++ = temp; + in_bytes--; + } + toread--; + } else if (!toread) { + /* + * We have run out of input data, but haven't read + * enough bytes after the preamble yet. Read some more, + * and make sure that we transmit dummy bytes too, to + * keep things going. + */ + assert(!out_bytes); + out_bytes = in_bytes; + toread = in_bytes; + txp = NULL; + spi_request_bytes(regs, toread); + } + if (spi_slave->skip_preamble && get_timer(start) > 100) { + printf("SPI timeout: in_bytes=%d, out_bytes=%d, ", + in_bytes, out_bytes); + return -1; } } + *dinp = rxp; *doutp = txp; + + return 0; } /** @@ -276,6 +315,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, struct exynos_spi_slave *spi_slave = to_exynos_spi(slave); int upto, todo; int bytelen; + int ret = 0; /* spi core configured to do 8 bit transfers */ if (bitlen % 8) { @@ -289,16 +329,24 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, /* Exynos SPI limits each transfer to 65535 bytes */ bytelen = bitlen / 8; - for (upto = 0; upto < bytelen; upto += todo) { + for (upto = 0; !ret && upto < bytelen; upto += todo) { todo = min(bytelen - upto, (1 << 16) - 1); - spi_rx_tx(spi_slave, todo, &din, &dout); + ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags); + if (ret) + break; } /* Stop the transaction, if necessary. */ - if ((flags & SPI_XFER_END)) + if ((flags & SPI_XFER_END) && !(spi_slave->mode & SPI_SLAVE)) { spi_cs_deactivate(slave); + if (spi_slave->skip_preamble) { + assert(!spi_slave->skip_preamble); + debug("Failed to complete premable transaction\n"); + ret = -1; + } + } - return 0; + return ret; } /** @@ -325,6 +373,7 @@ void spi_cs_activate(struct spi_slave *slave) clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT); debug("Activate CS, bus %d\n", spi_slave->slave.bus); + spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE; } /** -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode 2013-05-29 6:10 ` [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode Rajeshwari Shinde @ 2013-06-02 17:41 ` Jagan Teki 2013-06-02 18:00 ` Simon Glass 2013-06-02 18:20 ` [U-Boot] [U-Boot, 2/2, " Jagan Teki 2013-06-02 18:38 ` Jagan Teki 2 siblings, 1 reply; 14+ messages in thread From: Jagan Teki @ 2013-06-02 17:41 UTC (permalink / raw) To: u-boot Hi, I know this has been reviewed multiples time, but I have few questions on it. I think this preamble is one of spi mode characteristic, if so does it specific to a hw? On Wed, May 29, 2013 at 11:40 AM, Rajeshwari Shinde <rajeshwari.s@samsung.com> wrote: > Support interfaces with a preamble before each received message. > > We handle this when the client has requested a SPI_XFER_END, meaning > that we must close of the transaction. In this case we read until we > see the preamble (or a timeout occurs), skipping all data before and > including the preamble. The client will receive only data bytes after > the preamble. > > Signed-off-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > --- > Changes in V2: > - Remove preamable_count variable which is not really needed > - Fix checkpatch warning (multiple assignments) > Changes in V3: > - Modified the if logic in spi_rx_tx function > - Added blank lines as suggested by Minkyu Kang. > - Removed in_bytes check in while loop. > - Added a error check. > Changes in V4: > - Corrected a if condition. > Changes in V5: > - In commit message header changed EXYNOS: SPI: to spi:exynos. > drivers/spi/exynos_spi.c | 69 +++++++++++++++++++++++++++++++++++++++------ > 1 files changed, 59 insertions(+), 10 deletions(-) > > diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c > index 607e1cd..01378d0 100644 > --- a/drivers/spi/exynos_spi.c > +++ b/drivers/spi/exynos_spi.c > @@ -51,6 +51,7 @@ struct exynos_spi_slave { > unsigned int mode; > enum periph_id periph_id; /* Peripheral ID for this device */ > unsigned int fifo_size; > + int skip_preamble; > }; > > static struct spi_bus *spi_get_bus(unsigned dev_index) > @@ -105,6 +106,8 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, > else > spi_slave->fifo_size = 256; > > + spi_slave->skip_preamble = 0; > + > spi_slave->freq = bus->frequency; > if (max_hz) > spi_slave->freq = min(max_hz, spi_slave->freq); > @@ -217,17 +220,23 @@ static void spi_request_bytes(struct exynos_spi *regs, int count) > writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); > } > > -static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > - void **dinp, void const **doutp) > +static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > + void **dinp, void const **doutp, unsigned long flags) > { > struct exynos_spi *regs = spi_slave->regs; > uchar *rxp = *dinp; > const uchar *txp = *doutp; > int rx_lvl, tx_lvl; > uint out_bytes, in_bytes; > + int toread; > + unsigned start = get_timer(0); > + int stopping; > > out_bytes = in_bytes = todo; > > + stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) && > + !(spi_slave->mode & SPI_SLAVE); > + > /* > * If there's something to send, do a software reset and set a > * transaction size. > @@ -238,6 +247,8 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > * Bytes are transmitted/received in pairs. Wait to receive all the > * data because then transmission will be done as well. > */ > + toread = in_bytes; > + > while (in_bytes) { > int temp; > > @@ -248,15 +259,43 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > writel(temp, ®s->tx_data); > out_bytes--; > } > - if (rx_lvl > 0 && in_bytes) { > + if (rx_lvl > 0) { > temp = readl(®s->rx_data); > - if (rxp) > - *rxp++ = temp; > - in_bytes--; > + if (spi_slave->skip_preamble) { > + if (temp == SPI_PREAMBLE_END_BYTE) { > + spi_slave->skip_preamble = 0; > + stopping = 0; > + } > + } else { > + if (rxp || stopping) > + *rxp++ = temp; > + in_bytes--; > + } > + toread--; > + } else if (!toread) { > + /* > + * We have run out of input data, but haven't read > + * enough bytes after the preamble yet. Read some more, > + * and make sure that we transmit dummy bytes too, to > + * keep things going. > + */ > + assert(!out_bytes); > + out_bytes = in_bytes; > + toread = in_bytes; > + txp = NULL; > + spi_request_bytes(regs, toread); > + } > + if (spi_slave->skip_preamble && get_timer(start) > 100) { > + printf("SPI timeout: in_bytes=%d, out_bytes=%d, ", > + in_bytes, out_bytes); > + return -1; > } > } > + > *dinp = rxp; > *doutp = txp; > + > + return 0; > } > > /** > @@ -276,6 +315,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, > struct exynos_spi_slave *spi_slave = to_exynos_spi(slave); > int upto, todo; > int bytelen; > + int ret = 0; > > /* spi core configured to do 8 bit transfers */ > if (bitlen % 8) { > @@ -289,16 +329,24 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, > > /* Exynos SPI limits each transfer to 65535 bytes */ > bytelen = bitlen / 8; > - for (upto = 0; upto < bytelen; upto += todo) { > + for (upto = 0; !ret && upto < bytelen; upto += todo) { > todo = min(bytelen - upto, (1 << 16) - 1); > - spi_rx_tx(spi_slave, todo, &din, &dout); > + ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags); > + if (ret) > + break; > } > > /* Stop the transaction, if necessary. */ > - if ((flags & SPI_XFER_END)) > + if ((flags & SPI_XFER_END) && !(spi_slave->mode & SPI_SLAVE)) { > spi_cs_deactivate(slave); > + if (spi_slave->skip_preamble) { > + assert(!spi_slave->skip_preamble); > + debug("Failed to complete premable transaction\n"); > + ret = -1; > + } > + } > > - return 0; > + return ret; > } > > /** > @@ -325,6 +373,7 @@ void spi_cs_activate(struct spi_slave *slave) > > clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT); > debug("Activate CS, bus %d\n", spi_slave->slave.bus); > + spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE; So for each cs active, we can assign the state of prempble to skip_preamble and then we check if the preamble is there on below logic + if (spi_slave->skip_preamble) { + if (temp == SPI_PREAMBLE_END_BYTE) { + spi_slave->skip_preamble = 0; + stopping = 0; + } If the preamble is there, read the rx_data for preamble data. If ie the preamble data then add the skip to 0. and continue to read the next data as read rxed data by skipping preamble with toread--. Was my understanding is correct, please correct me if am wrong. -- Thanks, Jagan. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode 2013-06-02 17:41 ` Jagan Teki @ 2013-06-02 18:00 ` Simon Glass 0 siblings, 0 replies; 14+ messages in thread From: Simon Glass @ 2013-06-02 18:00 UTC (permalink / raw) To: u-boot Hi, On Sun, Jun 2, 2013 at 10:41 AM, Jagan Teki <jagannadh.teki@gmail.com>wrote: > Hi, > > I know this has been reviewed multiples time, but I have few questions on > it. > > I think this preamble is one of spi mode characteristic, if so does it > specific to a hw? > > On Wed, May 29, 2013 at 11:40 AM, Rajeshwari Shinde > <rajeshwari.s@samsung.com> wrote: > > Support interfaces with a preamble before each received message. > > > > We handle this when the client has requested a SPI_XFER_END, meaning > > that we must close of the transaction. In this case we read until we > > see the preamble (or a timeout occurs), skipping all data before and > > including the preamble. The client will receive only data bytes after > > the preamble. > > > > Signed-off-by: Simon Glass <sjg@chromium.org> > > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > > --- > > Changes in V2: > > - Remove preamable_count variable which is not really needed > > - Fix checkpatch warning (multiple assignments) > > Changes in V3: > > - Modified the if logic in spi_rx_tx function > > - Added blank lines as suggested by Minkyu Kang. > > - Removed in_bytes check in while loop. > > - Added a error check. > > Changes in V4: > > - Corrected a if condition. > > Changes in V5: > > - In commit message header changed EXYNOS: SPI: to spi:exynos. > > drivers/spi/exynos_spi.c | 69 > +++++++++++++++++++++++++++++++++++++++------ > > 1 files changed, 59 insertions(+), 10 deletions(-) > > > > diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c > > index 607e1cd..01378d0 100644 > > --- a/drivers/spi/exynos_spi.c > > +++ b/drivers/spi/exynos_spi.c > > @@ -51,6 +51,7 @@ struct exynos_spi_slave { > > unsigned int mode; > > enum periph_id periph_id; /* Peripheral ID for this device > */ > > unsigned int fifo_size; > > + int skip_preamble; > > }; > > > > static struct spi_bus *spi_get_bus(unsigned dev_index) > > @@ -105,6 +106,8 @@ struct spi_slave *spi_setup_slave(unsigned int > busnum, unsigned int cs, > > else > > spi_slave->fifo_size = 256; > > > > + spi_slave->skip_preamble = 0; > > + > > spi_slave->freq = bus->frequency; > > if (max_hz) > > spi_slave->freq = min(max_hz, spi_slave->freq); > > @@ -217,17 +220,23 @@ static void spi_request_bytes(struct exynos_spi > *regs, int count) > > writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); > > } > > > > -static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > > - void **dinp, void const **doutp) > > +static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > > + void **dinp, void const **doutp, unsigned long > flags) > > { > > struct exynos_spi *regs = spi_slave->regs; > > uchar *rxp = *dinp; > > const uchar *txp = *doutp; > > int rx_lvl, tx_lvl; > > uint out_bytes, in_bytes; > > + int toread; > > + unsigned start = get_timer(0); > > + int stopping; > > > > out_bytes = in_bytes = todo; > > > > + stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) && > > + !(spi_slave->mode & SPI_SLAVE); > > + > > /* > > * If there's something to send, do a software reset and set a > > * transaction size. > > @@ -238,6 +247,8 @@ static void spi_rx_tx(struct exynos_spi_slave > *spi_slave, int todo, > > * Bytes are transmitted/received in pairs. Wait to receive all > the > > * data because then transmission will be done as well. > > */ > > + toread = in_bytes; > > + > > while (in_bytes) { > > int temp; > > > > @@ -248,15 +259,43 @@ static void spi_rx_tx(struct exynos_spi_slave > *spi_slave, int todo, > > writel(temp, ®s->tx_data); > > out_bytes--; > > } > > - if (rx_lvl > 0 && in_bytes) { > > + if (rx_lvl > 0) { > > temp = readl(®s->rx_data); > > - if (rxp) > > - *rxp++ = temp; > > - in_bytes--; > > + if (spi_slave->skip_preamble) { > > + if (temp == SPI_PREAMBLE_END_BYTE) { > > + spi_slave->skip_preamble = 0; > > + stopping = 0; > > + } > > + } else { > > + if (rxp || stopping) > > + *rxp++ = temp; > > + in_bytes--; > > + } > > + toread--; > > + } else if (!toread) { > > + /* > > + * We have run out of input data, but haven't > read > > + * enough bytes after the preamble yet. Read > some more, > > + * and make sure that we transmit dummy bytes > too, to > > + * keep things going. > > + */ > > + assert(!out_bytes); > > + out_bytes = in_bytes; > > + toread = in_bytes; > > + txp = NULL; > > + spi_request_bytes(regs, toread); > > + } > > + if (spi_slave->skip_preamble && get_timer(start) > 100) { > > + printf("SPI timeout: in_bytes=%d, out_bytes=%d, > ", > > + in_bytes, out_bytes); > > + return -1; > > } > > } > > + > > *dinp = rxp; > > *doutp = txp; > > + > > + return 0; > > } > > > > /** > > @@ -276,6 +315,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int > bitlen, const void *dout, > > struct exynos_spi_slave *spi_slave = to_exynos_spi(slave); > > int upto, todo; > > int bytelen; > > + int ret = 0; > > > > /* spi core configured to do 8 bit transfers */ > > if (bitlen % 8) { > > @@ -289,16 +329,24 @@ int spi_xfer(struct spi_slave *slave, unsigned int > bitlen, const void *dout, > > > > /* Exynos SPI limits each transfer to 65535 bytes */ > > bytelen = bitlen / 8; > > - for (upto = 0; upto < bytelen; upto += todo) { > > + for (upto = 0; !ret && upto < bytelen; upto += todo) { > > todo = min(bytelen - upto, (1 << 16) - 1); > > - spi_rx_tx(spi_slave, todo, &din, &dout); > > + ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags); > > + if (ret) > > + break; > > } > > > > /* Stop the transaction, if necessary. */ > > - if ((flags & SPI_XFER_END)) > > + if ((flags & SPI_XFER_END) && !(spi_slave->mode & SPI_SLAVE)) { > > spi_cs_deactivate(slave); > > + if (spi_slave->skip_preamble) { > > + assert(!spi_slave->skip_preamble); > > + debug("Failed to complete premable > transaction\n"); > > + ret = -1; > > + } > > + } > > > > - return 0; > > + return ret; > > } > > > > /** > > @@ -325,6 +373,7 @@ void spi_cs_activate(struct spi_slave *slave) > > > > clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT); > > debug("Activate CS, bus %d\n", spi_slave->slave.bus); > > + spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE; > > So for each cs active, we can assign the state of prempble to > skip_preamble and then > we check if the preamble is there on below logic > + if (spi_slave->skip_preamble) { > + if (temp == SPI_PREAMBLE_END_BYTE) { > + spi_slave->skip_preamble = 0; > + stopping = 0; > + } > > If the preamble is there, read the rx_data for preamble data. > If ie the preamble data then add the skip to 0. and continue to read > the next data as read rxed data by > skipping preamble with toread--. > The problem here is is that the U-Boot SPI interface doesn't quite allow this. For example, 'sf probe' does a short write, then in a separate spi_xfer() call it does a read. Should the preamble be waited for in the first write? Perhaps not, if more bytes need to be sent before the other end can respond. It is a little complicated and we are working on another approach. But this code does work and is heavily tested. I would be reluctant to change it in mainline without further testing. We are working on generalising this. > Was my understanding is correct, please correct me if am wrong. > > -- > Thanks, > Jagan. > Regards, Simon ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [U-Boot, 2/2, V5] spi: exynos: Support SPI_PREAMBLE mode 2013-05-29 6:10 ` [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode Rajeshwari Shinde 2013-06-02 17:41 ` Jagan Teki @ 2013-06-02 18:20 ` Jagan Teki 2013-06-02 18:38 ` Jagan Teki 2 siblings, 0 replies; 14+ messages in thread From: Jagan Teki @ 2013-06-02 18:20 UTC (permalink / raw) To: u-boot On 29-05-2013 01:40, Rajeshwari Shinde wrote: > Support interfaces with a preamble before each received message. > > We handle this when the client has requested a SPI_XFER_END, meaning > that we must close of the transaction. In this case we read until we > see the preamble (or a timeout occurs), skipping all data before and > including the preamble. The client will receive only data bytes after > the preamble. > > Signed-off-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > > --- > Changes in V2: > - Remove preamable_count variable which is not really needed > - Fix checkpatch warning (multiple assignments) > Changes in V3: > - Modified the if logic in spi_rx_tx function > - Added blank lines as suggested by Minkyu Kang. > - Removed in_bytes check in while loop. > - Added a error check. > Changes in V4: > - Corrected a if condition. > Changes in V5: > - In commit message header changed EXYNOS: SPI: to spi:exynos. > drivers/spi/exynos_spi.c | 69 +++++++++++++++++++++++++++++++++++++++------ > 1 files changed, 59 insertions(+), 10 deletions(-) > > diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c > index 607e1cd..01378d0 100644 > --- a/drivers/spi/exynos_spi.c > +++ b/drivers/spi/exynos_spi.c > @@ -51,6 +51,7 @@ struct exynos_spi_slave { > unsigned int mode; > enum periph_id periph_id; /* Peripheral ID for this device */ > unsigned int fifo_size; > + int skip_preamble; > }; > > static struct spi_bus *spi_get_bus(unsigned dev_index) > @@ -105,6 +106,8 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, > else > spi_slave->fifo_size = 256; > > + spi_slave->skip_preamble = 0; > + > spi_slave->freq = bus->frequency; > if (max_hz) > spi_slave->freq = min(max_hz, spi_slave->freq); > @@ -217,17 +220,23 @@ static void spi_request_bytes(struct exynos_spi *regs, int count) > writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); > } > > -static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > - void **dinp, void const **doutp) > +static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > + void **dinp, void const **doutp, unsigned long flags) > { > struct exynos_spi *regs = spi_slave->regs; > uchar *rxp = *dinp; > const uchar *txp = *doutp; > int rx_lvl, tx_lvl; > uint out_bytes, in_bytes; > + int toread; > + unsigned start = get_timer(0); > + int stopping; > > out_bytes = in_bytes = todo; > > + stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) && > + !(spi_slave->mode & SPI_SLAVE); > + > /* > * If there's something to send, do a software reset and set a > * transaction size. > @@ -238,6 +247,8 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > * Bytes are transmitted/received in pairs. Wait to receive all the > * data because then transmission will be done as well. > */ > + toread = in_bytes; > + > while (in_bytes) { > int temp; > > @@ -248,15 +259,43 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > writel(temp, ®s->tx_data); > out_bytes--; > } > - if (rx_lvl > 0 && in_bytes) { > + if (rx_lvl > 0) { > temp = readl(®s->rx_data); > - if (rxp) > - *rxp++ = temp; > - in_bytes--; > + if (spi_slave->skip_preamble) { > + if (temp == SPI_PREAMBLE_END_BYTE) { > + spi_slave->skip_preamble = 0; > + stopping = 0; > + } > + } else { > + if (rxp || stopping) > + *rxp++ = temp; > + in_bytes--; > + } > + toread--; > + } else if (!toread) { > + /* > + * We have run out of input data, but haven't read > + * enough bytes after the preamble yet. Read some more, > + * and make sure that we transmit dummy bytes too, to > + * keep things going. > + */ > + assert(!out_bytes); > + out_bytes = in_bytes; > + toread = in_bytes; > + txp = NULL; > + spi_request_bytes(regs, toread); > + } > + if (spi_slave->skip_preamble && get_timer(start) > 100) { > + printf("SPI timeout: in_bytes=%d, out_bytes=%d, ", > + in_bytes, out_bytes); > + return -1; > } > } > + > *dinp = rxp; > *doutp = txp; > + > + return 0; > } > > /** > @@ -276,6 +315,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, > struct exynos_spi_slave *spi_slave = to_exynos_spi(slave); > int upto, todo; > int bytelen; > + int ret = 0; > > /* spi core configured to do 8 bit transfers */ > if (bitlen % 8) { > @@ -289,16 +329,24 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, > > /* Exynos SPI limits each transfer to 65535 bytes */ > bytelen = bitlen / 8; > - for (upto = 0; upto < bytelen; upto += todo) { > + for (upto = 0; !ret && upto < bytelen; upto += todo) { > todo = min(bytelen - upto, (1 << 16) - 1); > - spi_rx_tx(spi_slave, todo, &din, &dout); > + ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags); > + if (ret) > + break; > } > > /* Stop the transaction, if necessary. */ > - if ((flags & SPI_XFER_END)) > + if ((flags & SPI_XFER_END) && !(spi_slave->mode & SPI_SLAVE)) { > spi_cs_deactivate(slave); > + if (spi_slave->skip_preamble) { > + assert(!spi_slave->skip_preamble); > + debug("Failed to complete premable transaction\n"); > + ret = -1; > + } > + } > > - return 0; > + return ret; > } > > /** > @@ -325,6 +373,7 @@ void spi_cs_activate(struct spi_slave *slave) > > clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT); > debug("Activate CS, bus %d\n", spi_slave->slave.bus); > + spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE; > } > > /** Reviewed-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com> -- Thanks, Jagan. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [U-Boot, 2/2, V5] spi: exynos: Support SPI_PREAMBLE mode 2013-05-29 6:10 ` [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode Rajeshwari Shinde 2013-06-02 17:41 ` Jagan Teki 2013-06-02 18:20 ` [U-Boot] [U-Boot, 2/2, " Jagan Teki @ 2013-06-02 18:38 ` Jagan Teki 2 siblings, 0 replies; 14+ messages in thread From: Jagan Teki @ 2013-06-02 18:38 UTC (permalink / raw) To: u-boot On 29-05-2013 01:40, Rajeshwari Shinde wrote: > Support interfaces with a preamble before each received message. > > We handle this when the client has requested a SPI_XFER_END, meaning > that we must close of the transaction. In this case we read until we > see the preamble (or a timeout occurs), skipping all data before and > including the preamble. The client will receive only data bytes after > the preamble. > > Signed-off-by: Simon Glass <sjg@chromium.org> > Signed-off-by: Rajeshwari Shinde <rajeshwari.s@samsung.com> > Reviewed-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com> > > --- > Changes in V2: > - Remove preamable_count variable which is not really needed > - Fix checkpatch warning (multiple assignments) > Changes in V3: > - Modified the if logic in spi_rx_tx function > - Added blank lines as suggested by Minkyu Kang. > - Removed in_bytes check in while loop. > - Added a error check. > Changes in V4: > - Corrected a if condition. > Changes in V5: > - In commit message header changed EXYNOS: SPI: to spi:exynos. > drivers/spi/exynos_spi.c | 69 +++++++++++++++++++++++++++++++++++++++------ > 1 files changed, 59 insertions(+), 10 deletions(-) > > diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c > index 607e1cd..01378d0 100644 > --- a/drivers/spi/exynos_spi.c > +++ b/drivers/spi/exynos_spi.c > @@ -51,6 +51,7 @@ struct exynos_spi_slave { > unsigned int mode; > enum periph_id periph_id; /* Peripheral ID for this device */ > unsigned int fifo_size; > + int skip_preamble; > }; > > static struct spi_bus *spi_get_bus(unsigned dev_index) > @@ -105,6 +106,8 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, > else > spi_slave->fifo_size = 256; > > + spi_slave->skip_preamble = 0; > + > spi_slave->freq = bus->frequency; > if (max_hz) > spi_slave->freq = min(max_hz, spi_slave->freq); > @@ -217,17 +220,23 @@ static void spi_request_bytes(struct exynos_spi *regs, int count) > writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); > } > > -static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > - void **dinp, void const **doutp) > +static int spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > + void **dinp, void const **doutp, unsigned long flags) > { > struct exynos_spi *regs = spi_slave->regs; > uchar *rxp = *dinp; > const uchar *txp = *doutp; > int rx_lvl, tx_lvl; > uint out_bytes, in_bytes; > + int toread; > + unsigned start = get_timer(0); > + int stopping; > > out_bytes = in_bytes = todo; > > + stopping = spi_slave->skip_preamble && (flags & SPI_XFER_END) && > + !(spi_slave->mode & SPI_SLAVE); > + > /* > * If there's something to send, do a software reset and set a > * transaction size. > @@ -238,6 +247,8 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > * Bytes are transmitted/received in pairs. Wait to receive all the > * data because then transmission will be done as well. > */ > + toread = in_bytes; > + > while (in_bytes) { > int temp; > > @@ -248,15 +259,43 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, > writel(temp, ®s->tx_data); > out_bytes--; > } > - if (rx_lvl > 0 && in_bytes) { > + if (rx_lvl > 0) { > temp = readl(®s->rx_data); > - if (rxp) > - *rxp++ = temp; > - in_bytes--; > + if (spi_slave->skip_preamble) { > + if (temp == SPI_PREAMBLE_END_BYTE) { > + spi_slave->skip_preamble = 0; > + stopping = 0; > + } > + } else { > + if (rxp || stopping) > + *rxp++ = temp; > + in_bytes--; > + } > + toread--; > + } else if (!toread) { > + /* > + * We have run out of input data, but haven't read > + * enough bytes after the preamble yet. Read some more, > + * and make sure that we transmit dummy bytes too, to > + * keep things going. > + */ > + assert(!out_bytes); > + out_bytes = in_bytes; > + toread = in_bytes; > + txp = NULL; > + spi_request_bytes(regs, toread); > + } > + if (spi_slave->skip_preamble && get_timer(start) > 100) { > + printf("SPI timeout: in_bytes=%d, out_bytes=%d, ", > + in_bytes, out_bytes); > + return -1; > } > } > + > *dinp = rxp; > *doutp = txp; > + > + return 0; > } > > /** > @@ -276,6 +315,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, > struct exynos_spi_slave *spi_slave = to_exynos_spi(slave); > int upto, todo; > int bytelen; > + int ret = 0; > > /* spi core configured to do 8 bit transfers */ > if (bitlen % 8) { > @@ -289,16 +329,24 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, > > /* Exynos SPI limits each transfer to 65535 bytes */ > bytelen = bitlen / 8; > - for (upto = 0; upto < bytelen; upto += todo) { > + for (upto = 0; !ret && upto < bytelen; upto += todo) { > todo = min(bytelen - upto, (1 << 16) - 1); > - spi_rx_tx(spi_slave, todo, &din, &dout); > + ret = spi_rx_tx(spi_slave, todo, &din, &dout, flags); > + if (ret) > + break; > } > > /* Stop the transaction, if necessary. */ > - if ((flags & SPI_XFER_END)) > + if ((flags & SPI_XFER_END) && !(spi_slave->mode & SPI_SLAVE)) { > spi_cs_deactivate(slave); > + if (spi_slave->skip_preamble) { > + assert(!spi_slave->skip_preamble); > + debug("Failed to complete premable transaction\n"); > + ret = -1; > + } > + } > > - return 0; > + return ret; > } > > /** > @@ -325,6 +373,7 @@ void spi_cs_activate(struct spi_slave *slave) > > clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT); > debug("Activate CS, bus %d\n", spi_slave->slave.bus); > + spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE; > } > > /** Applied to u-boot-spi/master -- Thanks, Jagan. ^ permalink raw reply [flat|nested] 14+ messages in thread
* [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode 2013-05-29 6:10 [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode Rajeshwari Shinde 2013-05-29 6:10 ` [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes Rajeshwari Shinde 2013-05-29 6:10 ` [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode Rajeshwari Shinde @ 2013-05-30 4:38 ` Simon Glass 2 siblings, 0 replies; 14+ messages in thread From: Simon Glass @ 2013-05-30 4:38 UTC (permalink / raw) To: u-boot Hi, On Tue, May 28, 2013 at 11:10 PM, Rajeshwari Shinde < rajeshwari.s@samsung.com> wrote: > This patch set enables PREAMBLE Mode for EXYNOS SPI. > > Changes in v2: > - Remove preamable_count variable which is not really needed > - Fix checkpatch warning (multiple assignments) > Changes in V3: > - Modified the if logic in spi_rx_tx function > - Added blank lines as suggested by Minkyu Kang. > - Removed in_bytes check in while loop. > - Added a error check. > Changes in V4: > - Corrected a if condition. > Changes in V5: > - In commit message header changed > SPI to spi > EXYNOS: SPI: to spi: exynos: > > Rajeshwari Shinde (2): > spi: Add support for preamble bytes > spi: exynos: Support SPI_PREAMBLE mode > Hoping these patches can be applied soon... Regards, Simon > > drivers/spi/exynos_spi.c | 69 > +++++++++++++++++++++++++++++++++++++++------ > include/spi.h | 5 +++ > 2 files changed, 64 insertions(+), 10 deletions(-) > > -- > 1.7.4.4 > > ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2013-06-02 18:38 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-05-29 6:10 [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode Rajeshwari Shinde 2013-05-29 6:10 ` [U-Boot] [PATCH 1/2 V5] spi: Add support for preamble bytes Rajeshwari Shinde 2013-06-02 17:24 ` Jagan Teki 2013-06-02 17:55 ` Simon Glass 2013-06-02 18:00 ` Jagan Teki 2013-06-02 18:03 ` Simon Glass 2013-06-02 18:19 ` [U-Boot] [U-Boot,1/2,V5] " Jagan Teki 2013-06-02 18:38 ` Jagan Teki 2013-05-29 6:10 ` [U-Boot] [PATCH 2/2 V5] spi: exynos: Support SPI_PREAMBLE mode Rajeshwari Shinde 2013-06-02 17:41 ` Jagan Teki 2013-06-02 18:00 ` Simon Glass 2013-06-02 18:20 ` [U-Boot] [U-Boot, 2/2, " Jagan Teki 2013-06-02 18:38 ` Jagan Teki 2013-05-30 4:38 ` [U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode Simon Glass
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox