Merge branch 'topic/imx' into for-linus
authorVinod Koul <vkoul@kernel.org>
Tue, 12 Mar 2019 06:34:01 +0000 (12:04 +0530)
committerVinod Koul <vkoul@kernel.org>
Tue, 12 Mar 2019 06:34:01 +0000 (12:04 +0530)
1  2 
drivers/dma/imx-sdma.c

diff --combined drivers/dma/imx-sdma.c
index 237a9c165072e20ff2782b17f93ac1a23dc4bd07,af14a8d6efa8855d36cc9a727064f1f3919495eb..88197d5ac3b97cb3463cd681d2c8b8d756df4741
@@@ -377,6 -377,7 +377,7 @@@ struct sdma_channel 
        unsigned long                   watermark_level;
        u32                             shp_addr, per_addr;
        enum dma_status                 status;
+       bool                            context_loaded;
        struct imx_dma_data             data;
        struct work_struct              terminate_worker;
  };
@@@ -440,8 -441,6 +441,8 @@@ struct sdma_engine 
        unsigned int                    irq;
        dma_addr_t                      bd0_phys;
        struct sdma_buffer_descriptor   *bd0;
 +      /* clock ratio for AHB:SDMA core. 1:1 is 1, 2:1 is 0*/
 +      bool                            clk_ratio;
  };
  
  static int sdma_config_write(struct dma_chan *chan,
@@@ -664,11 -663,8 +665,11 @@@ static int sdma_run_channel0(struct sdm
                dev_err(sdma->dev, "Timeout waiting for CH0 ready\n");
  
        /* Set bits of CONFIG register with dynamic context switching */
 -      if (readl(sdma->regs + SDMA_H_CONFIG) == 0)
 -              writel_relaxed(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG);
 +      reg = readl(sdma->regs + SDMA_H_CONFIG);
 +      if ((reg & SDMA_H_CONFIG_CSM) == 0) {
 +              reg |= SDMA_H_CONFIG_CSM;
 +              writel_relaxed(reg, sdma->regs + SDMA_H_CONFIG);
 +      }
  
        return ret;
  }
@@@ -682,7 -678,7 +683,7 @@@ static int sdma_load_script(struct sdma
        int ret;
        unsigned long flags;
  
-       buf_virt = dma_alloc_coherent(NULL, size, &buf_phys, GFP_KERNEL);
+       buf_virt = dma_alloc_coherent(sdma->dev, size, &buf_phys, GFP_KERNEL);
        if (!buf_virt) {
                return -ENOMEM;
        }
  
        spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
  
-       dma_free_coherent(NULL, size, buf_virt, buf_phys);
+       dma_free_coherent(sdma->dev, size, buf_virt, buf_phys);
  
        return ret;
  }
@@@ -975,6 -971,9 +976,9 @@@ static int sdma_load_context(struct sdm
        int ret;
        unsigned long flags;
  
+       if (sdmac->context_loaded)
+               return 0;
        if (sdmac->direction == DMA_DEV_TO_MEM)
                load_address = sdmac->pc_from_device;
        else if (sdmac->direction == DMA_DEV_TO_DEV)
  
        spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
  
+       sdmac->context_loaded = true;
        return ret;
  }
  
@@@ -1056,6 -1057,7 +1062,7 @@@ static void sdma_channel_terminate_work
        sdmac->desc = NULL;
        spin_unlock_irqrestore(&sdmac->vc.lock, flags);
        vchan_dma_desc_free_list(&sdmac->vc, &head);
+       sdmac->context_loaded = false;
  }
  
  static int sdma_disable_channel_async(struct dma_chan *chan)
