On 01/09/2017 07:08 PM, Grygorii Strashko wrote:
> 
> 
> On 01/09/2017 10:06 AM, Alexandre Bailon wrote:
>> The da8xx has a cppi41 dma controller.
>> This is add the glue layer required to make it work on da8xx,
>> as well some changes in driver (e.g to manage clock).
>>
>> Signed-off-by: Alexandre Bailon <[email protected]>
>> ---
>>  drivers/dma/cppi41.c | 95 
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 95 insertions(+)
>>
>> diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
>> index 939398e..4318e53 100644
>> --- a/drivers/dma/cppi41.c
>> +++ b/drivers/dma/cppi41.c
>> @@ -1,3 +1,4 @@
>> +#include <linux/clk.h>
>>  #include <linux/delay.h>
>>  #include <linux/dmaengine.h>
>>  #include <linux/dma-mapping.h>
>> @@ -86,10 +87,19 @@
>>  
>>  #define USBSS_IRQ_PD_COMP   (1 <<  2)
>>  
>> +/* USB DA8XX */
>> +#define DA8XX_INTR_SRC_MASKED       0x38
>> +#define DA8XX_END_OF_INTR   0x3c
>> +
>> +#define DA8XX_QMGR_PENDING_MASK     (0xf << 24)
>> +
>> +
>> +
>>  /* Packet Descriptor */
>>  #define PD2_ZERO_LENGTH             (1 << 19)
>>  
>>  #define AM335X_CPPI41               0
>> +#define DA8XX_CPPI41                1
>>  
>>  struct cppi41_channel {
>>      struct dma_chan chan;
>> @@ -158,6 +168,9 @@ struct cppi41_dd {
>>  
>>      /* context for suspend/resume */
>>      unsigned int dma_tdfdq;
>> +
>> +    /* da8xx clock */
>> +    struct clk *clk;
>>  };
>>  
>>  static struct chan_queues am335x_usb_queues_tx[] = {
>> @@ -232,6 +245,20 @@ static const struct chan_queues am335x_usb_queues_rx[] 
>> = {
>>      [29] = { .submit = 30, .complete = 155},
>>  };
>>  
>> +static const struct chan_queues da8xx_usb_queues_tx[] = {
>> +    [0] = { .submit =  16, .complete = 24},
>> +    [1] = { .submit =  18, .complete = 24},
>> +    [2] = { .submit =  20, .complete = 24},
>> +    [3] = { .submit =  22, .complete = 24},
>> +};
>> +
>> +static const struct chan_queues da8xx_usb_queues_rx[] = {
>> +    [0] = { .submit =  1, .complete = 26},
>> +    [1] = { .submit =  3, .complete = 26},
>> +    [2] = { .submit =  5, .complete = 26},
>> +    [3] = { .submit =  7, .complete = 26},
>> +};
>> +
>>  struct cppi_glue_infos {
>>      irqreturn_t (*isr)(int irq, void *data);
>>      const struct chan_queues *queues_rx;
>> @@ -366,6 +393,26 @@ static irqreturn_t am335x_cppi41_irq(int irq, void 
>> *data)
>>      return cppi41_irq(cdd);
>>  }
>>  
>> +static irqreturn_t da8xx_cppi41_irq(int irq, void *data)
>> +{
>> +    struct cppi41_dd *cdd = data;
>> +    u32 status;
>> +    u32 usbss_status;
>> +
>> +    status = cppi_readl(cdd->qmgr_mem + QMGR_PEND(0));
>> +    if (status & DA8XX_QMGR_PENDING_MASK)
>> +            cppi41_irq(cdd);
>> +    else
>> +            return IRQ_NONE;
>> +
>> +    /* Re-assert IRQ if there no usb core interrupts pending */
>> +    usbss_status = cppi_readl(cdd->usbss_mem + DA8XX_INTR_SRC_MASKED);
>> +    if (!usbss_status)
>> +            cppi_writel(0, cdd->usbss_mem + DA8XX_END_OF_INTR);
>> +
>> +    return IRQ_HANDLED;
>> +}
>> +
>>  static dma_cookie_t cppi41_tx_submit(struct dma_async_tx_descriptor *tx)
>>  {
>>      dma_cookie_t cookie;
>> @@ -972,8 +1019,19 @@ static const struct cppi_glue_infos am335x_usb_infos = 
>> {
>>      .platform = AM335X_CPPI41,
>>  };
>>  
>> +static const struct cppi_glue_infos da8xx_usb_infos = {
>> +    .isr = da8xx_cppi41_irq,
>> +    .queues_rx = da8xx_usb_queues_rx,
>> +    .queues_tx = da8xx_usb_queues_tx,
>> +    .td_queue = { .submit = 31, .complete = 0 },
>> +    .first_completion_queue = 24,
>> +    .qmgr_num_pend = 2,
>> +    .platform = DA8XX_CPPI41,
>> +};
>> +
>>  static const struct of_device_id cppi41_dma_ids[] = {
>>      { .compatible = "ti,am3359-cppi41", .data = &am335x_usb_infos},
>> +    { .compatible = "ti,da8xx-cppi41", .data = &da8xx_usb_infos},
>>      {},
>>  };
>>  MODULE_DEVICE_TABLE(of, cppi41_dma_ids);
>> @@ -995,6 +1053,13 @@ static int is_am335x_cppi41(struct device *dev)
>>      return cdd->platform == AM335X_CPPI41;
>>  }
>>  
>> +static int is_da8xx_cppi41(struct device *dev)
>> +{
>> +    struct cppi41_dd *cdd = dev_get_drvdata(dev);
>> +
>> +    return cdd->platform == DA8XX_CPPI41;
>> +}
>> +
>>  #define CPPI41_DMA_BUSWIDTHS        (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
>>                              BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
>>                              BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
>> @@ -1058,6 +1123,21 @@ static int cppi41_dma_probe(struct platform_device 
>> *pdev)
>>      cdd->first_completion_queue = glue_info->first_completion_queue;
>>      cdd->platform = glue_info->platform;
>>  
>> +    if (is_da8xx_cppi41(dev)) {
>> +            cdd->clk = devm_clk_get(&pdev->dev, "usb20");
>> +            ret = PTR_ERR_OR_ZERO(cdd->clk);
>> +            if (ret) {
>> +                    dev_err(&pdev->dev, "failed to get clock\n");
>> +                    goto err_clk_en;
>> +            }
>> +
>> +            ret = clk_prepare_enable(cdd->clk);
>> +            if (ret) {
>> +                    dev_err(dev, "failed to enable clock\n");
>> +                    goto err_clk_en;
>> +            }
>> +    }
> 
> if this is functional clock then why not to use 
> ./arch/arm/mach-davinci/pm_domain.c ?
> wouldn't it work for use if you will just rename "usb20" -> "fck" -
> so PM runtime should manage this clock for you?
As is, I don't think it will work.
The usb20 is shared by the cppi41 and the usb otg.
So, if we rename "usb20" to "fck", clk_get() won't be able to find the
clock.
But may be adding "usb20" to "con_ids" in
arch/arm/mach-davinci/pm_domain.c could work.
But I think it will require some changes in da8xx musb driver.
I will take look.

Thanks,
Alexandre
> 
>> +
>>      ret = of_property_read_u32(dev->of_node,
>>                                 "#dma-channels", &cdd->n_chans);
>>      if (ret)
>> @@ -1112,6 +1192,9 @@ static int cppi41_dma_probe(struct platform_device 
>> *pdev)
>>  err_init_cppi:
>>      pm_runtime_dont_use_autosuspend(dev);
>>  err_get_n_chans:
>> +    if (is_da8xx_cppi41(dev))
>> +            clk_disable_unprepare(cdd->clk);
>> +err_clk_en:
>>  err_get_sync:
>>      pm_runtime_put_sync(dev);
>>      pm_runtime_disable(dev);
>> @@ -1146,6 +1229,8 @@ static int cppi41_dma_remove(struct platform_device 
>> *pdev)
>>      pm_runtime_dont_use_autosuspend(&pdev->dev);
>>      pm_runtime_put_sync(&pdev->dev);
>>      pm_runtime_disable(&pdev->dev);
>> +    if (is_da8xx_cppi41(&pdev->dev))
>> +            clk_disable_unprepare(cdd->clk);
>>      return 0;
>>  }
>>  
>> @@ -1158,6 +1243,9 @@ static int __maybe_unused cppi41_suspend(struct device 
>> *dev)
>>              cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR);
>>      disable_sched(cdd);
>>  
>> +    if (is_da8xx_cppi41(dev))
>> +            clk_disable_unprepare(cdd->clk);
>> +
>>      return 0;
>>  }
>>  
>> @@ -1165,8 +1253,15 @@ static int __maybe_unused cppi41_resume(struct device 
>> *dev)
>>  {
>>      struct cppi41_dd *cdd = dev_get_drvdata(dev);
>>      struct cppi41_channel *c;
>> +    int ret;
>>      int i;
>>  
>> +    if (is_da8xx_cppi41(dev)) {
>> +            ret = clk_prepare_enable(cdd->clk);
>> +            if (ret)
>> +                    return ret;
>> +    }
>> +
>>      for (i = 0; i < DESCS_AREAS; i++)
>>              cppi_writel(cdd->descs_phys, cdd->qmgr_mem + QMGR_MEMBASE(i));
>>  
>>
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to