]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/dma/apbh_dma.c
am33xx: Update DT files, add am335x_gp_evm_config target
[karo-tx-uboot.git] / drivers / dma / apbh_dma.c
index ef7441ce2e3be4eae1f0e4cb7d717fe8969de604..4c5732e76e4cffb4bcce8a411d3f98808569b134 100644 (file)
@@ -86,7 +86,7 @@ static int mxs_dma_read_semaphore(int channel)
 }
 
 #ifndef        CONFIG_SYS_DCACHE_OFF
-void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
+static void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
 {
        uint32_t addr;
        uint32_t size;
@@ -97,7 +97,9 @@ void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
        flush_dcache_range(addr, addr + size);
 }
 #else
-inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc) {}
+static inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
+{
+}
 #endif
 
 /*
@@ -208,10 +210,10 @@ static int mxs_dma_disable(int channel)
 static int mxs_dma_reset(int channel)
 {
        int ret;
-#if defined(CONFIG_MX23)
+#if defined(CONFIG_SOC_MX23)
        uint32_t *setreg = &apbh_regs->hw_apbh_ctrl0_set;
        uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET;
-#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6))
+#elif (defined(CONFIG_SOC_MX28) || defined(CONFIG_SOC_MX6))
        uint32_t *setreg = &apbh_regs->hw_apbh_channel_ctrl_set;
        uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET;
 #endif
@@ -288,6 +290,7 @@ static int mxs_dma_request(int channel)
        pchan->flags |= MXS_DMA_FLAGS_ALLOCATED;
        pchan->active_num = 0;
        pchan->pending_num = 0;
+       pchan->timeout = 10000000;
 
        INIT_LIST_HEAD(&pchan->active);
        INIT_LIST_HEAD(&pchan->done);
@@ -325,6 +328,44 @@ int mxs_dma_release(int channel)
        return 0;
 }
 
+/*
+ * Set the timeout for any DMA operation started with mxs_dma_go()
+ * The timeout value given is in milliseconds
+ */
+int mxs_dma_set_timeout(int channel, unsigned long timeout)
+{
+       int ret;
+       struct mxs_dma_chan *pchan;
+
+       ret = mxs_dma_validate_chan(channel);
+       if (ret)
+               return ret;
+
+       pchan = &mxs_dma_channels[channel];
+
+       if (pchan->flags & MXS_DMA_FLAGS_BUSY)
+               return -EBUSY;
+
+       if (timeout > ~0UL / 1000)
+               return -EINVAL;
+
+       pchan->timeout = timeout;
+       return 0;
+}
+
+unsigned long mxs_dma_get_timeout(int channel)
+{
+       int ret;
+       struct mxs_dma_chan *pchan;
+
+       ret = mxs_dma_validate_chan(channel);
+       if (ret)
+               return 0;
+
+       pchan = &mxs_dma_channels[channel];
+       return pchan->timeout;
+}
+
 /*
  * Allocate DMA descriptor
  */
@@ -511,16 +552,25 @@ static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan)
  */
 int mxs_dma_go(int chan)
 {
-       uint32_t timeout = 10000;
        int ret;
-
+       struct mxs_dma_chan *pchan;
        LIST_HEAD(tmp_desc_list);
 
+       ret = mxs_dma_validate_chan(chan);
+       if (ret)
+               return ret;
+
+       pchan = &mxs_dma_channels[chan];
+
        mxs_dma_enable_irq(chan, 1);
-       mxs_dma_enable(chan);
+       ret = mxs_dma_enable(chan);
+       if (ret) {
+               mxs_dma_enable_irq(chan, 0);
+               return ret;
+       }
 
        /* Wait for DMA to finish. */
-       ret = mxs_dma_wait_complete(timeout, chan);
+       ret = mxs_dma_wait_complete(pchan->timeout * 1000, chan);
 
        /* Clear out the descriptors we just ran. */
        mxs_dma_finish(chan, &tmp_desc_list);
@@ -534,6 +584,28 @@ int mxs_dma_go(int chan)
        return ret;
 }
 
+/*
+ * Execute a continuously running circular DMA descriptor.
+ * NOTE: This is not intended for general use, but rather
+ *      for the LCD driver in Smart-LCD mode. It allows
+ *      continuous triggering of the RUN bit there.
+ */
+void mxs_dma_circ_start(int chan, struct mxs_dma_desc *pdesc)
+{
+       struct mxs_apbh_regs *apbh_regs =
+               (struct mxs_apbh_regs *)MXS_APBH_BASE;
+
+       mxs_dma_flush_desc(pdesc);
+
+       mxs_dma_enable_irq(chan, 1);
+
+       writel(mxs_dma_cmd_address(pdesc),
+               &apbh_regs->ch[chan].hw_apbh_ch_nxtcmdar);
+       writel(1, &apbh_regs->ch[chan].hw_apbh_ch_sema);
+       writel(1 << (chan + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET),
+               &apbh_regs->hw_apbh_ctrl0_clr);
+}
+
 /*
  * Initialize the DMA hardware
  */