@@@ -1187,7 -1189,7 +1194,7 @@@ static int sdma_request_channel0(struc
  {
        int ret = -EBUSY;
  
-       sdma->bd0 = dma_zalloc_coherent(NULL, PAGE_SIZE, &sdma->bd0_phys,
+       sdma->bd0 = dma_zalloc_coherent(sdma->dev, PAGE_SIZE, &sdma->bd0_phys,
                                        GFP_NOWAIT);
        if (!sdma->bd0) {
                ret = -ENOMEM;
@@@ -1210,8 -1212,8 +1217,8 @@@ static int sdma_alloc_bd(struct sdma_de
        u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
        int ret = 0;
  
-       desc->bd = dma_zalloc_coherent(NULL, bd_size, &desc->bd_phys,
-                                       GFP_NOWAIT);
+       desc->bd = dma_zalloc_coherent(desc->sdmac->sdma->dev, bd_size,
+                                      &desc->bd_phys, GFP_NOWAIT);
        if (!desc->bd) {
                ret = -ENOMEM;
                goto out;
@@@ -1224,7 -1226,8 +1231,8 @@@ static void sdma_free_bd(struct sdma_de
  {
        u32 bd_size = desc->num_bd * sizeof(struct sdma_buffer_descriptor);
  
-       dma_free_coherent(NULL, bd_size, desc->bd, desc->bd_phys);
+       dma_free_coherent(desc->sdmac->sdma->dev, bd_size, desc->bd,
+                         desc->bd_phys);
  }
  
  static void sdma_desc_free(struct virt_dma_desc *vd)
@@@ -1844,13 -1847,10 +1852,13 @@@ static int sdma_init(struct sdma_engin
        if (ret)
                goto disable_clk_ipg;
  
 +      if (clk_get_rate(sdma->clk_ahb) == clk_get_rate(sdma->clk_ipg))
 +              sdma->clk_ratio = 1;
 +
        /* Be sure SDMA has not started yet */
        writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
  
-       sdma->channel_control = dma_alloc_coherent(NULL,
+       sdma->channel_control = dma_alloc_coherent(sdma->dev,
                        MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) +
                        sizeof(struct sdma_context_data),
                        &ccb_phys, GFP_KERNEL);
        writel_relaxed(0x4050, sdma->regs + SDMA_CHN0ADDR);
  
        /* Set bits of CONFIG register but with static context switching */
 -      /* FIXME: Check whether to set ACR bit depending on clock ratios */
 -      writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);
 +      if (sdma->clk_ratio)
 +              writel_relaxed(SDMA_H_CONFIG_ACR, sdma->regs + SDMA_H_CONFIG);
 +      else
 +              writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);
  
        writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR);
  
@@@ -1913,16 -1911,11 +1921,16 @@@ disable_clk_ipg
  static bool sdma_filter_fn(struct dma_chan *chan, void *fn_param)
  {
        struct sdma_channel *sdmac = to_sdma_chan(chan);
 +      struct sdma_engine *sdma = sdmac->sdma;
        struct imx_dma_data *data = fn_param;
  
        if (!imx_dma_is_general_purpose(chan))
                return false;
  
 +      /* return false if it's not the right device */
 +      if (sdma->dev->of_node != data->of_node)
 +              return false;
 +
        sdmac->data = *data;
        chan->private = &sdmac->data;
  
@@@ -1950,7 -1943,6 +1958,7 @@@ static struct dma_chan *sdma_xlate(stru
         * be set to sdmac->event_id1.
         */
        data.dma_request2 = 0;
 +      data.of_node = ofdma->of_node;
  
        return dma_request_channel(mask, sdma_filter_fn, &data);
  }
@@@ -2113,7 -2105,6 +2121,7 @@@ static int sdma_probe(struct platform_d
        sdma->dma_device.device_prep_dma_memcpy = sdma_prep_memcpy;
        sdma->dma_device.device_issue_pending = sdma_issue_pending;
        sdma->dma_device.dev->dma_parms = &sdma->dma_parms;
 +      sdma->dma_device.copy_align = 2;
        dma_set_max_seg_size(sdma->dma_device.dev, SDMA_BD_MAX_CNT);
  
        platform_set_drvdata(pdev, sdma);