* [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine
@ 2017-05-03 10:56 Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 1/4] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters Peter Ujfalusi
` (4 more replies)
0 siblings, 5 replies; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-03 10:56 UTC (permalink / raw)
To: b-liu, tony, gregkh; +Cc: linux-usb, linux-omap, balbi, linux-kernel
Hi,
With port_window support implemented in DMAengine and the sDMA DMAengine driver,
the tusb6010_omap driver can be converted away from the custom legacy omap-dma
API to generic DMAengine.
The first two patch is to prepare the tusb6010_omap driver for the conversion.
The third one adds the needed entries for the dma_slave_map so we can request
the DMA channels. This can be reverted when the stack is converted to DT.
The last patch does the main work to move the driver to DMAengine API.
I have tested the set on top of next-20170503 on Nokia n810 with nfsroot using
CDC Ethernet (g_cdc) and copying files with scp to/form my host.
To force that the DMA is actually used I have:
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 05aefcad40b5..a5fc2a6bdad3 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -216,8 +216,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
* use a timer for the callback, but it is unsafe as the XFR_SIZE
* register is corrupt, and we won't know if the DMA worked.
*/
- if (dma_addr & 0x2)
- return false;
+// if (dma_addr & 0x2)
+// return false;
/*
* Because of HW issue #10, it seems like mixing sync DMA and async
Since this condition will almost all the time was true - effectively disabling
the DMA use.
Regards.
Peter
---
Peter Ujfalusi (4):
usb: musb: tusb6010_omap: Create new struct for DMA data/parameters
usb: musb: tusb6010_omap: Allocate DMA channels upfront
ARM: OMAP2+: DMA: Add slave map entries for 24xx external request
lines
usb: musb: tusb6010_omap: Convert to DMAengine API
arch/arm/mach-omap2/dma.c | 24 +++
drivers/usb/musb/tusb6010_omap.c | 342 ++++++++++++++++++---------------------
2 files changed, 177 insertions(+), 189 deletions(-)
--
2.12.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 1/4] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters
2017-05-03 10:56 [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Peter Ujfalusi
@ 2017-05-03 10:56 ` Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 2/4] usb: musb: tusb6010_omap: Allocate DMA channels upfront Peter Ujfalusi
` (3 subsequent siblings)
4 siblings, 0 replies; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-03 10:56 UTC (permalink / raw)
To: b-liu, tony, gregkh; +Cc: linux-usb, linux-omap, balbi, linux-kernel
For the DMA we have ch (channel), dmareq and sync_dev parameters both
within the tusb_omap_dma_ch and tusb_omap_dma_ch struct.
By creating a common struct the code can be simplified when selecting
between the shared or multichannel DMA parameters.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
drivers/usb/musb/tusb6010_omap.c | 163 ++++++++++++++++++++-------------------
1 file changed, 84 insertions(+), 79 deletions(-)
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 8b43c4b99f04..2abd7895c3af 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -31,6 +31,12 @@
#define OMAP242X_DMA_EXT_DMAREQ4 16
#define OMAP242X_DMA_EXT_DMAREQ5 64
+struct tusb_dma_data {
+ int ch;
+ s8 dmareq;
+ s8 sync_dev;
+};
+
struct tusb_omap_dma_ch {
struct musb *musb;
void __iomem *tbase;
@@ -39,9 +45,7 @@ struct tusb_omap_dma_ch {
u8 tx;
struct musb_hw_ep *hw_ep;
- int ch;
- s8 dmareq;
- s8 sync_dev;
+ struct tusb_dma_data dma_data;
struct tusb_omap_dma *tusb_dma;
@@ -58,9 +62,7 @@ struct tusb_omap_dma {
struct dma_controller controller;
void __iomem *tbase;
- int ch;
- s8 dmareq;
- s8 sync_dev;
+ struct tusb_dma_data dma_data;
unsigned multichannel:1;
};
@@ -119,9 +121,9 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
spin_lock_irqsave(&musb->lock, flags);
if (tusb_dma->multichannel)
- ch = chdat->ch;
+ ch = chdat->dma_data.ch;
else
- ch = tusb_dma->ch;
+ ch = tusb_dma->dma_data.ch;
if (ch_status != OMAP_DMA_BLOCK_IRQ)
printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status);
@@ -140,8 +142,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
/* HW issue #10: XFR_SIZE may get corrupt on DMA (both async & sync) */
if (unlikely(remaining > chdat->transfer_len)) {
dev_dbg(musb->controller, "Corrupt %s dma ch%i XFR_SIZE: 0x%08lx\n",
- chdat->tx ? "tx" : "rx", chdat->ch,
- remaining);
+ chdat->tx ? "tx" : "rx", ch, remaining);
remaining = 0;
}
@@ -219,9 +220,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
u32 dma_remaining;
int src_burst, dst_burst;
u16 csr;
- int ch;
- s8 dmareq;
- s8 sync_dev;
+ struct tusb_dma_data *dma_data;
if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
return false;
@@ -248,7 +247,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dma_remaining = TUSB_EP_CONFIG_XFR_SIZE(dma_remaining);
if (dma_remaining) {
dev_dbg(musb->controller, "Busy %s dma ch%i, not using: %08x\n",
- chdat->tx ? "tx" : "rx", chdat->ch,
+ chdat->tx ? "tx" : "rx", chdat->dma_data.ch,
dma_remaining);
return false;
}
@@ -261,15 +260,15 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
chdat->transfer_packet_sz = packet_sz;
if (tusb_dma->multichannel) {
- ch = chdat->ch;
- dmareq = chdat->dmareq;
- sync_dev = chdat->sync_dev;
+ dma_data = &chdat->dma_data;
} else {
+ dma_data = &tusb_dma->dma_data;
+
if (tusb_omap_use_shared_dmareq(chdat) != 0) {
dev_dbg(musb->controller, "could not get dma for ep%i\n", chdat->epnum);
return false;
}
- if (tusb_dma->ch < 0) {
+ if (dma_data->ch < 0) {
/* REVISIT: This should get blocked earlier, happens
* with MSC ErrorRecoveryTest
*/
@@ -277,10 +276,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
return false;
}
- ch = tusb_dma->ch;
- dmareq = tusb_dma->dmareq;
- sync_dev = tusb_dma->sync_dev;
- omap_set_dma_callback(ch, tusb_omap_dma_cb, channel);
+ omap_set_dma_callback(dma_data->ch, tusb_omap_dma_cb, channel);
}
chdat->packet_sz = packet_sz;
@@ -311,7 +307,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %pad len: %u(%u) packet_sz: %i(%i)\n",
chdat->epnum, chdat->tx ? "tx" : "rx",
- ch, &dma_addr, chdat->transfer_len, len,
+ dma_data->ch, &dma_addr, chdat->transfer_len, len,
chdat->transfer_packet_sz, packet_sz);
/*
@@ -328,7 +324,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dma_params.dst_ei = 1;
dma_params.dst_fi = -31; /* Loop 32 byte window */
- dma_params.trigger = sync_dev;
+ dma_params.trigger = dma_data->sync_dev;
dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
dma_params.src_or_dst_synch = 0; /* Dest sync */
@@ -345,7 +341,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dma_params.dst_ei = 0;
dma_params.dst_fi = 0;
- dma_params.trigger = sync_dev;
+ dma_params.trigger = dma_data->sync_dev;
dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
dma_params.src_or_dst_synch = 1; /* Source sync */
@@ -359,10 +355,10 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
((dma_addr & 0x3) == 0) ? "sync" : "async",
dma_params.src_start, dma_params.dst_start);
- omap_set_dma_params(ch, &dma_params);
- omap_set_dma_src_burst_mode(ch, src_burst);
- omap_set_dma_dest_burst_mode(ch, dst_burst);
- omap_set_dma_write_mode(ch, OMAP_DMA_WRITE_LAST_NON_POSTED);
+ omap_set_dma_params(dma_data->ch, &dma_params);
+ omap_set_dma_src_burst_mode(dma_data->ch, src_burst);
+ omap_set_dma_dest_burst_mode(dma_data->ch, dst_burst);
+ omap_set_dma_write_mode(dma_data->ch, OMAP_DMA_WRITE_LAST_NON_POSTED);
/*
* Prepare MUSB for DMA transfer
@@ -386,7 +382,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
/*
* Start DMA transfer
*/
- omap_start_dma(ch);
+ omap_start_dma(dma_data->ch);
if (chdat->tx) {
/* Send transfer_packet_sz packets at a time */
@@ -411,16 +407,17 @@ static int tusb_omap_dma_abort(struct dma_channel *channel)
{
struct tusb_omap_dma_ch *chdat = to_chdat(channel);
struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
+ struct tusb_dma_data *dma_data = &tusb_dma->dma_data;
if (!tusb_dma->multichannel) {
- if (tusb_dma->ch >= 0) {
- omap_stop_dma(tusb_dma->ch);
- omap_free_dma(tusb_dma->ch);
- tusb_dma->ch = -1;
+ if (dma_data->ch >= 0) {
+ omap_stop_dma(dma_data->ch);
+ omap_free_dma(dma_data->ch);
+ dma_data->ch = -1;
}
- tusb_dma->dmareq = -1;
- tusb_dma->sync_dev = -1;
+ dma_data->dmareq = -1;
+ dma_data->sync_dev = -1;
}
channel->status = MUSB_DMA_STATUS_FREE;
@@ -458,8 +455,8 @@ static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
reg |= ((1 << 4) << (dmareq_nr * 5));
musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
- chdat->dmareq = dmareq_nr;
- chdat->sync_dev = sync_dev[chdat->dmareq];
+ chdat->dma_data.dmareq = dmareq_nr;
+ chdat->dma_data.sync_dev = sync_dev[chdat->dma_data.dmareq];
return 0;
}
@@ -468,15 +465,15 @@ static inline void tusb_omap_dma_free_dmareq(struct tusb_omap_dma_ch *chdat)
{
u32 reg;
- if (!chdat || chdat->dmareq < 0)
+ if (!chdat || chdat->dma_data.dmareq < 0)
return;
reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
- reg &= ~(0x1f << (chdat->dmareq * 5));
+ reg &= ~(0x1f << (chdat->dma_data.dmareq * 5));
musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
- chdat->dmareq = -1;
- chdat->sync_dev = -1;
+ chdat->dma_data.dmareq = -1;
+ chdat->dma_data.sync_dev = -1;
}
static struct dma_channel *dma_channel_pool[MAX_DMAREQ];
@@ -488,11 +485,13 @@ tusb_omap_dma_allocate(struct dma_controller *c,
{
int ret, i;
const char *dev_name;
+ void *cb_data;
struct tusb_omap_dma *tusb_dma;
struct musb *musb;
void __iomem *tbase;
struct dma_channel *channel = NULL;
struct tusb_omap_dma_ch *chdat = NULL;
+ struct tusb_dma_data *dma_data = NULL;
u32 reg;
tusb_dma = container_of(c, struct tusb_omap_dma, controller);
@@ -525,56 +524,61 @@ tusb_omap_dma_allocate(struct dma_controller *c,
if (!channel)
return NULL;
- if (tx) {
- chdat->tx = 1;
- dev_name = "TUSB transmit";
- } else {
- chdat->tx = 0;
- dev_name = "TUSB receive";
- }
-
chdat->musb = tusb_dma->controller.musb;
chdat->tbase = tusb_dma->tbase;
chdat->hw_ep = hw_ep;
chdat->epnum = hw_ep->epnum;
- chdat->dmareq = -1;
chdat->completed_len = 0;
chdat->tusb_dma = tusb_dma;
+ if (tx)
+ chdat->tx = 1;
+ else
+ chdat->tx = 0;
channel->max_len = 0x7fffffff;
channel->desired_mode = 0;
channel->actual_len = 0;
if (tusb_dma->multichannel) {
+ dma_data = &chdat->dma_data;
ret = tusb_omap_dma_allocate_dmareq(chdat);
if (ret != 0)
goto free_dmareq;
- ret = omap_request_dma(chdat->sync_dev, dev_name,
- tusb_omap_dma_cb, channel, &chdat->ch);
- if (ret != 0)
- goto free_dmareq;
- } else if (tusb_dma->ch == -1) {
- tusb_dma->dmareq = 0;
- tusb_dma->sync_dev = OMAP24XX_DMA_EXT_DMAREQ0;
-
+ if (chdat->tx)
+ dev_name = "TUSB transmit";
+ else
+ dev_name = "TUSB receive";
+ cb_data = channel;
+ } else if (tusb_dma->dma_data.ch == -1) {
+ dma_data = &tusb_dma->dma_data;
+ dma_data->dmareq = 0;
+ dma_data->sync_dev = OMAP24XX_DMA_EXT_DMAREQ0;
+
+ dev_name = "TUSB shared";
/* Callback data gets set later in the shared dmareq case */
- ret = omap_request_dma(tusb_dma->sync_dev, "TUSB shared",
- tusb_omap_dma_cb, NULL, &tusb_dma->ch);
+ cb_data = NULL;
+
+ chdat->dma_data.dmareq = -1;
+ chdat->dma_data.ch = -1;
+ chdat->dma_data.sync_dev = -1;
+ }
+
+ if (dma_data) {
+ ret = omap_request_dma(dma_data->sync_dev, dev_name,
+ tusb_omap_dma_cb, cb_data, &dma_data->ch);
if (ret != 0)
goto free_dmareq;
-
- chdat->dmareq = -1;
- chdat->ch = -1;
+ } else {
+ /* Already allocated shared, single DMA channel. */
+ dma_data = &tusb_dma->dma_data;
}
dev_dbg(musb->controller, "ep%i %s dma: %s dma%i dmareq%i sync%i\n",
chdat->epnum,
chdat->tx ? "tx" : "rx",
- chdat->ch >= 0 ? "dedicated" : "shared",
- chdat->ch >= 0 ? chdat->ch : tusb_dma->ch,
- chdat->dmareq >= 0 ? chdat->dmareq : tusb_dma->dmareq,
- chdat->sync_dev >= 0 ? chdat->sync_dev : tusb_dma->sync_dev);
+ chdat->dma_data.ch >= 0 ? "dedicated" : "shared",
+ dma_data->ch, dma_data->dmareq, dma_data->sync_dev);
return channel;
@@ -594,7 +598,8 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
void __iomem *tbase = musb->ctrl_base;
u32 reg;
- dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum, chdat->ch);
+ dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum,
+ chdat->dma_data.ch);
reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
if (chdat->tx)
@@ -612,13 +617,13 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
channel->status = MUSB_DMA_STATUS_UNKNOWN;
- if (chdat->ch >= 0) {
- omap_stop_dma(chdat->ch);
- omap_free_dma(chdat->ch);
- chdat->ch = -1;
+ if (chdat->dma_data.ch >= 0) {
+ omap_stop_dma(chdat->dma_data.ch);
+ omap_free_dma(chdat->dma_data.ch);
+ chdat->dma_data.ch = -1;
}
- if (chdat->dmareq >= 0)
+ if (chdat->dma_data.dmareq >= 0)
tusb_omap_dma_free_dmareq(chdat);
channel = NULL;
@@ -638,8 +643,8 @@ void tusb_dma_controller_destroy(struct dma_controller *c)
}
}
- if (tusb_dma && !tusb_dma->multichannel && tusb_dma->ch >= 0)
- omap_free_dma(tusb_dma->ch);
+ if (tusb_dma && !tusb_dma->multichannel && tusb_dma->dma_data.ch >= 0)
+ omap_free_dma(tusb_dma->dma_data.ch);
kfree(tusb_dma);
}
@@ -669,9 +674,9 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base)
tusb_dma->controller.musb = musb;
tusb_dma->tbase = musb->ctrl_base;
- tusb_dma->ch = -1;
- tusb_dma->dmareq = -1;
- tusb_dma->sync_dev = -1;
+ tusb_dma->dma_data.ch = -1;
+ tusb_dma->dma_data.dmareq = -1;
+ tusb_dma->dma_data.sync_dev = -1;
tusb_dma->controller.channel_alloc = tusb_omap_dma_allocate;
tusb_dma->controller.channel_release = tusb_omap_dma_release;
--
2.12.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/4] usb: musb: tusb6010_omap: Allocate DMA channels upfront
2017-05-03 10:56 [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 1/4] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters Peter Ujfalusi
@ 2017-05-03 10:56 ` Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 3/4] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines Peter Ujfalusi
` (2 subsequent siblings)
4 siblings, 0 replies; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-03 10:56 UTC (permalink / raw)
To: b-liu, tony, gregkh; +Cc: linux-usb, linux-omap, balbi, linux-kernel
Instead of requesting the DMA channel in tusb_omap_dma_allocate() do it
when the controller is created and in runtime work from the DMA channel
pool.
This change is needed for the DMAengine conversion of the driver since the
tusb_omap_dma_allocate() is called in interrupt context which might lead
to lock within the DMAengine API when requesting channel.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
drivers/usb/musb/tusb6010_omap.c | 184 +++++++++++++++++++--------------------
1 file changed, 92 insertions(+), 92 deletions(-)
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 2abd7895c3af..244b7b7cd26a 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -45,7 +45,7 @@ struct tusb_omap_dma_ch {
u8 tx;
struct musb_hw_ep *hw_ep;
- struct tusb_dma_data dma_data;
+ struct tusb_dma_data *dma_data;
struct tusb_omap_dma *tusb_dma;
@@ -62,7 +62,7 @@ struct tusb_omap_dma {
struct dma_controller controller;
void __iomem *tbase;
- struct tusb_dma_data dma_data;
+ struct tusb_dma_data dma_pool[MAX_DMAREQ];
unsigned multichannel:1;
};
@@ -120,10 +120,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
spin_lock_irqsave(&musb->lock, flags);
- if (tusb_dma->multichannel)
- ch = chdat->dma_data.ch;
- else
- ch = tusb_dma->dma_data.ch;
+ ch = chdat->dma_data->ch;
if (ch_status != OMAP_DMA_BLOCK_IRQ)
printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status);
@@ -247,7 +244,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dma_remaining = TUSB_EP_CONFIG_XFR_SIZE(dma_remaining);
if (dma_remaining) {
dev_dbg(musb->controller, "Busy %s dma ch%i, not using: %08x\n",
- chdat->tx ? "tx" : "rx", chdat->dma_data.ch,
+ chdat->tx ? "tx" : "rx",
+ chdat->dma_data ? chdat->dma_data->ch : -1,
dma_remaining);
return false;
}
@@ -259,11 +257,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
else
chdat->transfer_packet_sz = packet_sz;
- if (tusb_dma->multichannel) {
- dma_data = &chdat->dma_data;
- } else {
- dma_data = &tusb_dma->dma_data;
-
+ dma_data = chdat->dma_data;
+ if (!tusb_dma->multichannel) {
if (tusb_omap_use_shared_dmareq(chdat) != 0) {
dev_dbg(musb->controller, "could not get dma for ep%i\n", chdat->epnum);
return false;
@@ -275,10 +270,10 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
WARN_ON(1);
return false;
}
-
- omap_set_dma_callback(dma_data->ch, tusb_omap_dma_cb, channel);
}
+ omap_set_dma_callback(dma_data->ch, tusb_omap_dma_cb, channel);
+
chdat->packet_sz = packet_sz;
chdat->len = len;
channel->actual_len = 0;
@@ -406,19 +401,9 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
static int tusb_omap_dma_abort(struct dma_channel *channel)
{
struct tusb_omap_dma_ch *chdat = to_chdat(channel);
- struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
- struct tusb_dma_data *dma_data = &tusb_dma->dma_data;
- if (!tusb_dma->multichannel) {
- if (dma_data->ch >= 0) {
- omap_stop_dma(dma_data->ch);
- omap_free_dma(dma_data->ch);
- dma_data->ch = -1;
- }
-
- dma_data->dmareq = -1;
- dma_data->sync_dev = -1;
- }
+ if (chdat->dma_data)
+ omap_stop_dma(chdat->dma_data->ch);
channel->status = MUSB_DMA_STATUS_FREE;
@@ -430,15 +415,6 @@ static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
u32 reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
int i, dmareq_nr = -1;
- const int sync_dev[6] = {
- OMAP24XX_DMA_EXT_DMAREQ0,
- OMAP24XX_DMA_EXT_DMAREQ1,
- OMAP242X_DMA_EXT_DMAREQ2,
- OMAP242X_DMA_EXT_DMAREQ3,
- OMAP242X_DMA_EXT_DMAREQ4,
- OMAP242X_DMA_EXT_DMAREQ5,
- };
-
for (i = 0; i < MAX_DMAREQ; i++) {
int cur = (reg & (0xf << (i * 5))) >> (i * 5);
if (cur == 0) {
@@ -455,8 +431,7 @@ static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
reg |= ((1 << 4) << (dmareq_nr * 5));
musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
- chdat->dma_data.dmareq = dmareq_nr;
- chdat->dma_data.sync_dev = sync_dev[chdat->dma_data.dmareq];
+ chdat->dma_data = &chdat->tusb_dma->dma_pool[dmareq_nr];
return 0;
}
@@ -465,15 +440,14 @@ static inline void tusb_omap_dma_free_dmareq(struct tusb_omap_dma_ch *chdat)
{
u32 reg;
- if (!chdat || chdat->dma_data.dmareq < 0)
+ if (!chdat || !chdat->dma_data || chdat->dma_data->dmareq < 0)
return;
reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
- reg &= ~(0x1f << (chdat->dma_data.dmareq * 5));
+ reg &= ~(0x1f << (chdat->dma_data->dmareq * 5));
musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
- chdat->dma_data.dmareq = -1;
- chdat->dma_data.sync_dev = -1;
+ chdat->dma_data = NULL;
}
static struct dma_channel *dma_channel_pool[MAX_DMAREQ];
@@ -484,8 +458,6 @@ tusb_omap_dma_allocate(struct dma_controller *c,
u8 tx)
{
int ret, i;
- const char *dev_name;
- void *cb_data;
struct tusb_omap_dma *tusb_dma;
struct musb *musb;
void __iomem *tbase;
@@ -539,45 +511,22 @@ tusb_omap_dma_allocate(struct dma_controller *c,
channel->desired_mode = 0;
channel->actual_len = 0;
- if (tusb_dma->multichannel) {
- dma_data = &chdat->dma_data;
- ret = tusb_omap_dma_allocate_dmareq(chdat);
- if (ret != 0)
- goto free_dmareq;
-
- if (chdat->tx)
- dev_name = "TUSB transmit";
- else
- dev_name = "TUSB receive";
- cb_data = channel;
- } else if (tusb_dma->dma_data.ch == -1) {
- dma_data = &tusb_dma->dma_data;
- dma_data->dmareq = 0;
- dma_data->sync_dev = OMAP24XX_DMA_EXT_DMAREQ0;
-
- dev_name = "TUSB shared";
- /* Callback data gets set later in the shared dmareq case */
- cb_data = NULL;
-
- chdat->dma_data.dmareq = -1;
- chdat->dma_data.ch = -1;
- chdat->dma_data.sync_dev = -1;
+ if (!chdat->dma_data) {
+ if (tusb_dma->multichannel) {
+ ret = tusb_omap_dma_allocate_dmareq(chdat);
+ if (ret != 0)
+ goto free_dmareq;
+ } else {
+ chdat->dma_data = &tusb_dma->dma_pool[0];
+ }
}
- if (dma_data) {
- ret = omap_request_dma(dma_data->sync_dev, dev_name,
- tusb_omap_dma_cb, cb_data, &dma_data->ch);
- if (ret != 0)
- goto free_dmareq;
- } else {
- /* Already allocated shared, single DMA channel. */
- dma_data = &tusb_dma->dma_data;
- }
+ dma_data = chdat->dma_data;
dev_dbg(musb->controller, "ep%i %s dma: %s dma%i dmareq%i sync%i\n",
chdat->epnum,
chdat->tx ? "tx" : "rx",
- chdat->dma_data.ch >= 0 ? "dedicated" : "shared",
+ tusb_dma->multichannel ? "shared" : "dedicated",
dma_data->ch, dma_data->dmareq, dma_data->sync_dev);
return channel;
@@ -599,7 +548,7 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
u32 reg;
dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum,
- chdat->dma_data.ch);
+ chdat->dma_data->ch);
reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
if (chdat->tx)
@@ -617,14 +566,8 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
channel->status = MUSB_DMA_STATUS_UNKNOWN;
- if (chdat->dma_data.ch >= 0) {
- omap_stop_dma(chdat->dma_data.ch);
- omap_free_dma(chdat->dma_data.ch);
- chdat->dma_data.ch = -1;
- }
-
- if (chdat->dma_data.dmareq >= 0)
- tusb_omap_dma_free_dmareq(chdat);
+ omap_stop_dma(chdat->dma_data->ch);
+ tusb_omap_dma_free_dmareq(chdat);
channel = NULL;
}
@@ -641,15 +584,73 @@ void tusb_dma_controller_destroy(struct dma_controller *c)
kfree(ch->private_data);
kfree(ch);
}
- }
- if (tusb_dma && !tusb_dma->multichannel && tusb_dma->dma_data.ch >= 0)
- omap_free_dma(tusb_dma->dma_data.ch);
+ /* Free up the DMA channels */
+ if (tusb_dma && tusb_dma->dma_pool[i].ch >= 0)
+ omap_free_dma(tusb_dma->dma_pool[i].ch);
+ }
kfree(tusb_dma);
}
EXPORT_SYMBOL_GPL(tusb_dma_controller_destroy);
+static int tusb_omap_allocate_dma_pool(struct tusb_omap_dma *tusb_dma)
+{
+ int i;
+ int ret = 0;
+ const int sync_dev[6] = {
+ OMAP24XX_DMA_EXT_DMAREQ0,
+ OMAP24XX_DMA_EXT_DMAREQ1,
+ OMAP242X_DMA_EXT_DMAREQ2,
+ OMAP242X_DMA_EXT_DMAREQ3,
+ OMAP242X_DMA_EXT_DMAREQ4,
+ OMAP242X_DMA_EXT_DMAREQ5,
+ };
+
+ for (i = 0; i < MAX_DMAREQ; i++) {
+ struct tusb_dma_data *dma_data = &tusb_dma->dma_pool[i];
+
+ /*
+ * Request DMA channels:
+ * - one channel in case of non multichannel mode
+ * - MAX_DMAREQ number of channels in multichannel mode
+ */
+ if (i == 0 || tusb_dma->multichannel) {
+ char ch_name[8];
+
+ sprintf(ch_name, "dmareq%d", i);
+ dma_data->sync_dev = sync_dev[i];
+ dma_data->ch = -1;
+ /* callback data is ngoing to be set later */
+ ret = omap_request_dma(dma_data->sync_dev, ch_name,
+ tusb_omap_dma_cb, NULL, &dma_data->ch);
+ if (ret != 0) {
+ dev_err(tusb_dma->controller.musb->controller,
+ "Failed to request %s\n", ch_name);
+ goto dma_error;
+ }
+
+ dma_data->dmareq = i;
+ } else {
+ dma_data->dmareq = -1;
+ dma_data->sync_dev = -1;
+ dma_data->ch = -1;
+ }
+ }
+
+ return 0;
+
+dma_error:
+ for (; i >= 0; i--) {
+ struct tusb_dma_data *dma_data = &tusb_dma->dma_pool[i];
+
+ if (dma_data->ch >= 0)
+ omap_free_dma(dma_data->ch);
+ }
+
+ return ret;
+}
+
struct dma_controller *
tusb_dma_controller_create(struct musb *musb, void __iomem *base)
{
@@ -674,10 +675,6 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base)
tusb_dma->controller.musb = musb;
tusb_dma->tbase = musb->ctrl_base;
- tusb_dma->dma_data.ch = -1;
- tusb_dma->dma_data.dmareq = -1;
- tusb_dma->dma_data.sync_dev = -1;
-
tusb_dma->controller.channel_alloc = tusb_omap_dma_allocate;
tusb_dma->controller.channel_release = tusb_omap_dma_release;
tusb_dma->controller.channel_program = tusb_omap_dma_program;
@@ -704,6 +701,9 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base)
ch->private_data = chdat;
}
+ if (tusb_omap_allocate_dma_pool(tusb_dma))
+ goto cleanup;
+
return &tusb_dma->controller;
cleanup:
--
2.12.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/4] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines
2017-05-03 10:56 [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 1/4] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 2/4] usb: musb: tusb6010_omap: Allocate DMA channels upfront Peter Ujfalusi
@ 2017-05-03 10:56 ` Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API Peter Ujfalusi
2017-05-04 14:31 ` [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Tony Lindgren
4 siblings, 0 replies; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-03 10:56 UTC (permalink / raw)
To: b-liu, tony, gregkh; +Cc: linux-usb, linux-omap, balbi, linux-kernel
The external request lines are used by tusb6010 on OMAP24xx platforms.
Update the map so the driver can use dmaengine API to request the DMA
channel. At the same time add temporary map containing only the external
DMA request numbers for DT booted case on omap24xx since the tusb6010 stack
is not yet supports DT boot.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
arch/arm/mach-omap2/dma.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index e58c13a9bea5..0b77a0176018 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -249,6 +249,24 @@ static const struct dma_slave_map omap24xx_sdma_map[] = {
{ "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) },
{ "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) },
{ "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) },
+
+ /* external DMA requests when tusb6010 is used */
+ { "musb-tusb", "dmareq0", SDMA_FILTER_PARAM(2) },
+ { "musb-tusb", "dmareq1", SDMA_FILTER_PARAM(3) },
+ { "musb-tusb", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */
+ { "musb-tusb", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */
+ { "musb-tusb", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */
+ { "musb-tusb", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
+};
+
+static const struct dma_slave_map omap24xx_sdma_dt_map[] = {
+ /* external DMA requests when tusb6010 is used */
+ { "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) },
+ { "musb-hdrc.1.auto", "dmareq1", SDMA_FILTER_PARAM(3) },
+ { "musb-hdrc.1.auto", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */
+ { "musb-hdrc.1.auto", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */
+ { "musb-hdrc.1.auto", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */
+ { "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
};
static const struct dma_slave_map omap3xxx_sdma_map[] = {
@@ -346,6 +364,12 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
__func__);
return -ENODEV;
}
+ } else {
+ if (soc_is_omap24xx()) {
+ /* DMA slave map for drivers not yet converted to DT */
+ p.slave_map = omap24xx_sdma_dt_map;
+ p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map);
+ }
}
pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
--
2.12.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API
2017-05-03 10:56 [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Peter Ujfalusi
` (2 preceding siblings ...)
2017-05-03 10:56 ` [PATCH 3/4] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines Peter Ujfalusi
@ 2017-05-03 10:56 ` Peter Ujfalusi
2017-05-04 19:40 ` Tony Lindgren
2017-05-04 14:31 ` [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Tony Lindgren
4 siblings, 1 reply; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-03 10:56 UTC (permalink / raw)
To: b-liu, tony, gregkh; +Cc: linux-usb, linux-omap, balbi, linux-kernel
With the port_window support in DMAengine and the sDMA driver we can
convert the driver to DMAengine.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
drivers/usb/musb/tusb6010_omap.c | 201 ++++++++++++++++-----------------------
1 file changed, 80 insertions(+), 121 deletions(-)
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 244b7b7cd26a..05aefcad40b5 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -15,7 +15,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
-#include <linux/omap-dma.h>
+#include <linux/dmaengine.h>
#include "musb_core.h"
#include "tusb6010.h"
@@ -24,17 +24,9 @@
#define MAX_DMAREQ 5 /* REVISIT: Really 6, but req5 not OK */
-#define OMAP24XX_DMA_EXT_DMAREQ0 2
-#define OMAP24XX_DMA_EXT_DMAREQ1 3
-#define OMAP242X_DMA_EXT_DMAREQ2 14
-#define OMAP242X_DMA_EXT_DMAREQ3 15
-#define OMAP242X_DMA_EXT_DMAREQ4 16
-#define OMAP242X_DMA_EXT_DMAREQ5 64
-
struct tusb_dma_data {
- int ch;
s8 dmareq;
- s8 sync_dev;
+ struct dma_chan *chan;
};
struct tusb_omap_dma_ch {
@@ -105,7 +97,7 @@ static inline void tusb_omap_free_shared_dmareq(struct tusb_omap_dma_ch *chdat)
* See also musb_dma_completion in plat_uds.c and musb_g_[tx|rx]() in
* musb_gadget.c.
*/
-static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
+static void tusb_omap_dma_cb(void *data)
{
struct dma_channel *channel = (struct dma_channel *)data;
struct tusb_omap_dma_ch *chdat = to_chdat(channel);
@@ -116,18 +108,11 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
void __iomem *ep_conf = hw_ep->conf;
void __iomem *mbase = musb->mregs;
unsigned long remaining, flags, pio;
- int ch;
spin_lock_irqsave(&musb->lock, flags);
- ch = chdat->dma_data->ch;
-
- if (ch_status != OMAP_DMA_BLOCK_IRQ)
- printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status);
-
- dev_dbg(musb->controller, "ep%i %s dma callback ch: %i status: %x\n",
- chdat->epnum, chdat->tx ? "tx" : "rx",
- ch, ch_status);
+ dev_dbg(musb->controller, "ep%i %s dma callback\n",
+ chdat->epnum, chdat->tx ? "tx" : "rx");
if (chdat->tx)
remaining = musb_readl(ep_conf, TUSB_EP_TX_OFFSET);
@@ -138,8 +123,8 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
/* HW issue #10: XFR_SIZE may get corrupt on DMA (both async & sync) */
if (unlikely(remaining > chdat->transfer_len)) {
- dev_dbg(musb->controller, "Corrupt %s dma ch%i XFR_SIZE: 0x%08lx\n",
- chdat->tx ? "tx" : "rx", ch, remaining);
+ dev_dbg(musb->controller, "Corrupt %s XFR_SIZE: 0x%08lx\n",
+ chdat->tx ? "tx" : "rx", remaining);
remaining = 0;
}
@@ -212,12 +197,15 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
struct musb_hw_ep *hw_ep = chdat->hw_ep;
void __iomem *mbase = musb->mregs;
void __iomem *ep_conf = hw_ep->conf;
- dma_addr_t fifo = hw_ep->fifo_sync;
- struct omap_dma_channel_params dma_params;
+ dma_addr_t fifo_addr = hw_ep->fifo_sync;
u32 dma_remaining;
- int src_burst, dst_burst;
u16 csr;
struct tusb_dma_data *dma_data;
+ struct dma_async_tx_descriptor *dma_desc;
+ struct dma_slave_config dma_cfg;
+ enum dma_transfer_direction dma_dir;
+ u32 port_window;
+ int ret;
if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
return false;
@@ -243,10 +231,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dma_remaining = TUSB_EP_CONFIG_XFR_SIZE(dma_remaining);
if (dma_remaining) {
- dev_dbg(musb->controller, "Busy %s dma ch%i, not using: %08x\n",
- chdat->tx ? "tx" : "rx",
- chdat->dma_data ? chdat->dma_data->ch : -1,
- dma_remaining);
+ dev_dbg(musb->controller, "Busy %s dma, not using: %08x\n",
+ chdat->tx ? "tx" : "rx", dma_remaining);
return false;
}
@@ -263,7 +249,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
dev_dbg(musb->controller, "could not get dma for ep%i\n", chdat->epnum);
return false;
}
- if (dma_data->ch < 0) {
+ if (dma_data->dmareq < 0) {
/* REVISIT: This should get blocked earlier, happens
* with MSC ErrorRecoveryTest
*/
@@ -272,8 +258,6 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
}
}
- omap_set_dma_callback(dma_data->ch, tusb_omap_dma_cb, channel);
-
chdat->packet_sz = packet_sz;
chdat->len = len;
channel->actual_len = 0;
@@ -281,79 +265,68 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
channel->status = MUSB_DMA_STATUS_BUSY;
/* Since we're recycling dma areas, we need to clean or invalidate */
- if (chdat->tx)
+ if (chdat->tx) {
+ dma_dir = DMA_MEM_TO_DEV;
dma_map_single(dev, phys_to_virt(dma_addr), len,
DMA_TO_DEVICE);
- else
+ } else {
+ dma_dir = DMA_DEV_TO_MEM;
dma_map_single(dev, phys_to_virt(dma_addr), len,
DMA_FROM_DEVICE);
+ }
+
+ memset(&dma_cfg, 0, sizeof(dma_cfg));
/* Use 16-bit transfer if dma_addr is not 32-bit aligned */
if ((dma_addr & 0x3) == 0) {
- dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
- dma_params.elem_count = 8; /* Elements in frame */
+ dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ port_window = 8;
} else {
- dma_params.data_type = OMAP_DMA_DATA_TYPE_S16;
- dma_params.elem_count = 16; /* Elements in frame */
- fifo = hw_ep->fifo_async;
- }
+ dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ port_window = 16;
- dma_params.frame_count = chdat->transfer_len / 32; /* Burst sz frame */
+ fifo_addr = hw_ep->fifo_async;
+ }
- dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %pad len: %u(%u) packet_sz: %i(%i)\n",
- chdat->epnum, chdat->tx ? "tx" : "rx",
- dma_data->ch, &dma_addr, chdat->transfer_len, len,
- chdat->transfer_packet_sz, packet_sz);
+ dev_dbg(musb->controller,
+ "ep%i %s dma: %pad len: %u(%u) packet_sz: %i(%i)\n",
+ chdat->epnum, chdat->tx ? "tx" : "rx", &dma_addr,
+ chdat->transfer_len, len, chdat->transfer_packet_sz, packet_sz);
+
+ dma_cfg.src_addr = fifo_addr;
+ dma_cfg.dst_addr = fifo_addr;
+ dma_cfg.src_port_window_size = port_window;
+ dma_cfg.src_maxburst = port_window;
+ dma_cfg.dst_port_window_size = port_window;
+ dma_cfg.dst_maxburst = port_window;
+
+ ret = dmaengine_slave_config(dma_data->chan, &dma_cfg);
+ if (ret) {
+ dev_err(musb->controller, "DMA slave config failed: %d\n", ret);
+ return false;
+ }
- /*
- * Prepare omap DMA for transfer
- */
- if (chdat->tx) {
- dma_params.src_amode = OMAP_DMA_AMODE_POST_INC;
- dma_params.src_start = (unsigned long)dma_addr;
- dma_params.src_ei = 0;
- dma_params.src_fi = 0;
-
- dma_params.dst_amode = OMAP_DMA_AMODE_DOUBLE_IDX;
- dma_params.dst_start = (unsigned long)fifo;
- dma_params.dst_ei = 1;
- dma_params.dst_fi = -31; /* Loop 32 byte window */
-
- dma_params.trigger = dma_data->sync_dev;
- dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
- dma_params.src_or_dst_synch = 0; /* Dest sync */
-
- src_burst = OMAP_DMA_DATA_BURST_16; /* 16x32 read */
- dst_burst = OMAP_DMA_DATA_BURST_8; /* 8x32 write */
- } else {
- dma_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX;
- dma_params.src_start = (unsigned long)fifo;
- dma_params.src_ei = 1;
- dma_params.src_fi = -31; /* Loop 32 byte window */
-
- dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
- dma_params.dst_start = (unsigned long)dma_addr;
- dma_params.dst_ei = 0;
- dma_params.dst_fi = 0;
-
- dma_params.trigger = dma_data->sync_dev;
- dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
- dma_params.src_or_dst_synch = 1; /* Source sync */
-
- src_burst = OMAP_DMA_DATA_BURST_8; /* 8x32 read */
- dst_burst = OMAP_DMA_DATA_BURST_16; /* 16x32 write */
+ dma_desc = dmaengine_prep_slave_single(dma_data->chan, dma_addr,
+ chdat->transfer_len, dma_dir,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!dma_desc) {
+ dev_err(musb->controller, "DMA prep_slave_single failed\n");
+ return false;
}
- dev_dbg(musb->controller, "ep%i %s using %i-bit %s dma from 0x%08lx to 0x%08lx\n",
+ dma_desc->callback = tusb_omap_dma_cb;
+ dma_desc->callback_param = channel;
+ dmaengine_submit(dma_desc);
+
+ dev_dbg(musb->controller,
+ "ep%i %s using %i-bit %s dma from %pad to %pad\n",
chdat->epnum, chdat->tx ? "tx" : "rx",
- (dma_params.data_type == OMAP_DMA_DATA_TYPE_S32) ? 32 : 16,
+ dma_cfg.src_addr_width * 8,
((dma_addr & 0x3) == 0) ? "sync" : "async",
- dma_params.src_start, dma_params.dst_start);
-
- omap_set_dma_params(dma_data->ch, &dma_params);
- omap_set_dma_src_burst_mode(dma_data->ch, src_burst);
- omap_set_dma_dest_burst_mode(dma_data->ch, dst_burst);
- omap_set_dma_write_mode(dma_data->ch, OMAP_DMA_WRITE_LAST_NON_POSTED);
+ (dma_dir == DMA_MEM_TO_DEV) ? &dma_addr : &fifo_addr,
+ (dma_dir == DMA_MEM_TO_DEV) ? &fifo_addr : &dma_addr);
/*
* Prepare MUSB for DMA transfer
@@ -374,10 +347,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
csr | MUSB_RXCSR_P_WZC_BITS);
}
- /*
- * Start DMA transfer
- */
- omap_start_dma(dma_data->ch);
+ /* Start DMA transfer */
+ dma_async_issue_pending(dma_data->chan);
if (chdat->tx) {
/* Send transfer_packet_sz packets at a time */
@@ -403,7 +374,7 @@ static int tusb_omap_dma_abort(struct dma_channel *channel)
struct tusb_omap_dma_ch *chdat = to_chdat(channel);
if (chdat->dma_data)
- omap_stop_dma(chdat->dma_data->ch);
+ dmaengine_terminate_sync(chdat->dma_data->chan);
channel->status = MUSB_DMA_STATUS_FREE;
@@ -523,11 +494,11 @@ tusb_omap_dma_allocate(struct dma_controller *c,
dma_data = chdat->dma_data;
- dev_dbg(musb->controller, "ep%i %s dma: %s dma%i dmareq%i sync%i\n",
+ dev_dbg(musb->controller, "ep%i %s dma: %s dmareq%i\n",
chdat->epnum,
chdat->tx ? "tx" : "rx",
tusb_dma->multichannel ? "shared" : "dedicated",
- dma_data->ch, dma_data->dmareq, dma_data->sync_dev);
+ dma_data->dmareq);
return channel;
@@ -547,8 +518,7 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
void __iomem *tbase = musb->ctrl_base;
u32 reg;
- dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum,
- chdat->dma_data->ch);
+ dev_dbg(musb->controller, "Release for ep%i\n", chdat->epnum);
reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
if (chdat->tx)
@@ -566,7 +536,7 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
channel->status = MUSB_DMA_STATUS_UNKNOWN;
- omap_stop_dma(chdat->dma_data->ch);
+ dmaengine_terminate_sync(chdat->dma_data->chan);
tusb_omap_dma_free_dmareq(chdat);
channel = NULL;
@@ -586,8 +556,8 @@ void tusb_dma_controller_destroy(struct dma_controller *c)
}
/* Free up the DMA channels */
- if (tusb_dma && tusb_dma->dma_pool[i].ch >= 0)
- omap_free_dma(tusb_dma->dma_pool[i].ch);
+ if (tusb_dma && tusb_dma->dma_pool[i].chan)
+ dma_release_channel(tusb_dma->dma_pool[i].chan);
}
kfree(tusb_dma);
@@ -596,16 +566,9 @@ EXPORT_SYMBOL_GPL(tusb_dma_controller_destroy);
static int tusb_omap_allocate_dma_pool(struct tusb_omap_dma *tusb_dma)
{
+ struct musb *musb = tusb_dma->controller.musb;
int i;
int ret = 0;
- const int sync_dev[6] = {
- OMAP24XX_DMA_EXT_DMAREQ0,
- OMAP24XX_DMA_EXT_DMAREQ1,
- OMAP242X_DMA_EXT_DMAREQ2,
- OMAP242X_DMA_EXT_DMAREQ3,
- OMAP242X_DMA_EXT_DMAREQ4,
- OMAP242X_DMA_EXT_DMAREQ5,
- };
for (i = 0; i < MAX_DMAREQ; i++) {
struct tusb_dma_data *dma_data = &tusb_dma->dma_pool[i];
@@ -619,22 +582,18 @@ static int tusb_omap_allocate_dma_pool(struct tusb_omap_dma *tusb_dma)
char ch_name[8];
sprintf(ch_name, "dmareq%d", i);
- dma_data->sync_dev = sync_dev[i];
- dma_data->ch = -1;
- /* callback data is ngoing to be set later */
- ret = omap_request_dma(dma_data->sync_dev, ch_name,
- tusb_omap_dma_cb, NULL, &dma_data->ch);
- if (ret != 0) {
- dev_err(tusb_dma->controller.musb->controller,
+ dma_data->chan = dma_request_chan(musb->controller,
+ ch_name);
+ if (IS_ERR(dma_data->chan)) {
+ dev_err(musb->controller,
"Failed to request %s\n", ch_name);
+ ret = PTR_ERR(dma_data->chan);
goto dma_error;
}
dma_data->dmareq = i;
} else {
dma_data->dmareq = -1;
- dma_data->sync_dev = -1;
- dma_data->ch = -1;
}
}
@@ -644,8 +603,8 @@ static int tusb_omap_allocate_dma_pool(struct tusb_omap_dma *tusb_dma)
for (; i >= 0; i--) {
struct tusb_dma_data *dma_data = &tusb_dma->dma_pool[i];
- if (dma_data->ch >= 0)
- omap_free_dma(dma_data->ch);
+ if (dma_data->dmareq >= 0)
+ dma_release_channel(dma_data->chan);
}
return ret;
--
2.12.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine
2017-05-03 10:56 [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Peter Ujfalusi
` (3 preceding siblings ...)
2017-05-03 10:56 ` [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API Peter Ujfalusi
@ 2017-05-04 14:31 ` Tony Lindgren
2017-05-05 7:28 ` Peter Ujfalusi
4 siblings, 1 reply; 14+ messages in thread
From: Tony Lindgren @ 2017-05-04 14:31 UTC (permalink / raw)
To: Peter Ujfalusi
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
* Peter Ujfalusi <peter.ujfalusi@ti.com> [170503 04:00]:
> Hi,
>
> With port_window support implemented in DMAengine and the sDMA DMAengine driver,
> the tusb6010_omap driver can be converted away from the custom legacy omap-dma
> API to generic DMAengine.
>
> The first two patch is to prepare the tusb6010_omap driver for the conversion.
> The third one adds the needed entries for the dma_slave_map so we can request
> the DMA channels. This can be reverted when the stack is converted to DT.
>
> The last patch does the main work to move the driver to DMAengine API.
>
> I have tested the set on top of next-20170503 on Nokia n810 with nfsroot using
> CDC Ethernet (g_cdc) and copying files with scp to/form my host.
Thanks for doing this! For this series:
Acked-by: Tony Lindgren <tony@atomide.com>
> To force that the DMA is actually used I have:
> diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
> index 05aefcad40b5..a5fc2a6bdad3 100644
> --- a/drivers/usb/musb/tusb6010_omap.c
> +++ b/drivers/usb/musb/tusb6010_omap.c
> @@ -216,8 +216,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
> * use a timer for the callback, but it is unsafe as the XFR_SIZE
> * register is corrupt, and we won't know if the DMA worked.
> */
> - if (dma_addr & 0x2)
> - return false;
> +// if (dma_addr & 0x2)
> +// return false;
>
> /*
> * Because of HW issue #10, it seems like mixing sync DMA and async
>
> Since this condition will almost all the time was true - effectively disabling
> the DMA use.
Yeah this really should have the transfers aligned to 32-bit like
the production kernel did. For reference, the following should do
the trick but of course would have to be done conditionally.
Regards,
Tony
8< ----------------------
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -2153,6 +2153,7 @@ __acquires(musb->lock)
musb->g.a_alt_hnp_support = 0;
musb->g.a_hnp_support = 0;
musb->g.quirk_zlp_not_supp = 1;
+ musb->g.quirk_avoids_skb_reserve = 1;
/* Normal reset, as B-Device;
* or else after HNP, as A-Device
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API
2017-05-03 10:56 ` [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API Peter Ujfalusi
@ 2017-05-04 19:40 ` Tony Lindgren
2017-05-04 21:05 ` Tony Lindgren
0 siblings, 1 reply; 14+ messages in thread
From: Tony Lindgren @ 2017-05-04 19:40 UTC (permalink / raw)
To: Peter Ujfalusi
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
Hi,
* Peter Ujfalusi <peter.ujfalusi@ti.com> [170503 04:00]:
> With the port_window support in DMAengine and the sDMA driver we can
> convert the driver to DMAengine.
Actually looks like this patch still has some issues.. Pinging
the n8x0 with for example ping -s1 causes things to stop working.
This is when using only with the async gpmc access as the sync
gpmc access seems to have a regression not related to this series.
I'll try to track down that sync gpmc issue as that most likely
hints to something being wrong in the gpmc code in general.
Regards,
Tony
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API
2017-05-04 19:40 ` Tony Lindgren
@ 2017-05-04 21:05 ` Tony Lindgren
2017-05-05 13:37 ` Peter Ujfalusi
0 siblings, 1 reply; 14+ messages in thread
From: Tony Lindgren @ 2017-05-04 21:05 UTC (permalink / raw)
To: Peter Ujfalusi
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
* Tony Lindgren <tony@atomide.com> [170504 12:43]:
> Hi,
>
> * Peter Ujfalusi <peter.ujfalusi@ti.com> [170503 04:00]:
> > With the port_window support in DMAengine and the sDMA driver we can
> > convert the driver to DMAengine.
>
> Actually looks like this patch still has some issues.. Pinging
> the n8x0 with for example ping -s1 causes things to stop working.
Sorry it's actually ping -s2048, not -s1. Here's what happens
on n8x0 with first ping -s2048 with 4/4 applied:
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000010
g_ether gadget: invalid EEM CRC
g_ether gadget: invalid EEM CRC
musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x86803842 len: 512(512) packet_sz: 512(512)
musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from 0x02000620 to 0x86803842
musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
musb-hdrc musb-hdrc.1.auto: DMA remaining 448/512
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 000001c0
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x869fdc02 len: 512(512) packet_sz: 512(512)
musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from 0x02000620 to 0x869fdc02
musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
musb-hdrc musb-hdrc.1.auto: DMA remaining 448/512
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 000001c0
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x869fc642 len: 512(512) packet_sz: 512(512)
musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from 0x02000620 to 0x869fc642
musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
musb-hdrc musb-hdrc.1.auto: Corrupt rx XFR_SIZE: 0x7ffffec0
musb-hdrc musb-hdrc.1.auto: DMA remaining 0/512
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 7ffffec0
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000010
musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 7ffffcf0
It seems the hardware dmareq line is not triggering anything
above?
Also with just ping with no size specified, it seems every other
packet is missed or DMA interrupts are not properly triggering
as I'm getting these:
g_ether gadget: invalid EEM CRC
> This is when using only with the async gpmc access as the sync
> gpmc access seems to have a regression not related to this series.
> I'll try to track down that sync gpmc issue as that most likely
> hints to something being wrong in the gpmc code in general.
And this sync gpmc issue seems to be timing related. Setting
DEBUG in tusb6010_omap.c makes it happen easily while without
it it's much harder to trigger. So probably some kind of issue
with GPMC sync timings.
I also found one other issue that might need fixing depending
on the bootloader version, see below.
Regards,
Tony
8< -----------------
>From tony Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@atomide.com>
Date: Thu, 4 May 2017 09:35:32 -0700
Subject: [PATCH] ARM: dts: Fix n8x0 tusb6010 dmareq pin muxing
Looks like I forgot to add the device tree pin multiplexing for
tusb6010 on n8x0 when removing legacy platform code. Although the
bootloader sets the pins on n8x0, this may be needed on some n8x0
depending on the bootloader version.
Fixes: 602105ed740d ("ARM: OMAP2+: Remove legacy muxing
for usb-tusb6010.c")
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -103,3 +103,19 @@
};
};
};
+
+&omap2420_pmx {
+ pinctrl-0 = <&tusb6010_dmareq_pins>;
+ pinctrl-names = "default";
+
+ tusb6010_dmareq_pins: pinmux_tusb6010_dmareq_pins {
+ pinctrl-single,pins = <
+ OMAP2420_CORE_IOPAD(0x0071, PIN_INPUT | MUX_MODE2) /* gpmc_10.sys_ndmareq5 */
+ OMAP2420_CORE_IOPAD(0x0072, PIN_INPUT | MUX_MODE2) /* gpmc_9.sys_ndmareq4 */
+ OMAP2420_CORE_IOPAD(0x0073, PIN_INPUT | MUX_MODE2) /* gpmc_8.sys_ndmareq3 */
+ OMAP2420_CORE_IOPAD(0x0074, PIN_INPUT | MUX_MODE2) /* gpmc_7.sys_ndmareq1 */
+ OMAP2420_CORE_IOPAD(0x00e5, PIN_INPUT | MUX_MODE2) /* vlynq_clk.sys_ndmareq0 */
+ OMAP2420_CORE_IOPAD(0x00e6, PIN_INPUT | MUX_MODE2) /* vlynq_rx1.sys_ndmareq1 */
+ >;
+ };
+};
--
2.12.2
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine
2017-05-04 14:31 ` [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Tony Lindgren
@ 2017-05-05 7:28 ` Peter Ujfalusi
0 siblings, 0 replies; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-05 7:28 UTC (permalink / raw)
To: Tony Lindgren
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
On 2017-05-04 17:31, Tony Lindgren wrote:
> * Peter Ujfalusi <peter.ujfalusi@ti.com> [170503 04:00]:
>> Hi,
>>
>> With port_window support implemented in DMAengine and the sDMA DMAengine driver,
>> the tusb6010_omap driver can be converted away from the custom legacy omap-dma
>> API to generic DMAengine.
>>
>> The first two patch is to prepare the tusb6010_omap driver for the conversion.
>> The third one adds the needed entries for the dma_slave_map so we can request
>> the DMA channels. This can be reverted when the stack is converted to DT.
>>
>> The last patch does the main work to move the driver to DMAengine API.
>>
>> I have tested the set on top of next-20170503 on Nokia n810 with nfsroot using
>> CDC Ethernet (g_cdc) and copying files with scp to/form my host.
>
> Thanks for doing this! For this series:
>
> Acked-by: Tony Lindgren <tony@atomide.com>
>
>> To force that the DMA is actually used I have:
>> diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
>> index 05aefcad40b5..a5fc2a6bdad3 100644
>> --- a/drivers/usb/musb/tusb6010_omap.c
>> +++ b/drivers/usb/musb/tusb6010_omap.c
>> @@ -216,8 +216,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
>> * use a timer for the callback, but it is unsafe as the XFR_SIZE
>> * register is corrupt, and we won't know if the DMA worked.
>> */
>> - if (dma_addr & 0x2)
>> - return false;
>> +// if (dma_addr & 0x2)
>> +// return false;
>>
>> /*
>> * Because of HW issue #10, it seems like mixing sync DMA and async
>>
>> Since this condition will almost all the time was true - effectively disabling
>> the DMA use.
>
> Yeah this really should have the transfers aligned to 32-bit like
> the production kernel did. For reference, the following should do
> the trick but of course would have to be done conditionally.
>
> Regards,
>
> Tony
>
> 8< ----------------------
> diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
> --- a/drivers/usb/musb/musb_gadget.c
> +++ b/drivers/usb/musb/musb_gadget.c
> @@ -2153,6 +2153,7 @@ __acquires(musb->lock)
> musb->g.a_alt_hnp_support = 0;
> musb->g.a_hnp_support = 0;
> musb->g.quirk_zlp_not_supp = 1;
> + musb->g.quirk_avoids_skb_reserve = 1;
note for myself: this only works with g_ncm. I was using g_cdc, switched
to g_ether, then to g_ncm.
However... If I revert this series and add this line, the ethernet will
not work at all, I can not ping the n810 and it will not get the nfsroot
either (next-20170503).
only f_ncm.c does:
ncm->port.no_skb_reserve =
gadget_avoids_skb_reserve(cdev->gadget);
> /* Normal reset, as B-Device;
> * or else after HNP, as A-Device
>
- Péter
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API
2017-05-04 21:05 ` Tony Lindgren
@ 2017-05-05 13:37 ` Peter Ujfalusi
2017-05-05 15:17 ` Peter Ujfalusi
0 siblings, 1 reply; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-05 13:37 UTC (permalink / raw)
To: Tony Lindgren
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
Tony,
On 2017-05-05 00:05, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [170504 12:43]:
>> Hi,
>>
>> * Peter Ujfalusi <peter.ujfalusi@ti.com> [170503 04:00]:
>>> With the port_window support in DMAengine and the sDMA driver we can
>>> convert the driver to DMAengine.
>>
>> Actually looks like this patch still has some issues.. Pinging
>> the n8x0 with for example ping -s1 causes things to stop working.
>
> Sorry it's actually ping -s2048, not -s1. Here's what happens
> on n8x0 with first ping -s2048 with 4/4 applied:
>
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000010
> g_ether gadget: invalid EEM CRC
> g_ether gadget: invalid EEM CRC
> musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x86803842 len: 512(512) packet_sz: 512(512)
> musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from 0x02000620 to 0x86803842
> musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
> musb-hdrc musb-hdrc.1.auto: DMA remaining 448/512
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 000001c0
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
> musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x869fdc02 len: 512(512) packet_sz: 512(512)
> musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from 0x02000620 to 0x869fdc02
> musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
> musb-hdrc musb-hdrc.1.auto: DMA remaining 448/512
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 000001c0
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
> musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x869fc642 len: 512(512) packet_sz: 512(512)
> musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from 0x02000620 to 0x869fc642
> musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
> musb-hdrc musb-hdrc.1.auto: Corrupt rx XFR_SIZE: 0x7ffffec0
> musb-hdrc musb-hdrc.1.auto: DMA remaining 0/512
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 7ffffec0
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000010
> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 7ffffcf0
>
> It seems the hardware dmareq line is not triggering anything
> above?
>
> Also with just ping with no size specified, it seems every other
> packet is missed or DMA interrupts are not properly triggering
> as I'm getting these:
>
> g_ether gadget: invalid EEM CRC
>
>> This is when using only with the async gpmc access as the sync
>> gpmc access seems to have a regression not related to this series.
>> I'll try to track down that sync gpmc issue as that most likely
>> hints to something being wrong in the gpmc code in general.
>
> And this sync gpmc issue seems to be timing related. Setting
> DEBUG in tusb6010_omap.c makes it happen easily while without
> it it's much harder to trigger. So probably some kind of issue
> with GPMC sync timings.
Indeed there are some interesting things happening...
As I said, I was testing with g_cdc (CDC Composite (ECM + ACM)) and I
found it pretty stable with DMAengine. But short story long:
With the series applied and getting rid of the dma_addr & 0x2, plus
setting the set the quirk_avoids_skb_reserve flag:
g_cdc (ECM + ACM) boots to nfsroot most of the time, ping, scp works
g_ether (ECM) does not boot to nfsroot, ping does not work. However if I
disable the rx DMA with:
diff --git a/drivers/usb/musb/tusb6010_omap.c
b/drivers/usb/musb/tusb6010_omap.c
index 8b43c4b99f04..8e0a19b47132 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -512,6 +512,12 @@ tusb_omap_dma_allocate(struct dma_controller *c,
return NULL;
}
+ if (!tx) {
+ dev_err(musb->controller, "Not allowing RX DMA for ep%i %s\n",
+ chdat->epnum);
+ return NULL;
+ }
+
for (i = 0; i < MAX_DMAREQ; i++) {
struct dma_channel *ch = dma_channel_pool[i];
if (ch->status == MUSB_DMA_STATUS_UNKNOWN) {
nfsroot works, ping and scp also - TX is using DMA.
g_ncm (NCM): not booting to nfsroot, no ping, but if I disable the RX
DMA, then I have NULL pointer dereference :o
Something is wrong for sure.
But to see what I have been comparing to, I have reverted my series and
added the dma_addr & 2 and the quirk:
g_cdc (ECM + ACM): no nfsroot, no ping
g_ether (ECM): no nfsroot, no ping
g_ncm (NCM): no nfsroot, no ping, disabling RX DMA allow it to boot up,
but ping kills the USB
None of this is issue I think currently as the DMA is effectively
disabled for tusb by the dma_addr & 0x2 check, but it is somehow
bothersome...
I'll try to pin-point out what is going on.
As reference, my configs are:
https://github.com/omap-audio/linux-audio/blob/peter/linux-next-wip/arch/arm/configs/nokia_n810_cdc_defconfig
https://github.com/omap-audio/linux-audio/blob/peter/linux-next-wip/arch/arm/configs/nokia_n810_ether_defconfig
https://github.com/omap-audio/linux-audio/blob/peter/linux-next-wip/arch/arm/configs/nokia_n810_ncm_defconfig
- Péter
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API
2017-05-05 13:37 ` Peter Ujfalusi
@ 2017-05-05 15:17 ` Peter Ujfalusi
2017-05-05 22:55 ` Tony Lindgren
0 siblings, 1 reply; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-05 15:17 UTC (permalink / raw)
To: Tony Lindgren
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
On 2017-05-05 16:37, Peter Ujfalusi wrote:
> Tony,
>
> On 2017-05-05 00:05, Tony Lindgren wrote:
>> * Tony Lindgren <tony@atomide.com> [170504 12:43]:
>>> Hi,
>>>
>>> * Peter Ujfalusi <peter.ujfalusi@ti.com> [170503 04:00]:
>>>> With the port_window support in DMAengine and the sDMA driver we can
>>>> convert the driver to DMAengine.
>>>
>>> Actually looks like this patch still has some issues.. Pinging
>>> the n8x0 with for example ping -s1 causes things to stop working.
>>
>> Sorry it's actually ping -s2048, not -s1. Here's what happens
>> on n8x0 with first ping -s2048 with 4/4 applied:
>>
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000010
>> g_ether gadget: invalid EEM CRC
>> g_ether gadget: invalid EEM CRC
>> musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x86803842 len: 512(512)
>> packet_sz: 512(512)
>> musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from
>> 0x02000620 to 0x86803842
>> musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
>> musb-hdrc musb-hdrc.1.auto: DMA remaining 448/512
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 000001c0
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
>> musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x869fdc02 len: 512(512)
>> packet_sz: 512(512)
>> musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from
>> 0x02000620 to 0x869fdc02
>> musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
>> musb-hdrc musb-hdrc.1.auto: DMA remaining 448/512
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 000001c0
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
>> musb-hdrc musb-hdrc.1.auto: ep1 rx dma: 0x869fc642 len: 512(512)
>> packet_sz: 512(512)
>> musb-hdrc musb-hdrc.1.auto: ep1 rx using 16-bit async dma from
>> 0x02000620 to 0x869fc642
>> musb-hdrc musb-hdrc.1.auto: ep1 rx dma callback
>> musb-hdrc musb-hdrc.1.auto: Corrupt rx XFR_SIZE: 0x7ffffec0
>> musb-hdrc musb-hdrc.1.auto: DMA remaining 0/512
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 7ffffec0
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000008
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 00000010
>> musb-hdrc musb-hdrc.1.auto: Busy rx dma, not using: 7ffffcf0
>>
>> It seems the hardware dmareq line is not triggering anything
>> above?
>>
>> Also with just ping with no size specified, it seems every other
>> packet is missed or DMA interrupts are not properly triggering
>> as I'm getting these:
>>
>> g_ether gadget: invalid EEM CRC
>>
>>> This is when using only with the async gpmc access as the sync
>>> gpmc access seems to have a regression not related to this series.
>>> I'll try to track down that sync gpmc issue as that most likely
>>> hints to something being wrong in the gpmc code in general.
>>
>> And this sync gpmc issue seems to be timing related. Setting
>> DEBUG in tusb6010_omap.c makes it happen easily while without
>> it it's much harder to trigger. So probably some kind of issue
>> with GPMC sync timings.
>
> Indeed there are some interesting things happening...
> As I said, I was testing with g_cdc (CDC Composite (ECM + ACM)) and I
> found it pretty stable with DMAengine. But short story long:
>
> With the series applied and getting rid of the dma_addr & 0x2, plus
> setting the set the quirk_avoids_skb_reserve flag:
> g_cdc (ECM + ACM) boots to nfsroot most of the time, ping, scp works
> g_ether (ECM) does not boot to nfsroot, ping does not work. However if I
> disable the rx DMA with:
>
> diff --git a/drivers/usb/musb/tusb6010_omap.c
> b/drivers/usb/musb/tusb6010_omap.c
> index 8b43c4b99f04..8e0a19b47132 100644
> --- a/drivers/usb/musb/tusb6010_omap.c
> +++ b/drivers/usb/musb/tusb6010_omap.c
> @@ -512,6 +512,12 @@ tusb_omap_dma_allocate(struct dma_controller *c,
> return NULL;
> }
>
> + if (!tx) {
> + dev_err(musb->controller, "Not allowing RX DMA for ep%i %s\n",
> + chdat->epnum);
Remove the %s and s/chdat/hw_ep
and the kernel will not crash :( But still not booting with DMAengine
when RX DMA is disabled :o
> + return NULL;
> + }
> +
> for (i = 0; i < MAX_DMAREQ; i++) {
> struct dma_channel *ch = dma_channel_pool[i];
> if (ch->status == MUSB_DMA_STATUS_UNKNOWN) {
>
>
> nfsroot works, ping and scp also - TX is using DMA.
>
> g_ncm (NCM): not booting to nfsroot, no ping, but if I disable the RX
> DMA, then I have NULL pointer dereference :o
> Something is wrong for sure.
>
> But to see what I have been comparing to, I have reverted my series and
> added the dma_addr & 2 and the quirk:
>
> g_cdc (ECM + ACM): no nfsroot, no ping
> g_ether (ECM): no nfsroot, no ping
> g_ncm (NCM): no nfsroot, no ping, disabling RX DMA allow it to boot up,
> but ping kills the USB
>
> None of this is issue I think currently as the DMA is effectively
> disabled for tusb by the dma_addr & 0x2 check, but it is somehow
> bothersome...
>
> I'll try to pin-point out what is going on.
>
> As reference, my configs are:
> https://github.com/omap-audio/linux-audio/blob/peter/linux-next-wip/arch/arm/configs/nokia_n810_cdc_defconfig
>
>
> https://github.com/omap-audio/linux-audio/blob/peter/linux-next-wip/arch/arm/configs/nokia_n810_ether_defconfig
>
>
> https://github.com/omap-audio/linux-audio/blob/peter/linux-next-wip/arch/arm/configs/nokia_n810_ncm_defconfig
>
>
> - Péter
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
- Péter
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API
2017-05-05 15:17 ` Peter Ujfalusi
@ 2017-05-05 22:55 ` Tony Lindgren
2017-05-08 15:12 ` Peter Ujfalusi
0 siblings, 1 reply; 14+ messages in thread
From: Tony Lindgren @ 2017-05-05 22:55 UTC (permalink / raw)
To: Peter Ujfalusi
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
* Peter Ujfalusi <peter.ujfalusi@ti.com> [170505 08:20]:
> On 2017-05-05 16:37, Peter Ujfalusi wrote:
> > On 2017-05-05 00:05, Tony Lindgren wrote:
> > > And this sync gpmc issue seems to be timing related. Setting
> > > DEBUG in tusb6010_omap.c makes it happen easily while without
> > > it it's much harder to trigger. So probably some kind of issue
> > > with GPMC sync timings.
> >
> > Indeed there are some interesting things happening...
> > As I said, I was testing with g_cdc (CDC Composite (ECM + ACM)) and I
> > found it pretty stable with DMAengine. But short story long:
> >
> > With the series applied and getting rid of the dma_addr & 0x2, plus
> > setting the set the quirk_avoids_skb_reserve flag:
> > g_cdc (ECM + ACM) boots to nfsroot most of the time, ping, scp works
> > g_ether (ECM) does not boot to nfsroot, ping does not work. However if I
> > disable the rx DMA with:
> >
> > diff --git a/drivers/usb/musb/tusb6010_omap.c
> > b/drivers/usb/musb/tusb6010_omap.c
> > index 8b43c4b99f04..8e0a19b47132 100644
> > --- a/drivers/usb/musb/tusb6010_omap.c
> > +++ b/drivers/usb/musb/tusb6010_omap.c
> > @@ -512,6 +512,12 @@ tusb_omap_dma_allocate(struct dma_controller *c,
> > return NULL;
> > }
> >
> > + if (!tx) {
> > + dev_err(musb->controller, "Not allowing RX DMA for ep%i %s\n",
> > + chdat->epnum);
>
> Remove the %s and s/chdat/hw_ep
>
> and the kernel will not crash :( But still not booting with DMAengine when
> RX DMA is disabled :o
OK I verified that with the current mainline kernel using dma
and g_ether and your patches 1 to 3 I can run the variable size
ping test loop for few minutes before it just stops working and
I can see the legacy DMA interrupt increase depending on the
size of the packet. Then I checked with v4.1 kernel, and that
too seems to have the same issue.
I've also verified running the same variable size ping test with
your patch 4/4 makes things stop within just a few seconds. The
script I'm using for ping is below.
Anyways, what we really should ensure here is that the external
dmarequest line is properly triggering things with dmaengine :)
That's why I'm a bit worried your patch 4/4.
Oh and I also verified the GPMC timings we're using are the same
as in production n810 kernel so that should not be the issue.
And using the async access on n800 will not work as it will
produce corrupt transfer size register the report I posted
earlier is from n800 allowing it to use async transfers. On
n810 async transfers may work as I recall it having a newer
tusb6010 version.
Regards,
Tony
8< ----------------
#!/bin/bash
device=$1
size=$2
while [ 1 ]; do
#echo "Pinging with size $size"
if ! ping -w0 -c1 -s$size $device > /dev/null 2>&1; then
break;
fi
size=$(expr $size + 1)
if [ $size -gt 8192 ]; then
size=1
fi
done
echo "Test ran up to $size"
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API
2017-05-05 22:55 ` Tony Lindgren
@ 2017-05-08 15:12 ` Peter Ujfalusi
2017-05-08 15:29 ` Tony Lindgren
0 siblings, 1 reply; 14+ messages in thread
From: Peter Ujfalusi @ 2017-05-08 15:12 UTC (permalink / raw)
To: Tony Lindgren
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
Tony,
On 2017-05-06 01:55, Tony Lindgren wrote:
> OK I verified that with the current mainline kernel using dma
> and g_ether and your patches 1 to 3 I can run the variable size
> ping test loop for few minutes before it just stops working and
> I can see the legacy DMA interrupt increase depending on the
> size of the packet. Then I checked with v4.1 kernel, and that
> too seems to have the same issue.
>
> I've also verified running the same variable size ping test with
> your patch 4/4 makes things stop within just a few seconds. The
> script I'm using for ping is below.
>
> Anyways, what we really should ensure here is that the external
> dmarequest line is properly triggering things with dmaengine :)
> That's why I'm a bit worried your patch 4/4.
>
> Oh and I also verified the GPMC timings we're using are the same
> as in production n810 kernel so that should not be the issue.
>
> And using the async access on n800 will not work as it will
> produce corrupt transfer size register the report I posted
> earlier is from n800 allowing it to use async transfers. On
> n810 async transfers may work as I recall it having a newer
> tusb6010 version.
I think I have nailed the issue. I had a bug in the omap-dma
implementation of the port_window (sigh) and couple of issues in the
tusb6010/*_omap, not introduced by the series.
The ASYNC access is pretty unstable on n810 as well, I got corruption in
the XFR_SIZE.
I have been using the g_ncm gadget with
"musb->g.quirk_avoids_skb_reserve = 1;" to ensure that we are using SYNC
access.
I'm running your variable ping script for 2 hours now, it wrapped >130
times already, I also run a standalone ping with 2048 size in parallel,
the n810 is booted to nfsroot:
# cat /proc/interrupts | grep dma
29: 9483598 INTC 13 Edge omap-dma-engine
#
I need to clean up the code as I had debugs (disabled now) and stuff and
I want to try the tusb6010 changes w/o the DMAengine conversion.
>
> Regards,
>
> Tony
>
> 8< ----------------
> #!/bin/bash
>
> device=$1
> size=$2
+ wraps = 0
>
> while [ 1 ]; do
> #echo "Pinging with size $size"
> if ! ping -w0 -c1 -s$size $device > /dev/null 2>&1; then
> break;
> fi
> size=$(expr $size + 1)
>
> if [ $size -gt 8192 ]; then
+ wraps=$(expr $wraps + 1)
+ echo "wrapping ($wraps) at $size"
> size=1
> fi
> done
> echo "Test ran up to $size"
>
- Péter
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API
2017-05-08 15:12 ` Peter Ujfalusi
@ 2017-05-08 15:29 ` Tony Lindgren
0 siblings, 0 replies; 14+ messages in thread
From: Tony Lindgren @ 2017-05-08 15:29 UTC (permalink / raw)
To: Peter Ujfalusi
Cc: b-liu, gregkh, linux-usb, linux-omap, balbi, linux-kernel, Aaro Koskinen
* Peter Ujfalusi <peter.ujfalusi@ti.com> [170508 08:15]:
> Tony,
>
> On 2017-05-06 01:55, Tony Lindgren wrote:
> > OK I verified that with the current mainline kernel using dma
> > and g_ether and your patches 1 to 3 I can run the variable size
> > ping test loop for few minutes before it just stops working and
> > I can see the legacy DMA interrupt increase depending on the
> > size of the packet. Then I checked with v4.1 kernel, and that
> > too seems to have the same issue.
> >
> > I've also verified running the same variable size ping test with
> > your patch 4/4 makes things stop within just a few seconds. The
> > script I'm using for ping is below.
> >
> > Anyways, what we really should ensure here is that the external
> > dmarequest line is properly triggering things with dmaengine :)
> > That's why I'm a bit worried your patch 4/4.
> >
> > Oh and I also verified the GPMC timings we're using are the same
> > as in production n810 kernel so that should not be the issue.
> >
> > And using the async access on n800 will not work as it will
> > produce corrupt transfer size register the report I posted
> > earlier is from n800 allowing it to use async transfers. On
> > n810 async transfers may work as I recall it having a newer
> > tusb6010 version.
>
> I think I have nailed the issue. I had a bug in the omap-dma implementation
> of the port_window (sigh) and couple of issues in the tusb6010/*_omap, not
> introduced by the series.
> The ASYNC access is pretty unstable on n810 as well, I got corruption in the
> XFR_SIZE.
> I have been using the g_ncm gadget with "musb->g.quirk_avoids_skb_reserve =
> 1;" to ensure that we are using SYNC access.
>
> I'm running your variable ping script for 2 hours now, it wrapped >130 times
> already, I also run a standalone ping with 2048 size in parallel, the n810
> is booted to nfsroot:
>
> # cat /proc/interrupts | grep dma
> 29: 9483598 INTC 13 Edge omap-dma-engine
> #
>
> I need to clean up the code as I had debugs (disabled now) and stuff and I
> want to try the tusb6010 changes w/o the DMAengine conversion.
Hey that's good news!
Tony
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2017-05-08 15:29 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-03 10:56 [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 1/4] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 2/4] usb: musb: tusb6010_omap: Allocate DMA channels upfront Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 3/4] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines Peter Ujfalusi
2017-05-03 10:56 ` [PATCH 4/4] usb: musb: tusb6010_omap: Convert to DMAengine API Peter Ujfalusi
2017-05-04 19:40 ` Tony Lindgren
2017-05-04 21:05 ` Tony Lindgren
2017-05-05 13:37 ` Peter Ujfalusi
2017-05-05 15:17 ` Peter Ujfalusi
2017-05-05 22:55 ` Tony Lindgren
2017-05-08 15:12 ` Peter Ujfalusi
2017-05-08 15:29 ` Tony Lindgren
2017-05-04 14:31 ` [PATCH 0/4] usb: musb: tusb6010_omap: Convert to DMAengine Tony Lindgren
2017-05-05 7:28 ` Peter Ujfalusi
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).