Message ID | 200912220806.33304.roman.fietze@telemotive.de (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Grant Likely |
Headers | show |
On Tue, Dec 22, 2009 at 12:06 AM, Roman Fietze <roman.fietze@telemotive.de> wrote: > Need patch description > Signed-off-by: Roman Fietze <roman.fietze@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); Writing the control register is being deferred to later. I'm not convinced this is correct (see comment on previous patch). > > 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. Drop formatting changes or spilt to separate patch. > * > * 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, unrelated change (and this line was also changed in an earlier patch) > 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, ditto > 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 >
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);
Signed-off-by: Roman Fietze <roman.fietze@telemotive.de> --- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 40 ++++++++++++++++--------- 1 files changed, 26 insertions(+), 14 deletions(-)