From: akuster <akuster@dslextreme.com>
To: Todd Poynor <tpoynor@mvista.com>
Cc: jim <jduey@ccc-dcs.com>, linuxppc-embedded@lists.linuxppc.org
Subject: Re: Question about ppc4xx_dma.h
Date: Mon, 26 Aug 2002 20:44:18 -0700 [thread overview]
Message-ID: <3D6AF592.9090402@dslextreme.com> (raw)
In-Reply-To: 3D641186.2020800@mvista.com
[-- 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 --]
prev parent reply other threads:[~2002-08-27 3:44 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
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 message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3D6AF592.9090402@dslextreme.com \
--to=akuster@dslextreme.com \
--cc=jduey@ccc-dcs.com \
--cc=linuxppc-embedded@lists.linuxppc.org \
--cc=tpoynor@mvista.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).