Example #1
0
static void 
socle_hdma_set_count(struct socle_dma *dma)
{
	int burst_val;
	int data_size_val=0;
	u32 inter_ch = *((u32 *)dma->private_data);

	switch(dma->burst_type) {
	case SOCLE_DMA_BURST_SINGLE:
		burst_val = 1;
		break;
	case SOCLE_DMA_BURST_INCR4:
		burst_val = 4;
		break;
	case SOCLE_DMA_BURST_INCR8:
		burst_val = 8;
		break;
	case SOCLE_DMA_BURST_INCR16:
		burst_val = 16;
		break;
	default:
		printk(KERN_ERR "SQ HDMA: burst type (%d) is unknown\n", dma->burst_type);
		return;
	}
	switch (dma->data_size) {
	case SOCLE_DMA_DATA_BYTE:
		data_size_val = 1;
		break;
	case SOCLE_DMA_DATA_HALFWORD:
		data_size_val = 2;
		break;
	case SOCLE_DMA_DATA_WORD:
		data_size_val = 4;
		break;
	}
	if (0 == (dma->tx_cnt % (burst_val * data_size_val))) {
		if (0 == inter_ch) 
			socle_hdma_write(SOCLE_HDMA_ICNT0, (dma->tx_cnt/data_size_val)-1, IO_ADDRESS(dma->res->start));
		else if(1 == inter_ch)
			socle_hdma_write(SOCLE_HDMA_ICNT1, (dma->tx_cnt/data_size_val)-1, IO_ADDRESS(dma->res->start));
		else if(2 == inter_ch)
			socle_hdma_write(SOCLE_HDMA_ICNT2, (dma->tx_cnt/data_size_val)-1, IO_ADDRESS(dma->res->start));
		else 
			socle_hdma_write(SOCLE_HDMA_ICNT3, (dma->tx_cnt/data_size_val)-1, IO_ADDRESS(dma->res->start));
	} else
		printk(KERN_ERR "SQ HDMA: %d is not a multiple of %d (%d * %d)\n", dma->tx_cnt, (burst_val*data_size_val), burst_val,
		       data_size_val);
}
Example #2
0
static void
socle_hdma_isr_3(void *_dma)
{
	u32 int_stat;
	struct socle_dma *dma = _dma;

	int_stat = socle_hdma_read(SOCLE_HDMA_ISR23, dma->base_addr);
	int_stat &= SOCLE_HDMA_CH3_INT_ACT;
		
	/* Clear the interrupt flag */
	socle_hdma_write(SOCLE_HDMA_ISR23,
			    socle_hdma_read(SOCLE_HDMA_ISR23, dma->base_addr) & (~int_stat),
			    dma->base_addr);
			    
	if (int_stat & SOCLE_HDMA_CH3_INT_ACT){
		if (dma->notifier->complete)
			dma->notifier->complete(dma->notifier->data);
	}
}
Example #3
0
static void 
socle_hdma_disable(u32 ch, struct socle_dma *dma)
{
	u32 inter_ch = *((u32 *)dma->private_data);
	u32 tmp;

		
	
	switch (inter_ch) {
	case 0:
			/* Clear channel 0 interrupt flag */
		tmp = SOCLE_HDMA_CH0_INT_ACT;
		socle_hdma_write(SOCLE_HDMA_ISR01,
				    socle_hdma_read(SOCLE_HDMA_ISR01, IO_ADDRESS(dma->res->start))&(~tmp),
				    IO_ADDRESS(dma->res->start));
			/* Clear channel 0 configuration register */
		socle_hdma_write(SOCLE_HDMA_CON0, 0, IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_ISRC0, 0 , IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_IDST0, 0 , IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_ICNT0, 0, IO_ADDRESS(dma->res->start));		
		break;
	case 1:
			/* Clear channel 0 interrupt flag */
		tmp = SOCLE_HDMA_CH1_INT_ACT;
		socle_hdma_write(SOCLE_HDMA_ISR01,
				    socle_hdma_read(SOCLE_HDMA_ISR01, IO_ADDRESS(dma->res->start))&(~tmp),
				    IO_ADDRESS(dma->res->start));
			/* Clear channel 1 configuration register */
		socle_hdma_write(SOCLE_HDMA_CON1, 0, IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_ISRC1, 0, IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_IDST1, 0, IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_ICNT1, 0, IO_ADDRESS(dma->res->start));		
		break;
	case 2:
			/* Clear channel 0 interrupt flag */
		tmp = SOCLE_HDMA_CH2_INT_ACT;
		socle_hdma_write(SOCLE_HDMA_ISR23,
				    socle_hdma_read(SOCLE_HDMA_ISR23, IO_ADDRESS(dma->res->start))&(~tmp),
				    IO_ADDRESS(dma->res->start));
		/* Clear channel 2 configuration register */
		socle_hdma_write(SOCLE_HDMA_CON2, 0, IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_ISRC2, 0 , IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_IDST2, 0 , IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_ICNT2, 0, IO_ADDRESS(dma->res->start));		
		break;
	case 3:
			/* Clear channel 0 interrupt flag */
		tmp = SOCLE_HDMA_CH3_INT_ACT;
		socle_hdma_write(SOCLE_HDMA_ISR23,
				    socle_hdma_read(SOCLE_HDMA_ISR23, IO_ADDRESS(dma->res->start))&(~tmp),
				    IO_ADDRESS(dma->res->start));
		/* Clear channel 3 configuration register */
		socle_hdma_write(SOCLE_HDMA_CON3, 0, IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_ISRC3, 0, IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_IDST3, 0, IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_ICNT3, 0, IO_ADDRESS(dma->res->start));		
		break;
	default:
		printk(KERN_ERR "HDMA: unknown channel number %d\n", ch);
		return;
	}
}
Example #4
0
static void 
socle_hdma_enable(u32 ch, struct socle_dma *dma)
{
	u32 inter_ch = *((u32 *)dma->private_data);
	u32 conf = SOCLE_HDMA_AUTORELOAD_DIS |
		SOCLE_HDMA_CH_EN |
		SOCLE_HDMA_INT_MODE_INT |
		SOCLE_HDMA_FLY_DIS |
		SOCLE_HDMA_TX_MODE_SINGLE |
		SOCLE_HDMA_HDREQ0(0) |
		SOCLE_HDMA_DIR_SRC_INC |
		SOCLE_HDMA_DIR_DST_INC |
		SOCLE_HDMA_DATA_SIZE_BYTE |
		SOCLE_HDMA_SWDMA_OP_NO |
		SOCLE_HDMA_HWDMA_TRIGGER_DIS;

	switch (dma->burst_type) {
	case SOCLE_DMA_BURST_SINGLE:
		conf |= SOCLE_HDMA_TX_MODE_SINGLE;
		break;
	case SOCLE_DMA_BURST_INCR4:
		conf |= SOCLE_HDMA_TX_MODE_INCR4;
		break;
	case SOCLE_DMA_BURST_INCR8:
		conf |= SOCLE_HDMA_TX_MODE_INCR8;
		break;
	case SOCLE_DMA_BURST_INCR16:
		conf |= SOCLE_HDMA_TX_MODE_INCR16;
		break;
	}
	conf |= SOCLE_HDMA_HDREQ0(dma->ext_hdreq);
	if (SOCLE_DMA_DIR_FIXED == dma->src_dir)
		conf |= SOCLE_HDMA_DIR_SRC_FIXED;
	if (SOCLE_DMA_DIR_FIXED == dma->dst_dir)
		conf |= SOCLE_HDMA_DIR_DST_FIXED;		
	if (SOCLE_DMA_FLY_READ == dma->fly_op)
		conf |= SOCLE_HDMA_FLY_READ;		
	if (SOCLE_DMA_FLY_WRITE == dma->fly_op)
		conf |= SOCLE_HDMA_FLY_WRITE;
	switch (dma->data_size) {
	case SOCLE_DMA_DATA_BYTE:
		conf |= SOCLE_HDMA_DATA_SIZE_BYTE;
		break;
	case SOCLE_DMA_DATA_HALFWORD:
		conf |= SOCLE_HDMA_DATA_SIZE_HALFWORD;
		break;
	case SOCLE_DMA_DATA_WORD:
		conf |= SOCLE_HDMA_DATA_SIZE_WORD;
		break;
	}	
	if (SOCLE_DMA_MODE_HW == dma->mode)
		conf |= SOCLE_HDMA_HWDMA_TRIGGER_EN;
	else
		conf |= SOCLE_HDMA_SWDMA_OP_START;
	switch (inter_ch) {
	case 0:    
		socle_hdma_write(SOCLE_HDMA_ISRC0, dma->src_addr , IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_IDST0, dma->dst_addr , IO_ADDRESS(dma->res->start));
		socle_hdma_set_count(dma);
		socle_hdma_write(SOCLE_HDMA_CON0, conf, IO_ADDRESS(dma->res->start));
		break;
	case 1:
		socle_hdma_write(SOCLE_HDMA_ISRC1, dma->src_addr , IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_IDST1, dma->dst_addr , IO_ADDRESS(dma->res->start));		
		socle_hdma_set_count(dma);
		socle_hdma_write(SOCLE_HDMA_CON1, conf, IO_ADDRESS(dma->res->start));
		break;
	case 2:    
		socle_hdma_write(SOCLE_HDMA_ISRC2, dma->src_addr , IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_IDST2, dma->dst_addr , IO_ADDRESS(dma->res->start));	
		socle_hdma_set_count(dma);
		socle_hdma_write(SOCLE_HDMA_CON2, conf, IO_ADDRESS(dma->res->start));
		break;
	case 3:
		socle_hdma_write(SOCLE_HDMA_ISRC3, dma->src_addr , IO_ADDRESS(dma->res->start));
		socle_hdma_write(SOCLE_HDMA_IDST3, dma->dst_addr , IO_ADDRESS(dma->res->start));	
		socle_hdma_set_count(dma);
		socle_hdma_write(SOCLE_HDMA_CON3, conf, IO_ADDRESS(dma->res->start));
		break;
	default:
		printk(KERN_ERR "HDMA: unknown channel number %d\n", ch);
	}
}