Commit 13f21fc8 authored by Tony Lindgren's avatar Tony Lindgren

musb_hdrc: Allow tusb3.0 and greater to use multichannel DMA

Allow tusb3.0 and greater to use multichannel DMA
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 51112776
...@@ -34,7 +34,7 @@ static void tusb_source_power(struct musb *musb, int is_on); ...@@ -34,7 +34,7 @@ static void tusb_source_power(struct musb *musb, int is_on);
* Checks the revision. We need to use the DMA register as 3.0 does not * Checks the revision. We need to use the DMA register as 3.0 does not
* have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV. * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
*/ */
static u8 tusb_get_revision(struct musb *musb) u8 tusb_get_revision(struct musb *musb)
{ {
void __iomem *tbase = musb->ctrl_base; void __iomem *tbase = musb->ctrl_base;
u32 die_id; u32 die_id;
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#ifndef __TUSB6010_H__ #ifndef __TUSB6010_H__
#define __TUSB6010_H__ #define __TUSB6010_H__
extern u8 tusb_get_revision(struct musb *musb);
#ifdef CONFIG_USB_TUSB6010 #ifdef CONFIG_USB_TUSB6010
#define musb_in_tusb() 1 #define musb_in_tusb() 1
#else #else
......
...@@ -20,18 +20,6 @@ ...@@ -20,18 +20,6 @@
#include "musb_core.h" #include "musb_core.h"
/*
* REVISIT: With TUSB2.0 only one dmareq line can be used at a time.
* This should get fixed in hardware at some point.
*/
#define BROKEN_DMAREQ
#ifdef BROKEN_DMAREQ
#define dmareq_works() 0
#else
#define dmareq_works() 1
#endif
#define to_chdat(c) (struct tusb_omap_dma_ch *)(c)->private_data #define to_chdat(c) (struct tusb_omap_dma_ch *)(c)->private_data
#define MAX_DMAREQ 5 /* REVISIT: Really 6, but req5 not OK */ #define MAX_DMAREQ 5 /* REVISIT: Really 6, but req5 not OK */
...@@ -67,6 +55,7 @@ struct tusb_omap_dma { ...@@ -67,6 +55,7 @@ struct tusb_omap_dma {
int ch; int ch;
s8 dmareq; s8 dmareq;
s8 sync_dev; s8 sync_dev;
unsigned multichannel:1;
}; };
static int tusb_omap_dma_start(struct dma_controller *c) static int tusb_omap_dma_start(struct dma_controller *c)
...@@ -91,8 +80,6 @@ static int tusb_omap_dma_stop(struct dma_controller *c) ...@@ -91,8 +80,6 @@ static int tusb_omap_dma_stop(struct dma_controller *c)
return 0; return 0;
} }
#ifdef BROKEN_DMAREQ
/* /*
* Allocate dmareq0 to the current channel unless it's already taken * Allocate dmareq0 to the current channel unless it's already taken
*/ */
...@@ -128,11 +115,6 @@ static inline void tusb_omap_free_shared_dmareq(struct tusb_omap_dma_ch *chdat) ...@@ -128,11 +115,6 @@ static inline void tusb_omap_free_shared_dmareq(struct tusb_omap_dma_ch *chdat)
musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, 0); musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, 0);
} }
#else
#define tusb_omap_use_shared_dmareq(x, y) do {} while (0)
#define tusb_omap_free_shared_dmareq(x, y) do {} while (0)
#endif
/* /*
* See also musb_dma_completion in plat_uds.c and musb_g_[tx|rx]() in * See also musb_dma_completion in plat_uds.c and musb_g_[tx|rx]() in
* musb_gadget.c. * musb_gadget.c.
...@@ -151,7 +133,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) ...@@ -151,7 +133,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
spin_lock_irqsave(&musb->lock, flags); spin_lock_irqsave(&musb->lock, flags);
if (dmareq_works()) if (tusb_dma->multichannel)
ch = chdat->ch; ch = chdat->ch;
else else
ch = tusb_dma->ch; ch = tusb_dma->ch;
...@@ -201,7 +183,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) ...@@ -201,7 +183,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
channel->actual_len += pio; channel->actual_len += pio;
} }
if (!dmareq_works()) if (!tusb_dma->multichannel)
tusb_omap_free_shared_dmareq(chdat); tusb_omap_free_shared_dmareq(chdat);
channel->status = MUSB_DMA_STATUS_FREE; channel->status = MUSB_DMA_STATUS_FREE;
...@@ -283,7 +265,6 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, ...@@ -283,7 +265,6 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
return false; return false;
} }
chdat->transfer_len = len & ~0x1f; chdat->transfer_len = len & ~0x1f;
if (len < packet_sz) if (len < packet_sz)
...@@ -291,7 +272,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, ...@@ -291,7 +272,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
else else
chdat->transfer_packet_sz = packet_sz; chdat->transfer_packet_sz = packet_sz;
if (dmareq_works()) { if (tusb_dma->multichannel) {
ch = chdat->ch; ch = chdat->ch;
dmareq = chdat->dmareq; dmareq = chdat->dmareq;
sync_dev = chdat->sync_dev; sync_dev = chdat->sync_dev;
...@@ -441,7 +422,7 @@ static int tusb_omap_dma_abort(struct dma_channel *channel) ...@@ -441,7 +422,7 @@ static int tusb_omap_dma_abort(struct dma_channel *channel)
struct tusb_omap_dma_ch *chdat = to_chdat(channel); struct tusb_omap_dma_ch *chdat = to_chdat(channel);
struct tusb_omap_dma *tusb_dma = chdat->tusb_dma; struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
if (!dmareq_works()) { if (!tusb_dma->multichannel) {
if (tusb_dma->ch >= 0) { if (tusb_dma->ch >= 0) {
omap_stop_dma(tusb_dma->ch); omap_stop_dma(tusb_dma->ch);
omap_free_dma(tusb_dma->ch); omap_free_dma(tusb_dma->ch);
...@@ -574,7 +555,7 @@ tusb_omap_dma_allocate(struct dma_controller *c, ...@@ -574,7 +555,7 @@ tusb_omap_dma_allocate(struct dma_controller *c,
channel->desired_mode = 0; channel->desired_mode = 0;
channel->actual_len = 0; channel->actual_len = 0;
if (dmareq_works()) { if (tusb_dma->multichannel) {
ret = tusb_omap_dma_allocate_dmareq(chdat); ret = tusb_omap_dma_allocate_dmareq(chdat);
if (ret != 0) if (ret != 0)
goto free_dmareq; goto free_dmareq;
...@@ -668,7 +649,7 @@ void dma_controller_destroy(struct dma_controller *c) ...@@ -668,7 +649,7 @@ void dma_controller_destroy(struct dma_controller *c)
} }
} }
if (!dmareq_works() && tusb_dma && tusb_dma->ch >= 0) if (!tusb_dma->multichannel && tusb_dma && tusb_dma->ch >= 0)
omap_free_dma(tusb_dma->ch); omap_free_dma(tusb_dma->ch);
kfree(tusb_dma); kfree(tusb_dma);
...@@ -710,6 +691,9 @@ dma_controller_create(struct musb *musb, void __iomem *base) ...@@ -710,6 +691,9 @@ dma_controller_create(struct musb *musb, void __iomem *base)
tusb_dma->controller.channel_abort = tusb_omap_dma_abort; tusb_dma->controller.channel_abort = tusb_omap_dma_abort;
tusb_dma->controller.private_data = tusb_dma; tusb_dma->controller.private_data = tusb_dma;
if (tusb_get_revision(musb) >= TUSB_REV_30)
tusb_dma->multichannel = 1;
for (i = 0; i < MAX_DMAREQ; i++) { for (i = 0; i < MAX_DMAREQ; i++) {
struct dma_channel *ch; struct dma_channel *ch;
struct tusb_omap_dma_ch *chdat; struct tusb_omap_dma_ch *chdat;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment