[PATCH 08/13] powerpc/5200: LocalPlus driver: smart flush of receive FIFO
Roman Fietze
roman.fietze at telemotive.de
Tue Dec 22 18:06:33 EST 2009
Signed-off-by: Roman Fietze <roman.fietze at 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
More information about the Linuxppc-dev
mailing list