I've been trying to get DMA working on the 405GP and I've run across
something in ppc4xx_dma.h.
In the function 'enable_dma' the following piece of code appears:
(begin excerpt)
/* for other xfer modes, the addresses are already set */
control = mfdcr(DCRN_DMACR0);
control &= ~(DMA_TM_MASK | DMA_TD); /* clear all mode bits */
if (p_dma_ch->mode == DMA_MODE_MM) {
/* software initiated memory to memory */
control |= control | DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
}
control |= (p_dma_ch->mode | DMA_CH_ENABLE);
mtdcr(DCRN_DMACR0, control);
(end excerpt)
It looks to me like this code will always read/write the control register for
DMA channel 0 regardless of the channel specified by the parameter 'dmanr'
that is passed to the function. Is this observation correct? What would the
fix be, if so?
Also, does anyone have a short piece of code that shows how to start a DMA
read on the 405?
Thanks,
Jim
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
I've been trying to get DMA working on the 405GP and I've run across
something in ppc4xx_dma.h.
In the function 'enable_dma' the following piece of code appears:
(begin excerpt)
/* for other xfer modes, the addresses are already set */
control = mfdcr(DCRN_DMACR0);
control &= ~(DMA_TM_MASK | DMA_TD); /* clear all mode bits */
if (p_dma_ch->mode == DMA_MODE_MM) {
/* software initiated memory to memory */
control |= control | DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
}
control |= (p_dma_ch->mode | DMA_CH_ENABLE);
mtdcr(DCRN_DMACR0, control);
(end excerpt)
It looks to me like this code will always read/write the control register for
DMA channel 0 regardless of the channel specified by the parameter 'dmanr'
that is passed to the function. Is this observation correct?
good catch.
What would the
fix be, if so?
Most likey switch statment like the disable has.
give me a day
Armin
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
I've been trying to get DMA working on the 405GP and I've run across
something in ppc4xx_dma.h.
In the function 'enable_dma' the following piece of code appears:
(begin excerpt)
/* for other xfer modes, the addresses are already set */
control = mfdcr(DCRN_DMACR0);
control &= ~(DMA_TM_MASK | DMA_TD); /* clear all mode bits */
if (p_dma_ch->mode == DMA_MODE_MM) {
/* software initiated memory to memory */
control |= control | DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
}
control |= (p_dma_ch->mode | DMA_CH_ENABLE);
mtdcr(DCRN_DMACR0, control);
(end excerpt)
It looks to me like this code will always read/write the control
register for
DMA channel 0 regardless of the channel specified by the parameter
'dmanr'
that is passed to the function. Is this observation correct?
good catch.
quoted
What would the
fix be, if so?
Most likey switch statment like the disable has.
give me a day
Armin
Here is the patch , please let me know it it helps.
Armin
Noticed that the order of clearing the old transfer mode bits and
setting the p_dma_ch->mode bits is reversed in the new patch, not sure
if this causes problems:
+ tmp_cntl |= (p_dma_ch->mode | DMA_CH_ENABLE);
+
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ control |= tmp_cntl;
+ control &= ~(DMA_TM_MASK | DMA_TD); /* clear all
mode bits */
This seems to set and then clear the p_dma_ch->mode bits in control
prior to writing to the DMACR, a problem?
--
Todd
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Noticed that the order of clearing the old transfer mode bits and
setting the p_dma_ch->mode bits is reversed in the new patch, not sure
if this causes problems:
+ tmp_cntl |= (p_dma_ch->mode | DMA_CH_ENABLE);
+
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ control |= tmp_cntl;
+ control &= ~(DMA_TM_MASK | DMA_TD); /* clear all
mode bits */
This seems to set and then clear the p_dma_ch->mode bits in control
prior to writing to the DMACR, a problem?
--
Todd
Todd,
yeap, looks like it.
armin
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Noticed that the order of clearing the old transfer mode bits and
setting the p_dma_ch->mode bits is reversed in the new patch, not sure
if this causes problems:
+ tmp_cntl |= (p_dma_ch->mode | DMA_CH_ENABLE);
+
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ control |= tmp_cntl;
+ control &= ~(DMA_TM_MASK | DMA_TD); /* clear all
mode bits */
This seems to set and then clear the p_dma_ch->mode bits in control
prior to writing to the DMACR, a problem?
--
Todd
Here is a patch that should address the above issue. I put in
additional checks for if a the current dma channel is all ready claimed
and if the requestion channel is greater than max dma channels.
dma_enable no longer clears mode bits. ( TODO: should document 4xx dma
usage)
Armin