static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) { struct davinci_runtime_data *prtd = substream->runtime->private_data; struct snd_pcm_runtime *runtime = substream->runtime; int lch = prtd->slave_lch; unsigned int period_size; unsigned int dma_offset; dma_addr_t dma_pos; dma_addr_t src, dst; unsigned short src_bidx, dst_bidx; unsigned int data_type; unsigned int count; period_size = snd_pcm_lib_period_bytes(substream); dma_offset = prtd->period * period_size; dma_pos = runtime->dma_addr + dma_offset; pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size); data_type = prtd->params->data_type; count = period_size / data_type; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { src = dma_pos; dst = prtd->params->dma_addr; src_bidx = data_type; dst_bidx = 0; } else { src = prtd->params->dma_addr; dst = dma_pos; src_bidx = 0; dst_bidx = data_type; } davinci_set_dma_src_params(lch, src, INCR, W8BIT); davinci_set_dma_dest_params(lch, dst, INCR, W8BIT); davinci_set_dma_src_index(lch, src_bidx, 0); davinci_set_dma_dest_index(lch, dst_bidx, 0); davinci_set_dma_transfer_params(lch, data_type, count, 1, 0, ASYNC); prtd->period++; if (unlikely(prtd->period >= runtime->periods)) prtd->period = 0; }
static int mmc_davinci_send_dma_request(struct mmc_davinci_host *host, struct mmc_request *req) { int sync_dev; unsigned char i, j; unsigned short acnt, bcnt, ccnt; unsigned int src_port, dst_port, temp_ccnt; enum address_mode mode_src, mode_dst; enum fifo_width fifo_width_src, fifo_width_dst; unsigned short src_bidx, dst_bidx; unsigned short src_cidx, dst_cidx; unsigned short bcntrld; enum sync_dimension sync_mode; edmacc_paramentry_regs temp; int edma_chan_num; struct mmc_data *data = host->data; struct scatterlist *sg = &data->sg[0]; unsigned int count; int num_frames, frame; frame = data->blksz; count = sg_dma_len(sg); if ((data->blocks == 1) && (count > data->blksz)) count = frame; if (count % 32 == 0) { acnt = 4; bcnt = 8; num_frames = count / 32; } else { acnt = count; bcnt = 1; num_frames = 1; } if (num_frames > MAX_C_CNT) { temp_ccnt = MAX_C_CNT; ccnt = temp_ccnt; } else { ccnt = num_frames; temp_ccnt = ccnt; } if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) { /*AB Sync Transfer */ sync_dev = host->dma_tx_event; src_port = (unsigned int)sg_dma_address(sg); mode_src = INCR; fifo_width_src = W8BIT; /* It's not cared as modeDsr is INCR */ src_bidx = acnt; src_cidx = acnt * bcnt; dst_port = host->phys_base + DAVINCI_MMC_REG_DXR; mode_dst = INCR; fifo_width_dst = W8BIT; /* It's not cared as modeDsr is INCR */ dst_bidx = 0; dst_cidx = 0; bcntrld = 8; sync_mode = ABSYNC; } else { sync_dev = host->dma_rx_event; src_port = host->phys_base + DAVINCI_MMC_REG_DRR; mode_src = INCR; fifo_width_src = W8BIT; src_bidx = 0; src_cidx = 0; dst_port = (unsigned int)sg_dma_address(sg); mode_dst = INCR; fifo_width_dst = W8BIT; /* It's not cared as modeDsr is INCR */ dst_bidx = acnt; dst_cidx = acnt * bcnt; bcntrld = 8; sync_mode = ABSYNC; } davinci_set_dma_src_params(sync_dev, src_port, mode_src, fifo_width_src); davinci_set_dma_dest_params(sync_dev, dst_port, mode_dst, fifo_width_dst); davinci_set_dma_src_index(sync_dev, src_bidx, src_cidx); davinci_set_dma_dest_index(sync_dev, dst_bidx, dst_cidx); davinci_set_dma_transfer_params(sync_dev, acnt, bcnt, ccnt, bcntrld, sync_mode); davinci_get_dma_params(sync_dev, &temp); if (sync_dev == host->dma_tx_event) { if (host->option_write == 0) { host->option_write = temp.opt; } else { temp.opt = host->option_write; davinci_set_dma_params(sync_dev, &temp); } } if (sync_dev == host->dma_rx_event) { if (host->option_read == 0) { host->option_read = temp.opt; } else { temp.opt = host->option_read; davinci_set_dma_params(sync_dev, &temp); } } if (host->sg_len > 1) { davinci_get_dma_params(sync_dev, &temp); temp.opt &= ~TCINTEN; davinci_set_dma_params(sync_dev, &temp); for (i = 0; i < host->sg_len - 1; i++) { sg = &data->sg[i + 1]; if (i != 0) { j = i - 1; davinci_get_dma_params(host->edma_ch_details. chanel_num[j], &temp); temp.opt &= ~TCINTEN; davinci_set_dma_params(host->edma_ch_details. chanel_num[j], &temp); } edma_chan_num = host->edma_ch_details.chanel_num[0]; frame = data->blksz; count = sg_dma_len(sg); if ((data->blocks == 1) && (count > data->blksz)) count = frame; ccnt = count / 32; if (sync_dev == host->dma_tx_event) temp.src = (unsigned int)sg_dma_address(sg); else temp.dst = (unsigned int)sg_dma_address(sg); temp.opt |= TCINTEN; temp.ccnt = (temp.ccnt & 0xFFFF0000) | (ccnt); davinci_set_dma_params(edma_chan_num, &temp); if (i != 0) { j = i - 1; davinci_dma_link_lch(host->edma_ch_details. chanel_num[j], edma_chan_num); } } davinci_dma_link_lch(sync_dev, host->edma_ch_details.chanel_num[0]); } davinci_start_dma(sync_dev); return 0; }
static int davinci_spi_bufs_dma(struct spi_device *spi, struct spi_transfer *t) { struct davinci_spi *davinci_spi; int int_status = 0; int count; u8 conv = 1; u8 tmp; u32 data1_reg_val; struct davinci_spi_dma *davinci_spi_dma; int word_len, data_type, ret; unsigned long tx_reg, rx_reg; struct davinci_spi_config_t *spi_cfg; struct davinci_spi_platform_data *pdata; davinci_spi = spi_master_get_devdata(spi->master); pdata = davinci_spi->pdata; BUG_ON(davinci_spi->dma_channels == NULL); davinci_spi_dma = &davinci_spi->dma_channels[spi->chip_select]; tx_reg = (unsigned long)davinci_spi->pbase + SPIDAT1; rx_reg = (unsigned long)davinci_spi->pbase + SPIBUF; /* used for macro defs */ davinci_spi->tx = t->tx_buf; davinci_spi->rx = t->rx_buf; /* convert len to words bbased on bits_per_word */ conv = davinci_spi->slave[spi->chip_select].bytes_per_word; davinci_spi->count = t->len / conv; INIT_COMPLETION(davinci_spi->done); init_completion(&davinci_spi_dma->dma_rx_completion); init_completion(&davinci_spi_dma->dma_tx_completion); word_len = conv * 8; if (word_len <= 8) data_type = DAVINCI_DMA_DATA_TYPE_S8; else if (word_len <= 16) data_type = DAVINCI_DMA_DATA_TYPE_S16; else if (word_len <= 32) data_type = DAVINCI_DMA_DATA_TYPE_S32; else return -1; spi_cfg = (struct davinci_spi_config_t *)spi->controller_data; ret = davinci_spi_bufs_prep(spi, davinci_spi, spi_cfg); if (ret) return ret; /* Put delay val if required */ iowrite32(0, davinci_spi->base + SPIDELAY); count = davinci_spi->count; /* the number of elements */ data1_reg_val = spi_cfg->cs_hold << SPI_SPIDAT1_CSHOLD_SHIFT; /* CD default = 0xFF */ tmp = ~(0x1 << spi->chip_select); if ((pdata->chip_sel != NULL) && (pdata->chip_sel[spi->chip_select] != DAVINCI_SPI_INTERN_CS)) gpio_set_value(pdata->chip_sel[spi->chip_select], 0); else clear_bits(davinci_spi->base + SPIDEF, ~tmp); data1_reg_val |= tmp << SPI_SPIDAT1_CSNR_SHIFT; /* disable all interrupts for dma transfers */ clear_bits(davinci_spi->base + SPIINT, SPI_SPIINT_MASKALL); /* Disable SPI to write configuration bits in SPIDAT */ clear_bits(davinci_spi->base + SPIGCR1, SPI_SPIGCR1_SPIENA_MASK); iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1); /* Enable SPI */ set_bits(davinci_spi->base + SPIGCR1, SPI_SPIGCR1_SPIENA_MASK); while (1) if (ioread32(davinci_spi->base + SPIBUF) & SPI_SPIBUF_RXEMPTY_MASK) break; if (t->tx_buf != NULL) { t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf, count, DMA_TO_DEVICE); if (dma_mapping_error(t->tx_dma)) { pr_err("%s(): Couldn't DMA map a %d bytes TX buffer\n", __func__, count); return -1; } davinci_set_dma_transfer_params(davinci_spi_dma->dma_tx_channel, data_type, count, 1, 0, ASYNC); davinci_set_dma_dest_params(davinci_spi_dma->dma_tx_channel, tx_reg, INCR, W8BIT); davinci_set_dma_src_params(davinci_spi_dma->dma_tx_channel, t->tx_dma, INCR, W8BIT); davinci_set_dma_src_index(davinci_spi_dma->dma_tx_channel, data_type, 0); davinci_set_dma_dest_index(davinci_spi_dma->dma_tx_channel, 0, 0); } else { /* We need TX clocking for RX transaction */ t->tx_dma = dma_map_single(&spi->dev, (void *)davinci_spi->tmp_buf, count + 1, DMA_TO_DEVICE); if (dma_mapping_error(t->tx_dma)) { pr_err("%s(): Couldn't DMA map a %d bytes TX " "tmp buffer\n", __func__, count); return -1; } davinci_set_dma_transfer_params(davinci_spi_dma->dma_tx_channel, data_type, count + 1, 1, 0, ASYNC); davinci_set_dma_dest_params(davinci_spi_dma->dma_tx_channel, tx_reg, INCR, W8BIT); davinci_set_dma_src_params(davinci_spi_dma->dma_tx_channel, t->tx_dma, INCR, W8BIT); davinci_set_dma_src_index(davinci_spi_dma->dma_tx_channel, data_type, 0); davinci_set_dma_dest_index(davinci_spi_dma->dma_tx_channel, 0, 0); } if (t->rx_buf != NULL) { /* initiate transaction */ iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1); t->rx_dma = dma_map_single(&spi->dev, (void *)t->rx_buf, count, DMA_FROM_DEVICE); if (dma_mapping_error(t->rx_dma)) { pr_err("%s(): Couldn't DMA map a %d bytes RX buffer\n", __func__, count); if (t->tx_buf != NULL) dma_unmap_single(NULL, t->tx_dma, count, DMA_TO_DEVICE); return -1; } davinci_set_dma_transfer_params(davinci_spi_dma->dma_rx_channel, data_type, count, 1, 0, ASYNC); davinci_set_dma_src_params(davinci_spi_dma->dma_rx_channel, rx_reg, INCR, W8BIT); davinci_set_dma_dest_params(davinci_spi_dma->dma_rx_channel, t->rx_dma, INCR, W8BIT); davinci_set_dma_src_index(davinci_spi_dma->dma_rx_channel, 0, 0); davinci_set_dma_dest_index(davinci_spi_dma->dma_rx_channel, data_type, 0); } if ((t->tx_buf != NULL) || (t->rx_buf != NULL)) davinci_start_dma(davinci_spi_dma->dma_tx_channel); if (t->rx_buf != NULL) davinci_start_dma(davinci_spi_dma->dma_rx_channel); if ((t->rx_buf != NULL) || (t->tx_buf != NULL)) davinci_spi_set_dma_req(spi, 1); if (t->tx_buf != NULL) wait_for_completion_interruptible( &davinci_spi_dma->dma_tx_completion); if (t->rx_buf != NULL) wait_for_completion_interruptible( &davinci_spi_dma->dma_rx_completion); if (t->tx_buf != NULL) dma_unmap_single(NULL, t->tx_dma, count, DMA_TO_DEVICE); else dma_unmap_single(NULL, t->tx_dma, count + 1, DMA_TO_DEVICE); if (t->rx_buf != NULL) dma_unmap_single(NULL, t->rx_dma, count, DMA_FROM_DEVICE); /* * Check for bit error, desync error,parity error,timeout error and * receive overflow errors */ int_status = ioread32(davinci_spi->base + SPIFLG); ret = davinci_spi_check_error(davinci_spi, int_status); if (ret != 0) return ret; /* SPI Framework maintains the count only in bytes so convert back */ davinci_spi->count *= conv; return t->len; }
static int ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args) { int ret; unsigned int __user *argp = (unsigned int __user *) args; unsigned long physp; unsigned long virtp; unsigned int type; //__D("ioctl %d received. \n", cmd); switch (cmd) { case IPERA_INIT_PMU_STATICS: init_pmu_asm(); __D("IPERA_INIT_PMU_STATICS : returning\n"); break; case IPERA_START_PMU_CACHES_STATICS: //memset(&type, 0, sizeof(type)); //ret = copy_from_user(&type, argp, sizeof(type)); //set_pmu_event_asm(PMU_ICACHE_EXEC, EVENT_COUNTER0); //set_pmu_event_asm(PMU_ICACHE_MISS, EVENT_COUNTER1); //set_pmu_event_asm(PMU_DCACHE_ACCESS, EVENT_COUNTER2); //set_pmu_event_asm(PMU_DCACHE_MISS, EVENT_COUNTER3); //start_pmu_asm(); //__D("IPERA_START_PMU_CACHES_STATICS : returning\n"); break; case IPERA_END_PMU_CACHES_STATICS: //memset(&type, 0, sizeof(type)); //ret = copy_from_user(&type, argp, sizeof(type)); //stop_pmu_asm(); //pmu_statics[type].pmu_count += 1; //pmu_statics[type].pmu_cycles += get_clock_counter_asm(); //pmu_statics[type].pmu_instr_exec += get_pmnx_counter_asm(EVENT_COUNTER0); //pmu_statics[type].pmu_icache_miss += get_pmnx_counter_asm(EVENT_COUNTER1); //pmu_statics[type].pmu_dcache_access += get_pmnx_counter_asm(EVENT_COUNTER2); //pmu_statics[type].pmu_dcache_miss += get_pmnx_counter_asm(EVENT_COUNTER3); //__D("IPERA_END_PMU_CACHES_STATICS : returning\n"); break; case IPERA_GET_STATICS: //memset(&type, 0, sizeof(type)); //ret = copy_from_user(&type, argp, sizeof(type)); //ret_get_cycles = pmu_statics[type].pmu_cycles; //__D("IPERA_GET_CYCLES : returning %#lx\n", (unsigned long)pmu_statics[type].pmu_count); //__D("IPERA_GET_CYCLES : returning %#lx\n", (unsigned long)pmu_statics[type].pmu_cycles); //__D("IPERA_GET_ICACHE_EXEC : returning %#lx\n", (unsigned long)pmu_statics[type].pmu_instr_exec); //__D("IPERA_GET_ICACHE_MISS : returning %#lx\n", (unsigned long)pmu_statics[type].pmu_icache_miss); //__D("IPERA_GET_DCACHE_ACCESS : returning %#lx\n", (unsigned long)pmu_statics[type].pmu_dcache_access); //__D("IPERA_GET_DCACHE_MISS : returning %#lx\n", (unsigned long)pmu_statics[type].pmu_dcache_miss); //ret = copy_to_user(argp, &pmu_statics[type], sizeof(pmu_statics[type])); break; case IPERA_GET_PHYS: get_user(virtp, argp); physp = ipera_get_phys(virtp); put_user(physp, argp); //__D("IPERA_GET_PHYS : returning %#lx\n", physp); break; #if 0 case IPERA_GET_CYCLES: __D("IPERA_GET_CYCLES : received.\n"); cur_cycles = get_cycles(); copy_to_user(argp, &cur_cycles, sizeof(cur_cycles)); __D("IPERA_GET_CYCLES : returning %#lx\n", cur_cycles); break; case IPERA_GET_PHYS: __D("IPERA_GET_PHYS : received.\n"); get_user(virtp, argp); physp = get_phys(virtp); put_user(physp, argp); __D("IPERA_GET_PHYS : returning %#lx\n", physp); break; case IPERA_DMACPY: __D("IPERA_DMACPY : received.\n"); if (copy_from_user(&dma, argp, sizeof(dma))) { return -EFAULT; } err = davinci_request_dma(DM350_DMA_CHANNEL_ANY, "EDMA memcpy", memcpy_dma_irq_handler, NULL, &master_ch, &tcc, EVENTQ_1); if (err < 0) { __E("Error in requesting Master channel %d = 0x%x\n", master_ch, err); return err; } else if(master_ch != 25) __E("get channel %d \n", master_ch); davinci_stop_dma(master_ch); init_completion(&edmacompletion); davinci_set_dma_src_params(master_ch, (unsigned long) edmaparams.src, edmaparams.srcmode, edmaparams.srcfifowidth); davinci_set_dma_dest_params(master_ch, (unsigned long) edmaparams.dst, edmaparams.dstmode, edmaparams.dstfifowidth); davinci_set_dma_src_index(master_ch, edmaparams.srcbidx, edmaparams.srccidx); davinci_set_dma_dest_index(master_ch, edmaparams.dstbidx, edmaparams.dstcidx); davinci_set_dma_transfer_params(master_ch, edmaparams.acnt, edmaparams.bcnt, edmaparams.ccnt, edmaparams.bcntrld, edmaparams.syncmode); davinci_get_dma_params(master_ch, ¶mentry); davinci_set_dma_params(master_ch, ¶mentry); davinci_start_dma(master_ch); wait_for_completion(&edmacompletion); //printk("Dma completed... \n"); davinci_stop_dma(master_ch); davinci_free_dma(master_ch); break; #endif default: __E("Unknown ioctl received = %d.\n", cmd); return -EINVAL; } return 0; }