浏览代码

waterHeterogeneousDataSynchronization memoryOperation.c 姚强 commit at 2020-12-04

姚强 4 年之前
父节点
当前提交
6a800da0ea
共有 1 个文件被更改,包括 120 次插入0 次删除
  1. 120 0
      waterHeterogeneousDataSynchronization/dataSharedMemory/memoryOperation.c

+ 120 - 0
waterHeterogeneousDataSynchronization/dataSharedMemory/memoryOperation.c

@@ -1065,3 +1065,123 @@ int s3c2410_dma_config(enum dma_ch channel,
 
 	case 2:
 		dcon |= S3C2410_DCON_HALFWORD;
+		break;
+
+	case 4:
+		dcon |= S3C2410_DCON_WORD;
+		break;
+
+	default:
+		pr_debug("%s: bad transfer size %d\n", __func__, xferunit);
+		return -EINVAL;
+	}
+
+	dcon |= S3C2410_DCON_HWTRIG;
+	dcon |= S3C2410_DCON_INTREQ;
+
+	pr_debug("%s: dcon now %08x\n", __func__, dcon);
+
+	chan->dcon = dcon;
+	chan->xfer_unit = xferunit;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+
+/* s3c2410_dma_devconfig
+ *
+ * configure the dma source/destination hardware type and address
+ *
+ * source:    DMA_FROM_DEVICE: source is hardware
+ *            DMA_TO_DEVICE: source is memory
+ *
+ * devaddr:   physical address of the source
+*/
+
+int s3c2410_dma_devconfig(enum dma_ch channel,
+			  enum dma_data_direction source,
+			  unsigned long devaddr)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+	unsigned int hwcfg;
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	pr_debug("%s: source=%d, devaddr=%08lx\n",
+		 __func__, (int)source, devaddr);
+
+	chan->source = source;
+	chan->dev_addr = devaddr;
+
+	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 DMA_FROM_DEVICE:
+		/* source is hardware */
+		pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
+			 __func__, devaddr, hwcfg);
+		dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
+		dma_wrreg(chan, S3C2410_DMA_DISRC,  devaddr);
+		dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
+
+		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
+		break;
+
+	case DMA_TO_DEVICE:
+		/* source is memory */
+		pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
+			 __func__, devaddr, hwcfg);
+		dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
+		dma_wrreg(chan, S3C2410_DMA_DIDST,  devaddr);
+		dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
+
+		chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
+		break;
+
+	default:
+		printk(KERN_ERR "dma%d: invalid source type (%d)\n",
+		       channel, source);
+
+		return -EINVAL;
+	}
+
+	if (dma_sel.direction != NULL)
+		(dma_sel.direction)(chan, chan->map, source);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+/* s3c2410_dma_getposition
+ *
+ * returns the current transfer points for the dma source and destination
+*/
+
+int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dst)
+{
+	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+	if (chan == NULL)
+		return -EINVAL;
+
+	if (src != NULL)
+ 		*src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+
+ 	if (dst != NULL)
+ 		*dst = dma_rdreg(chan, S3C2410_DMA_DCDST);