On Wed, Jan 25, 2017 at 06:34:17PM +0300, Eugeniy Paltsev wrote:
> This patch adds support for the DW AXI DMAC controller.
> 
> DW AXI DMAC is a part of upcoming development board from Synopsys.

How different is AXI from DW Synopsys?

Is the spec publicly available?

> +config AXI_DW_DMAC
> +     tristate "Synopsys DesignWare AXI DMA support"
> +     depends on OF && !64BIT

why not 64 bit, can you also add compile test

> +#define AXI_DMA_BUSWIDTHS              \
> +     (DMA_SLAVE_BUSWIDTH_UNDEFINED   | \

DMA_SLAVE_BUSWIDTH_UNDEFINED??

> +static irqreturn_t dw_axi_dma_intretupt(int irq, void *dev_id)
> +{
> +     struct axi_dma_chip *chip = dev_id;
> +
> +     /* Disable DMAC inerrupts. We'll enable them in the tasklet */
> +     axi_dma_irq_disable(chip);
> +
> +     tasklet_schedule(&chip->dw->tasklet);

This is very inefficient, we would want to submit next txn here and not in
tasklet

> +static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
> +{
> +     struct virt_dma_desc *vd;
> +     unsigned long flags;
> +
> +     spin_lock_irqsave(&chan->vc.lock, flags);
> +     if (unlikely(axi_chan_is_hw_enable(chan))) {
> +             dev_err(chan2dev(chan), "BUG: %s catched DWAXIDMAC_IRQ_DMA_TRF, 
> but channel not idle!\n",
> +                     axi_chan_name(chan));
> +             axi_chan_disable(chan);
> +     }
> +
> +     /* The completed descriptor currently is in the head of vc list */
> +     vd = vchan_next_desc(&chan->vc);
> +     /* Remove the completed descriptor from issued list before completing */
> +     list_del(&vd->node);
> +     vchan_cookie_complete(vd);

this should be called from irq handler


> +static int dw_remove(struct platform_device *pdev)
> +{
> +     struct axi_dma_chip *chip = platform_get_drvdata(pdev);
> +     struct dw_axi_dma *dw = chip->dw;
> +     struct axi_dma_chan *chan, *_chan;
> +     u32 i;
> +
> +     axi_dma_irq_disable(chip);
> +     for (i = 0; i < dw->hdata->nr_channels; i++) {
> +             axi_chan_disable(&chip->dw->chan[i]);
> +             axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
> +     }
> +     axi_dma_disable(chip);
> +
> +     tasklet_kill(&dw->tasklet);
> +
> +     list_for_each_entry_safe(chan, _chan, &dw->dma.channels,
> +                     vc.chan.device_node) {
> +             list_del(&chan->vc.chan.device_node);
> +             tasklet_kill(&chan->vc.task);
> +     }

very nice :)

But please freeup irq as well

> +module_platform_driver(dw_driver);
> +
> +static int __init dw_init(void)
> +{
> +     return platform_driver_register(&dw_driver);
> +}
> +subsys_initcall(dw_init);

why subsys_initcall??

> +/* Common registers offset */
> +#define DMAC_ID                      0x000 // R DMAC ID
> +#define DMAC_COMPVER         0x008 // R DMAC Component Version
> +#define DMAC_CFG             0x010 // R/W DMAC Configuration
> +#define DMAC_CHEN            0x018 // R/W DMAC Channel Enable
> +#define DMAC_CHEN_L          0x018 // R/W DMAC Channel Enable 00-31
> +#define DMAC_CHEN_H          0x01C // R/W DMAC Channel Enable 32-63
> +#define DMAC_INTSTATUS               0x030 // R DMAC Interrupt Status
> +#define DMAC_COMMON_INTCLEAR 0x038 // W DMAC Interrupt Clear
> +#define DMAC_COMMON_INTSTATUS_ENA 0x040 // R DMAC Interrupt Status Enable
> +#define DMAC_COMMON_INTSIGNAL_ENA 0x048 // R/W DMAC Interrupt Signal Enable
> +#define DMAC_COMMON_INTSTATUS        0x050 // R DMAC Interrupt Status
> +#define DMAC_RESET           0x058 // R DMAC Reset Register1

DMAC is a generic term, AX_DMAC and no C99 style comment, checkpatch would
have cribbed

Use BITS and GENMASK here

> +
> +/* DMA channel registers offset */
> +#define CH_SAR                       0x000 // R/W Chan Source Address
> +#define CH_DAR                       0x008 // R/W Chan Destination Address
> +#define CH_BLOCK_TS          0x010 // R/W Chan Block Transfer Size
> +#define CH_CTL                       0x018 // R/W Chan Control
> +#define CH_CTL_L             0x018 // R/W Chan Control 00-31
> +#define CH_CTL_H             0x01C // R/W Chan Control 32-63
> +#define CH_CFG                       0x020 // R/W Chan Configuration
> +#define CH_CFG_L             0x020 // R/W Chan Configuration 00-31
> +#define CH_CFG_H             0x024 // R/W Chan Configuration 32-63
> +#define CH_LLP                       0x028 // R/W Chan Linked List Pointer
> +#define CH_STATUS            0x030 // R Chan Status
> +#define CH_SWHSSRC           0x038 // R/W Chan SW Handshake Source
> +#define CH_SWHSDST           0x040 // R/W Chan SW Handshake Destination
> +#define CH_BLK_TFR_RESUMEREQ 0x048 // W Chan Block Transfer Resume Req
> +#define CH_AXI_ID            0x050 // R/W Chan AXI ID
> +#define CH_AXI_QOS           0x058 // R/W Chan AXI QOS
> +#define CH_SSTAT             0x060 // R Chan Source Status
> +#define CH_DSTAT             0x068 // R Chan Destination Status
> +#define CH_SSTATAR           0x070 // R/W Chan Source Status Fetch Addr
> +#define CH_DSTATAR           0x078 // R/W Chan Destination Status Fetch Addr
> +#define CH_INTSTATUS_ENA     0x080 // R/W Chan Interrupt Status Enable
> +#define CH_INTSTATUS         0x088 // R/W Chan Interrupt Status
> +#define CH_INTSIGNAL_ENA     0x090 // R/W Chan Interrupt Signal Enable
> +#define CH_INTCLEAR          0x098 // W Chan Interrupt Clear

Same here

-- 
~Vinod

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

Reply via email to