Signed-off-by: Roman Fietze <roman.fie...@telemotive.de>
---
 arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c |   40 ++++++++++++++++---------
 1 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c 
b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
index a7cd585..48f2b4f 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
@@ -84,8 +84,7 @@ static void mpc52xx_lpbfifo_kick(struct 
mpc52xx_lpbfifo_request *req)
        struct bcom_bd *bd;
        void __iomem *reg;
        u32 *data;
-       int i;
-       int bit_fields;
+       u32 bit_fields;
        int rflags = req->flags;
 
        /* Set and clear the reset bits; is good practice in User Manual */
@@ -96,27 +95,32 @@ static void mpc52xx_lpbfifo_kick(struct 
mpc52xx_lpbfifo_request *req)
 
        /* Set CS and BPT */
        bit_fields = MPC52xx_SCLPC_CONTROL_CS(req->cs) | 0x8;
-       if (!(mpc52xx_lpbfifo_is_write(rflags))) {
+       if (!(mpc52xx_lpbfifo_is_write(rflags)))
                bit_fields |= MPC52xx_SCLPC_CONTROL_RWB_RECEIVE;        /* read 
mode */
-               bit_fields |= MPC52xx_SCLPC_CONTROL_FLUSH;
-       }
-       out_be32(&lpbfifo.regs->control, bit_fields);
 
        if (!mpc52xx_lpbfifo_is_dma(rflags)) {
-               /* While the FIFO can be setup for transfer sizes as large as
-                * 16M-1, the FIFO itself is only 512 bytes deep and it does
-                * not generate interrupts for FIFO full events (only transfer
-                * complete will raise an IRQ).  Therefore when not using
-                * Bestcomm to drive the FIFO it needs to either be polled, or
-                * transfers need to constrained to the size of the fifo.
+               /* While the FIFO can be setup for transfer sizes as
+                * large as 16M-1, the FIFO itself is only 512 bytes
+                * deep and it does not generate interrupts for FIFO
+                * full events (only transfer complete will raise an
+                * IRQ). Therefore when not using Bestcomm to drive the
+                * FIFO it needs to either be polled, or transfers need
+                * to constrained to the size of the fifo.
                 *
                 * This driver restricts the size of the transfer
+                *
+                * The last block of data will be received with the
+                * flush bit set. This avoids stale read data.
                 */
                if (transfer_size > 512)
                        transfer_size = 512;
+               else if (!(mpc52xx_lpbfifo_is_write(rflags)))
+                       bit_fields |= MPC52xx_SCLPC_CONTROL_FLUSH;
 
                /* Load the FIFO with data */
                if (mpc52xx_lpbfifo_is_write(rflags)) {
+                       size_t i;
+
                        reg = &lpbfifo.regs->fifo_data;
                        data = req->data + req->pos;
                        for (i = 0; i < transfer_size; i += 4)
@@ -128,6 +132,12 @@ static void mpc52xx_lpbfifo_kick(struct 
mpc52xx_lpbfifo_request *req)
                                                 MPC52xx_SCLPC_ENABLE_NIE |
                                                 MPC52xx_SCLPC_ENABLE_ME));
        } else {
+
+               /* In DMA mode we can always set the flush bit to avoid
+                * stale read data. */
+               if (!(mpc52xx_lpbfifo_is_write(rflags)))
+                       bit_fields |= MPC52xx_SCLPC_CONTROL_FLUSH;
+
                /* Choose the correct direction
                 *
                 * Configure the watermarks so DMA will always complete 
correctly.
@@ -168,6 +178,8 @@ static void mpc52xx_lpbfifo_kick(struct 
mpc52xx_lpbfifo_request *req)
                bcom_submit_next_buffer(lpbfifo.bcom_cur_task, NULL);
        }
 
+       out_be32(&lpbfifo.regs->control, bit_fields);
+
        /* Set packet size and kick it off */
        out_be32(&lpbfifo.regs->packet_size.packet_size, 
MPC52xx_SCLPC_PACKET_SIZE_RESTART | transfer_size);
        if (mpc52xx_lpbfifo_is_dma(rflags))
@@ -455,7 +467,7 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct 
of_device_id *match)
                goto err_irq;
 
        /* Request the Bestcomm receive (fifo --> memory) task and IRQ */
-       lpbfifo.bcom_rx_task = bcom_gen_bd_rx_init(4,
+       lpbfifo.bcom_rx_task = bcom_gen_bd_rx_init(2,
                                                   res.start + offsetof(struct 
mpc52xx_sclpc, fifo_data),
                                                   BCOM_INITIATOR_SCLPC, 
BCOM_IPR_SCLPC,
                                                   16 * 1024 * 1024);
@@ -469,7 +481,7 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct 
of_device_id *match)
                goto err_bcom_rx_irq;
 
        /* Request the Bestcomm transmit (memory --> fifo) task and IRQ */
-       lpbfifo.bcom_tx_task = bcom_gen_bd_tx_init(4,
+       lpbfifo.bcom_tx_task = bcom_gen_bd_tx_init(2,
                                                   res.start + offsetof(struct 
mpc52xx_sclpc, fifo_data),
                                                   BCOM_INITIATOR_SCLPC,
                                                   BCOM_IPR_SCLPC);
-- 
1.6.5.5



-- 
Roman Fietze                Telemotive AG Büro Mühlhausen
Breitwiesen                              73347 Mühlhausen
Tel.: +49(0)7335/18493-45        http://www.telemotive.de
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to