diff options
Diffstat (limited to 'arch/arm/plat-s3c24xx/dma.c')
| -rw-r--r-- | arch/arm/plat-s3c24xx/dma.c | 151 | 
1 files changed, 56 insertions, 95 deletions
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 07326f63236..196b1912365 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -31,10 +31,10 @@  #include <asm/irq.h>  #include <mach/hardware.h>  #include <mach/dma.h> -  #include <mach/map.h> -#include <plat/dma.h> +#include <plat/dma-plat.h> +#include <plat/regs-dma.h>  /* io map for dma */  static void __iomem *dma_base; @@ -44,8 +44,6 @@ static int dma_channels;  static struct s3c24xx_dma_selection dma_sel; -/* dma channel state information */ -struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];  /* debugging functions */ @@ -135,21 +133,6 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)  #define dbg_showchan(chan) do { } while(0)  #endif /* CONFIG_S3C2410_DMA_DEBUG */ -static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX]; - -/* lookup_dma_channel - * - * change the dma channel number given into a real dma channel id -*/ - -static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel) -{ -	if (channel & DMACH_LOW_LEVEL) -		return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL]; -	else -		return dma_chan_map[channel]; -} -  /* s3c2410_dma_stats_timeout   *   * Update DMA stats from timeout info @@ -214,8 +197,6 @@ s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)  	return 0;  } - -  /* s3c2410_dma_loadbuffer   *   * load a buffer, and update the channel state @@ -453,7 +434,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)  int s3c2410_dma_enqueue(unsigned int channel, void *id,  			dma_addr_t data, int size)  { -	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); +	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);  	struct s3c2410_dma_buf *buf;  	unsigned long flags; @@ -804,7 +785,7 @@ EXPORT_SYMBOL(s3c2410_dma_request);  int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)  { -	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); +	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);  	unsigned long flags;  	if (chan == NULL) @@ -836,7 +817,7 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)  	chan->irq_claimed = 0;  	if (!(channel & DMACH_LOW_LEVEL)) -		dma_chan_map[channel] = NULL; +		s3c_dma_chan_map[channel] = NULL;  	local_irq_restore(flags); @@ -995,7 +976,7 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)  int  s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)  { -	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); +	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);  	if (chan == NULL)  		return -EINVAL; @@ -1038,14 +1019,13 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl);  /* s3c2410_dma_config   *   * xfersize:     size of unit in bytes (1,2,4) - * dcon:         base value of the DCONx register  */  int s3c2410_dma_config(unsigned int channel, -		       int xferunit, -		       int dcon) +		       int xferunit)  { -	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); +	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); +	unsigned int dcon;  	pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",  		 __func__, channel, xferunit, dcon); @@ -1055,10 +1035,33 @@ int s3c2410_dma_config(unsigned int channel,  	pr_debug("%s: Initial dcon is %08x\n", __func__, dcon); -	dcon |= chan->dcon & dma_sel.dcon_mask; +	dcon = chan->dcon & dma_sel.dcon_mask;  	pr_debug("%s: New dcon is %08x\n", __func__, dcon); +	switch (chan->req_ch) { +	case DMACH_I2S_IN: +	case DMACH_I2S_OUT: +	case DMACH_PCM_IN: +	case DMACH_PCM_OUT: +	case DMACH_MIC_IN: +	default: +		dcon |= S3C2410_DCON_HANDSHAKE; +		dcon |= S3C2410_DCON_SYNC_PCLK; +		break; + +	case DMACH_SDI: +		/* note, ensure if need HANDSHAKE or not */ +		dcon |= S3C2410_DCON_SYNC_PCLK; +		break; + +	case DMACH_XD0: +	case DMACH_XD1: +		dcon |= S3C2410_DCON_HANDSHAKE; +		dcon |= S3C2410_DCON_SYNC_HCLK; +		break; +	} +  	switch (xferunit) {  	case 1:  		dcon |= S3C2410_DCON_BYTE; @@ -1090,58 +1093,6 @@ int s3c2410_dma_config(unsigned int channel,  EXPORT_SYMBOL(s3c2410_dma_config); -int s3c2410_dma_setflags(unsigned int channel, unsigned int flags) -{ -	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - -	if (chan == NULL) -		return -EINVAL; - -	pr_debug("%s: chan=%p, flags=%08x\n", __func__, chan, flags); - -	chan->flags = flags; - -	return 0; -} - -EXPORT_SYMBOL(s3c2410_dma_setflags); - - -/* do we need to protect the settings of the fields from - * irq? -*/ - -int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) -{ -	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - -	if (chan == NULL) -		return -EINVAL; - -	pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn); - -	chan->op_fn = rtn; - -	return 0; -} - -EXPORT_SYMBOL(s3c2410_dma_set_opfn); - -int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) -{ -	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - -	if (chan == NULL) -		return -EINVAL; - -	pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn); - -	chan->callback_fn = rtn; - -	return 0; -} - -EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);  /* s3c2410_dma_devconfig   * @@ -1150,29 +1101,38 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);   * source:    S3C2410_DMASRC_HW: source is hardware   *            S3C2410_DMASRC_MEM: source is memory   * - * hwcfg:     the value for xxxSTCn register, - *            bit 0: 0=increment pointer, 1=leave pointer - *            bit 1: 0=source is AHB, 1=source is APB - *   * devaddr:   physical address of the source  */  int s3c2410_dma_devconfig(int channel,  			  enum s3c2410_dmasrc source, -			  int hwcfg,  			  unsigned long devaddr)  { -	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); +	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); +	unsigned int hwcfg;  	if (chan == NULL)  		return -EINVAL; -	pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", -		 __func__, (int)source, hwcfg, devaddr); +	pr_debug("%s: source=%d, devaddr=%08lx\n", +		 __func__, (int)source, devaddr);  	chan->source = source;  	chan->dev_addr = devaddr; -	chan->hw_cfg = hwcfg; + +	switch (chan->req_ch) { +	case DMACH_XD0: +	case DMACH_XD1: +		hwcfg = 0; /* AHB */ +		break; + +	default: +		hwcfg = S3C2410_DISRCC_APB; +	} + +	/* always assume our peripheral desintation is a fixed +	 * address in memory. */ +	 hwcfg |= S3C2410_DISRCC_INC;  	switch (source) {  	case S3C2410_DMASRC_HW: @@ -1219,7 +1179,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig);  int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst)  { - 	struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); +	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);  	if (chan == NULL)  		return -EINVAL; @@ -1278,8 +1238,8 @@ static int s3c2410_dma_resume(struct sys_device *dev)  	printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); -	s3c2410_dma_config(no, cp->xfer_unit, cp->dcon); -	s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr); +	s3c2410_dma_config(no, cp->xfer_unit); +	s3c2410_dma_devconfig(no, cp->source, cp->dev_addr);  	/* re-select the dma source for this channel */ @@ -1476,7 +1436,8 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)   found:  	dmach = &s3c2410_chans[ch];  	dmach->map = ch_map; -	dma_chan_map[channel] = dmach; +	dmach->req_ch = channel; +	s3c_dma_chan_map[channel] = dmach;  	/* select the channel */  |