On Tuesday 10 January 2017 03:08 PM, Alexandre Bailon wrote:
> 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 <abai...@baylibre.com>
>>> ---
>>>  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.

On DA8xx, CPPI 4.1 DMAengine is not an independent system resource, but
embedded within the USB 2.0 controller. So, I think all that is needed
is for MUSB DA8xx glue to trigger probe of CPPI 4.1 dmaengine driver
when it is ready. I am not sure all this DA850-specific clock handling
is really necessary.

Even in DT, the CPPI 4.1 node should be a child node of USB 2.0 node.

Thanks,
sekhar
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to