* Question about ppc4xx_dma.h
@ 2002-08-20 15:26 jim
2002-08-20 23:18 ` akuster
0 siblings, 1 reply; 6+ messages in thread
From: jim @ 2002-08-20 15:26 UTC (permalink / raw)
To: linuxppc-embedded
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/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Question about ppc4xx_dma.h
2002-08-20 15:26 Question about ppc4xx_dma.h jim
@ 2002-08-20 23:18 ` akuster
2002-08-21 19:39 ` akuster
0 siblings, 1 reply; 6+ messages in thread
From: akuster @ 2002-08-20 23:18 UTC (permalink / raw)
To: jim; +Cc: linuxppc-embedded
jim wrote:
> 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/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Question about ppc4xx_dma.h
2002-08-20 23:18 ` akuster
@ 2002-08-21 19:39 ` akuster
2002-08-21 22:17 ` Todd Poynor
0 siblings, 1 reply; 6+ messages in thread
From: akuster @ 2002-08-21 19:39 UTC (permalink / raw)
To: akuster; +Cc: jim, linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1119 bytes --]
akuster wrote:
>
> jim wrote:
>
>> 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
>
>
>
>
>
Here is the patch , please let me know it it helps.
Armin
[-- Attachment #2: dma_0821.patch.gz --]
[-- Type: application/x-gunzip, Size: 1013 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Question about ppc4xx_dma.h
2002-08-21 19:39 ` akuster
@ 2002-08-21 22:17 ` Todd Poynor
2002-08-22 6:18 ` akuster
2002-08-27 3:44 ` akuster
0 siblings, 2 replies; 6+ messages in thread
From: Todd Poynor @ 2002-08-21 22:17 UTC (permalink / raw)
To: akuster; +Cc: jim, linuxppc-embedded
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/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Question about ppc4xx_dma.h
2002-08-21 22:17 ` Todd Poynor
@ 2002-08-22 6:18 ` akuster
2002-08-27 3:44 ` akuster
1 sibling, 0 replies; 6+ messages in thread
From: akuster @ 2002-08-22 6:18 UTC (permalink / raw)
To: Todd Poynor; +Cc: jim, linuxppc-embedded
Todd Poynor wrote:
>
> 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/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Question about ppc4xx_dma.h
2002-08-21 22:17 ` Todd Poynor
2002-08-22 6:18 ` akuster
@ 2002-08-27 3:44 ` akuster
1 sibling, 0 replies; 6+ messages in thread
From: akuster @ 2002-08-27 3:44 UTC (permalink / raw)
To: Todd Poynor; +Cc: jim, linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 898 bytes --]
Todd Poynor wrote:
>
> 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
[-- Attachment #2: dma_fix_0826.patch --]
[-- Type: text/plain, Size: 5058 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux 2.4 for PowerPC development tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1140 -> 1.1141
# arch/ppc/kernel/ppc4xx_dma.c 1.14 -> 1.15
# include/asm-ppc/ppc4xx_dma.h 1.15 -> 1.16
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/26 armin@essen.mvista.com 1.1141
# fixed enable to allow more than 1 channel support pointed out by Jim Duey
# added check in enable / disable and for chan > MAX
# added in_use field in struct to make sure you can enable a chan twice
# and new return error code
# --------------------------------------------
#
diff -Nru a/arch/ppc/kernel/ppc4xx_dma.c b/arch/ppc/kernel/ppc4xx_dma.c
--- a/arch/ppc/kernel/ppc4xx_dma.c Mon Aug 26 20:37:25 2002
+++ b/arch/ppc/kernel/ppc4xx_dma.c Mon Aug 26 20:37:25 2002
@@ -34,6 +34,11 @@
*
* Version 1.2 07/23/02 - Armin
* added CE to stuct in get_config
+ *
+ * Version 1.3 08/21/02 - Armin
+ * fixed enable to allow more than 1 channel support pointed out by
+ * Jim Duey
+ *
*
*/
@@ -136,8 +141,12 @@
enable_dma(unsigned int dmanr)
{
unsigned int control;
+ unsigned int tmp_cntl = 0;
ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+ if (p_dma_ch->in_use)
+ return DMA_STATUS_CHANNEL_NOTFREE;
+
if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
printk("enable_dma: bad channel: %d\n", dmanr);
return DMA_STATUS_BAD_CHANNEL;
@@ -153,15 +162,39 @@
set_dst_addr(dmanr, 0);
}
/* 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) {
+ if (p_dma_ch->mode == DMA_MODE_MM) {
/* software initiated memory to memory */
- control |= control | DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
+ tmp_cntl |= DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
}
- control |= (p_dma_ch->mode | DMA_CH_ENABLE);
- mtdcr(DCRN_DMACR0, control);
+ tmp_cntl |= (p_dma_ch->mode | DMA_CH_ENABLE);
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ control |= tmp_cntl;
+ mtdcr(DCRN_DMACR0, control);
+ break;
+ case 1:
+ control = mfdcr(DCRN_DMACR1);
+ control |= tmp_cntl;
+ mtdcr(DCRN_DMACR1, control);
+ break;
+ case 2:
+ control = mfdcr(DCRN_DMACR2);
+ control |= tmp_cntl;
+ mtdcr(DCRN_DMACR2, control);
+ break;
+ case 3:
+ control = mfdcr(DCRN_DMACR3);
+ control |= tmp_cntl;
+ mtdcr(DCRN_DMACR3, control);
+ break;
+ default:
+#ifdef DEBUG_4xxDMA
+ printk("enable_dma: bad channel: %d\n", dmanr);
+#endif
+ }
+ p_dma_ch->in_use = 1;
return DMA_STATUS_GOOD;
}
@@ -169,6 +202,15 @@
disable_dma(unsigned int dmanr)
{
unsigned int control;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ if (!p_dma_ch->in_use)
+ return DMA_STATUS_CHANNEL_NOTFREE;
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("enable_dma: bad channel: %d\n", dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
switch (dmanr) {
case 0:
@@ -196,6 +238,7 @@
printk("disable_dma: bad channel: %d\n", dmanr);
#endif
}
+ p_dma_ch->in_use = 0;
}
/*
@@ -348,6 +391,12 @@
set_dma_addr(unsigned int dmanr, phys_addr_t addr)
{
ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("enable_dma: bad channel: %d\n", dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
#ifdef DEBUG_4xxDMA
{
int error = 0;
@@ -495,7 +544,7 @@
unsigned int control;
ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
- p_dma_ch->int_enable = TRUE;
+ p_dma_ch->int_enable = FALSE;
switch (dmanr) {
case 0:
control = mfdcr(DCRN_DMACR0);
@@ -545,11 +594,11 @@
DMA_MODE_READ = (unsigned long) DMA_TD; /* Peripheral to Memory */
DMA_MODE_WRITE = 0; /* Memory to Peripheral */
-#ifdef DEBUG_4xxDMA
if (!p_init) {
printk("hw_init_dma_channel: NULL p_init\n");
return DMA_STATUS_NULL_POINTER;
}
+#ifdef DEBUG_4xxDMA
if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
printk("hw_init_dma_channel: bad channel %d\n", dmanr);
return DMA_STATUS_BAD_CHANNEL;
diff -Nru a/include/asm-ppc/ppc4xx_dma.h b/include/asm-ppc/ppc4xx_dma.h
--- a/include/asm-ppc/ppc4xx_dma.h Mon Aug 26 20:37:25 2002
+++ b/include/asm-ppc/ppc4xx_dma.h Mon Aug 26 20:37:25 2002
@@ -26,6 +26,10 @@
* moved scatter/gather inline code to ppc4xx_sgdma.c
* added three new extern proto types for the STBxxxx API's
*
+ * version 1.4: 08/26/02 - Armin
+ * added in_use field for when a channel is claimed
+ * added new return code *_NOTFREE
+ *
*/
#ifdef __KERNEL__
@@ -57,6 +61,7 @@
#define DMA_STATUS_OUT_OF_MEMORY 5
#define DMA_STATUS_SGL_LIST_EMPTY 6
#define DMA_STATUS_GENERAL_ERROR 7
+#define DMA_STATUS_CHANNEL_NOTFREE 8
#define DMA_CHANNEL_BUSY 0x80000000
@@ -411,7 +416,9 @@
#endif
typedef struct {
-
+ bool in_use; /* set when channel is being used, clr when
+ avaliable
+ */
/*
* Valid polarity settings:
* DMAReq0_ActiveLow
[-- Attachment #3: dma_fix_0826.patch.gz --]
[-- Type: application/x-gunzip, Size: 1796 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2002-08-27 3:44 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-08-20 15:26 Question about ppc4xx_dma.h jim
2002-08-20 23:18 ` akuster
2002-08-21 19:39 ` akuster
2002-08-21 22:17 ` Todd Poynor
2002-08-22 6:18 ` akuster
2002-08-27 3:44 ` akuster
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).