|
@@ -322,3 +322,80 @@ static __inline__ void enable_dma(unsigned int dmanr)
|
|
#ifdef DMA_DEBUG
|
|
#ifdef DMA_DEBUG
|
|
printk("enable_dma(dmanr=%d)\n", dmanr);
|
|
printk("enable_dma(dmanr=%d)\n", dmanr);
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
|
|
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
|
|
|
|
+ dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static __inline__ void disable_dma(unsigned int dmanr)
|
|
|
|
+{
|
|
|
|
+ volatile unsigned int *dmalp;
|
|
|
|
+
|
|
|
|
+#ifdef DMA_DEBUG
|
|
|
|
+ printk("disable_dma(dmanr=%d)\n", dmanr);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
|
|
|
|
+
|
|
|
|
+ /* Turn off external requests, and stop any DMA in progress */
|
|
|
|
+ dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
|
|
|
|
+ dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Clear the 'DMA Pointer Flip Flop'.
|
|
|
|
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
|
|
|
|
+ * Use this once to initialize the FF to a known state.
|
|
|
|
+ * After that, keep track of it. :-)
|
|
|
|
+ * --- In order to do that, the DMA routines below should ---
|
|
|
|
+ * --- only be used while interrupts are disabled! ---
|
|
|
|
+ *
|
|
|
|
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
|
|
|
|
+ */
|
|
|
|
+static __inline__ void clear_dma_ff(unsigned int dmanr)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* set mode (above) for a specific DMA channel */
|
|
|
|
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ volatile unsigned int *dmalp;
|
|
|
|
+ volatile unsigned short *dmawp;
|
|
|
|
+
|
|
|
|
+#ifdef DMA_DEBUG
|
|
|
|
+ printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
|
|
|
|
+#endif
|
|
|
|
+ dmalp = (unsigned int *) dma_base_addr[dmanr];
|
|
|
|
+ dmawp = (unsigned short *) dma_base_addr[dmanr];
|
|
|
|
+
|
|
|
|
+ /* Clear config errors */
|
|
|
|
+ dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
|
|
|
|
+
|
|
|
|
+ /* Set command register */
|
|
|
|
+ dmalp[MCFDMA_DMR] =
|
|
|
|
+ MCFDMA_DMR_RQM_DUAL | /* Mandatory Request Mode setting */
|
|
|
|
+ MCFDMA_DMR_DSTT_SD | /* Set up addressing types; set to supervisor-data. */
|
|
|
|
+ MCFDMA_DMR_SRCT_SD | /* Set up addressing types; set to supervisor-data. */
|
|
|
|
+ /* source static-address-mode */
|
|
|
|
+ ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
|
|
|
|
+ /* dest static-address-mode */
|
|
|
|
+ ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
|
|
|
|
+ /* burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 */
|
|
|
|
+ (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
|
|
|
|
+ (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
|
|
|
|
+
|
|
|
|
+ dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG_DMA
|
|
|
|
+ printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
|
|
|
|
+ dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
|
|
|
|
+ (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Set transfer address for specific DMA channel */
|
|
|
|
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
|
|
|
|
+{
|
|
|
|
+ volatile unsigned int *dmalp;
|
|
|
|
+
|