Commit 963accbc authored by Manuel Lauss's avatar Manuel Lauss Committed by Ralf Baechle

MIPS: Alchemy: change dbdma to accept physical memory addresses

DMA can only be done from physical addresses; move the "virt_to_phys"
source/destination buffer address translation from the dbdma queueing
functions (since the hardware can only DMA to/from physical addresses)
to their respective users.
Signed-off-by: default avatarManuel Lauss <manuel.lauss@gmail.com>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent ea071cc7
...@@ -571,7 +571,7 @@ EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc); ...@@ -571,7 +571,7 @@ EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
* This updates the source pointer and byte count. Normally used * This updates the source pointer and byte count. Normally used
* for memory to fifo transfers. * for memory to fifo transfers.
*/ */
u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
{ {
chan_tab_t *ctp; chan_tab_t *ctp;
au1x_ddma_desc_t *dp; au1x_ddma_desc_t *dp;
...@@ -597,7 +597,7 @@ u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) ...@@ -597,7 +597,7 @@ u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
return 0; return 0;
/* Load up buffer address and byte count. */ /* Load up buffer address and byte count. */
dp->dscr_source0 = virt_to_phys(buf); dp->dscr_source0 = buf & ~0UL;
dp->dscr_cmd1 = nbytes; dp->dscr_cmd1 = nbytes;
/* Check flags */ /* Check flags */
if (flags & DDMA_FLAGS_IE) if (flags & DDMA_FLAGS_IE)
...@@ -630,7 +630,7 @@ EXPORT_SYMBOL(au1xxx_dbdma_put_source); ...@@ -630,7 +630,7 @@ EXPORT_SYMBOL(au1xxx_dbdma_put_source);
* This updates the destination pointer and byte count. Normally used * This updates the destination pointer and byte count. Normally used
* to place an empty buffer into the ring for fifo to memory transfers. * to place an empty buffer into the ring for fifo to memory transfers.
*/ */
u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
{ {
chan_tab_t *ctp; chan_tab_t *ctp;
au1x_ddma_desc_t *dp; au1x_ddma_desc_t *dp;
...@@ -660,7 +660,7 @@ u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) ...@@ -660,7 +660,7 @@ u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
if (flags & DDMA_FLAGS_NOIE) if (flags & DDMA_FLAGS_NOIE)
dp->dscr_cmd0 &= ~DSCR_CMD0_IE; dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
dp->dscr_dest0 = virt_to_phys(buf); dp->dscr_dest0 = buf & ~0UL;
dp->dscr_cmd1 = nbytes; dp->dscr_cmd1 = nbytes;
#if 0 #if 0
printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
......
...@@ -339,8 +339,8 @@ u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits); ...@@ -339,8 +339,8 @@ u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries); u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
/* Put buffers on source/destination descriptors. */ /* Put buffers on source/destination descriptors. */
u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags); u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags); u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
/* Get a buffer from the destination descriptor. */ /* Get a buffer from the destination descriptor. */
u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes); u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);
......
...@@ -56,7 +56,7 @@ static inline void auide_insw(unsigned long port, void *addr, u32 count) ...@@ -56,7 +56,7 @@ static inline void auide_insw(unsigned long port, void *addr, u32 count)
chan_tab_t *ctp; chan_tab_t *ctp;
au1x_ddma_desc_t *dp; au1x_ddma_desc_t *dp;
if (!au1xxx_dbdma_put_dest(ahwif->rx_chan, (void*)addr, if (!au1xxx_dbdma_put_dest(ahwif->rx_chan, virt_to_phys(addr),
count << 1, DDMA_FLAGS_NOIE)) { count << 1, DDMA_FLAGS_NOIE)) {
printk(KERN_ERR "%s failed %d\n", __func__, __LINE__); printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
return; return;
...@@ -74,7 +74,7 @@ static inline void auide_outsw(unsigned long port, void *addr, u32 count) ...@@ -74,7 +74,7 @@ static inline void auide_outsw(unsigned long port, void *addr, u32 count)
chan_tab_t *ctp; chan_tab_t *ctp;
au1x_ddma_desc_t *dp; au1x_ddma_desc_t *dp;
if (!au1xxx_dbdma_put_source(ahwif->tx_chan, (void*)addr, if (!au1xxx_dbdma_put_source(ahwif->tx_chan, virt_to_phys(addr),
count << 1, DDMA_FLAGS_NOIE)) { count << 1, DDMA_FLAGS_NOIE)) {
printk(KERN_ERR "%s failed %d\n", __func__, __LINE__); printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
return; return;
...@@ -247,13 +247,13 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) ...@@ -247,13 +247,13 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
if (iswrite) { if (iswrite) {
if (!au1xxx_dbdma_put_source(ahwif->tx_chan, if (!au1xxx_dbdma_put_source(ahwif->tx_chan,
(void *)sg_virt(sg), tc, flags)) { sg_phys(sg), tc, flags)) {
printk(KERN_ERR "%s failed %d\n", printk(KERN_ERR "%s failed %d\n",
__func__, __LINE__); __func__, __LINE__);
} }
} else { } else {
if (!au1xxx_dbdma_put_dest(ahwif->rx_chan, if (!au1xxx_dbdma_put_dest(ahwif->rx_chan,
(void *)sg_virt(sg), tc, flags)) { sg_phys(sg), tc, flags)) {
printk(KERN_ERR "%s failed %d\n", printk(KERN_ERR "%s failed %d\n",
__func__, __LINE__); __func__, __LINE__);
} }
......
...@@ -651,10 +651,10 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host, ...@@ -651,10 +651,10 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host,
if (host->flags & HOST_F_XMIT) { if (host->flags & HOST_F_XMIT) {
ret = au1xxx_dbdma_put_source(channel, ret = au1xxx_dbdma_put_source(channel,
(void *)sg_virt(sg), len, flags); sg_phys(sg), len, flags);
} else { } else {
ret = au1xxx_dbdma_put_dest(channel, ret = au1xxx_dbdma_put_dest(channel,
(void *)sg_virt(sg), len, flags); sg_phys(sg), len, flags);
} }
if (!ret) if (!ret)
......
...@@ -412,12 +412,12 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) ...@@ -412,12 +412,12 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
} }
/* put buffers on the ring */ /* put buffers on the ring */
res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, hw->rx, res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, virt_to_phys(hw->rx),
t->len, DDMA_FLAGS_IE); t->len, DDMA_FLAGS_IE);
if (!res) if (!res)
dev_err(hw->dev, "rx dma put dest error\n"); dev_err(hw->dev, "rx dma put dest error\n");
res = au1xxx_dbdma_put_source(hw->dma_tx_ch, (void *)hw->tx, res = au1xxx_dbdma_put_source(hw->dma_tx_ch, virt_to_phys(hw->tx),
t->len, DDMA_FLAGS_IE); t->len, DDMA_FLAGS_IE);
if (!res) if (!res)
dev_err(hw->dev, "tx dma put source error\n"); dev_err(hw->dev, "tx dma put source error\n");
......
...@@ -614,7 +614,7 @@ start_adc(struct au1550_state *s) ...@@ -614,7 +614,7 @@ start_adc(struct au1550_state *s)
/* Put two buffers on the ring to get things started. /* Put two buffers on the ring to get things started.
*/ */
for (i=0; i<2; i++) { for (i=0; i<2; i++) {
au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, au1xxx_dbdma_put_dest(db->dmanr, virt_to_phys(db->nextIn),
db->dma_fragsize, DDMA_FLAGS_IE); db->dma_fragsize, DDMA_FLAGS_IE);
db->nextIn += db->dma_fragsize; db->nextIn += db->dma_fragsize;
...@@ -733,8 +733,9 @@ static void dac_dma_interrupt(int irq, void *dev_id) ...@@ -733,8 +733,9 @@ static void dac_dma_interrupt(int irq, void *dev_id)
db->dma_qcount--; db->dma_qcount--;
if (db->count >= db->fragsize) { if (db->count >= db->fragsize) {
if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, if (au1xxx_dbdma_put_source(db->dmanr,
db->fragsize, DDMA_FLAGS_IE) == 0) { virt_to_phys(db->nextOut), db->fragsize,
DDMA_FLAGS_IE) == 0) {
err("qcount < 2 and no ring room!"); err("qcount < 2 and no ring room!");
} }
db->nextOut += db->fragsize; db->nextOut += db->fragsize;
...@@ -778,7 +779,7 @@ static void adc_dma_interrupt(int irq, void *dev_id) ...@@ -778,7 +779,7 @@ static void adc_dma_interrupt(int irq, void *dev_id)
/* Put a new empty buffer on the destination DMA. /* Put a new empty buffer on the destination DMA.
*/ */
au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, au1xxx_dbdma_put_dest(dp->dmanr, virt_to_phys(dp->nextIn),
dp->dma_fragsize, DDMA_FLAGS_IE); dp->dma_fragsize, DDMA_FLAGS_IE);
dp->nextIn += dp->dma_fragsize; dp->nextIn += dp->dma_fragsize;
...@@ -1180,7 +1181,8 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) ...@@ -1180,7 +1181,8 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
*/ */
while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) { while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
if (au1xxx_dbdma_put_source(db->dmanr, if (au1xxx_dbdma_put_source(db->dmanr,
db->nextOut, db->fragsize, DDMA_FLAGS_IE) == 0) { virt_to_phys(db->nextOut), db->fragsize,
DDMA_FLAGS_IE) == 0) {
err("qcount < 2 and no ring room!"); err("qcount < 2 and no ring room!");
} }
db->nextOut += db->fragsize; db->nextOut += db->fragsize;
......
...@@ -51,8 +51,8 @@ struct au1xpsc_audio_dmadata { ...@@ -51,8 +51,8 @@ struct au1xpsc_audio_dmadata {
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
unsigned long curr_period; /* current segment DDMA is working on */ unsigned long curr_period; /* current segment DDMA is working on */
unsigned long q_period; /* queue period(s) */ unsigned long q_period; /* queue period(s) */
unsigned long dma_area; /* address of queued DMA area */ dma_addr_t dma_area; /* address of queued DMA area */
unsigned long dma_area_s; /* start address of DMA area */ dma_addr_t dma_area_s; /* start address of DMA area */
unsigned long pos; /* current byte position being played */ unsigned long pos; /* current byte position being played */
unsigned long periods; /* number of SG segments in total */ unsigned long periods; /* number of SG segments in total */
unsigned long period_bytes; /* size in bytes of one SG segment */ unsigned long period_bytes; /* size in bytes of one SG segment */
...@@ -94,8 +94,7 @@ static const struct snd_pcm_hardware au1xpsc_pcm_hardware = { ...@@ -94,8 +94,7 @@ static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd) static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
{ {
au1xxx_dbdma_put_source(cd->ddma_chan, au1xxx_dbdma_put_source(cd->ddma_chan, cd->dma_area,
(void *)phys_to_virt(cd->dma_area),
cd->period_bytes, DDMA_FLAGS_IE); cd->period_bytes, DDMA_FLAGS_IE);
/* update next-to-queue period */ /* update next-to-queue period */
...@@ -109,8 +108,7 @@ static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd) ...@@ -109,8 +108,7 @@ static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd)
static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd) static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd)
{ {
au1xxx_dbdma_put_dest(cd->ddma_chan, au1xxx_dbdma_put_dest(cd->ddma_chan, cd->dma_area,
(void *)phys_to_virt(cd->dma_area),
cd->period_bytes, DDMA_FLAGS_IE); cd->period_bytes, DDMA_FLAGS_IE);
/* update next-to-queue period */ /* update next-to-queue period */
...@@ -233,7 +231,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -233,7 +231,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream,
pcd->substream = substream; pcd->substream = substream;
pcd->period_bytes = params_period_bytes(params); pcd->period_bytes = params_period_bytes(params);
pcd->periods = params_periods(params); pcd->periods = params_periods(params);
pcd->dma_area_s = pcd->dma_area = (unsigned long)runtime->dma_addr; pcd->dma_area_s = pcd->dma_area = runtime->dma_addr;
pcd->q_period = 0; pcd->q_period = 0;
pcd->curr_period = 0; pcd->curr_period = 0;
pcd->pos = 0; pcd->pos = 0;
......
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