lkml.org 
[lkml]   [2023]   [May]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v1 10/12] dmaengine: fsl-edma: move tcd into struct fsl_dma_chan
    Date
    Relocates the tcd into the fsl_dma_chan structure. This adjustment reduces
    the need to reference back to fsl_edma_engine, paving the way for EDMA V3
    support.

    Unified the edma_writel and edma_writew functions for accessing TCD
    (Transfer Control Descriptor) registers. A new macro is added that can
    automatically detect whether a 32-bit or 16-bit access should be used
    based on the structure field definition. This provide better support
    64-bit TCD with future v5 version.

    Signed-off-by: Frank Li <Frank.Li@nxp.com>
    ---
    drivers/dma/fsl-edma-common.c | 38 +++++++++++++----------------------
    drivers/dma/fsl-edma-common.h | 22 +++++++++++++++++++-
    drivers/dma/fsl-edma-main.c | 6 ++++--
    drivers/dma/mcf-edma-main.c | 4 +++-
    4 files changed, 42 insertions(+), 28 deletions(-)

    diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
    index 659bef4a3b23..186b5c41d07f 100644
    --- a/drivers/dma/fsl-edma-common.c
    +++ b/drivers/dma/fsl-edma-common.c
    @@ -40,8 +40,6 @@
    #define EDMA64_ERRH 0x28
    #define EDMA64_ERRL 0x2c

    -#define EDMA_TCD 0x1000
    -
    void fsl_edma_tx_chan_handler(struct fsl_edma_chan *fsl_chan)
    {
    spin_lock(&fsl_chan->vchan.lock);
    @@ -285,8 +283,6 @@ static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
    struct virt_dma_desc *vdesc, bool in_progress)
    {
    struct fsl_edma_desc *edesc = fsl_chan->edesc;
    - struct edma_regs *regs = &fsl_chan->edma->regs;
    - u32 ch = fsl_chan->vchan.chan.chan_id;
    enum dma_transfer_direction dir = edesc->dirn;
    dma_addr_t cur_addr, dma_addr;
    size_t len, size;
    @@ -301,9 +297,9 @@ static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
    return len;

    if (dir == DMA_MEM_TO_DEV)
    - cur_addr = edma_readl(fsl_chan->edma, &regs->tcd[ch].saddr);
    + cur_addr = edma_read_tcdreg(fsl_chan, saddr);
    else
    - cur_addr = edma_readl(fsl_chan->edma, &regs->tcd[ch].daddr);
    + cur_addr = edma_read_tcdreg(fsl_chan, daddr);

    /* figure out the finished and calculate the residue */
    for (i = 0; i < fsl_chan->edesc->n_tcds; i++) {
    @@ -358,9 +354,6 @@ enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
    static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
    struct fsl_edma_hw_tcd *tcd)
    {
    - struct fsl_edma_engine *edma = fsl_chan->edma;
    - struct edma_regs *regs = &fsl_chan->edma->regs;
    - u32 ch = fsl_chan->vchan.chan.chan_id;
    u16 csr = 0;

    /*
    @@ -369,23 +362,22 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
    * big- or little-endian obeying the eDMA engine model endian,
    * and this is performed from specific edma_write functions
    */
    - edma_writew(edma, 0, &regs->tcd[ch].csr);
    + edma_write_tcdreg(fsl_chan, 0, csr);

    - edma_writel(edma, (s32)tcd->saddr, &regs->tcd[ch].saddr);
    - edma_writel(edma, (s32)tcd->daddr, &regs->tcd[ch].daddr);
    + edma_write_tcdreg(fsl_chan, (s32)tcd->saddr, saddr);
    + edma_write_tcdreg(fsl_chan, (s32)tcd->daddr, daddr);

    - edma_writew(edma, (s16)tcd->attr, &regs->tcd[ch].attr);
    - edma_writew(edma, tcd->soff, &regs->tcd[ch].soff);
    + edma_write_tcdreg(fsl_chan, (s16)tcd->attr, attr);
    + edma_write_tcdreg(fsl_chan, tcd->soff, soff);

    - edma_writel(edma, (s32)tcd->nbytes, &regs->tcd[ch].nbytes);
    - edma_writel(edma, (s32)tcd->slast, &regs->tcd[ch].slast);
    + edma_write_tcdreg(fsl_chan, (s32)tcd->nbytes, nbytes);
    + edma_write_tcdreg(fsl_chan, (s32)tcd->slast, slast);

    - edma_writew(edma, (s16)tcd->citer, &regs->tcd[ch].citer);
    - edma_writew(edma, (s16)tcd->biter, &regs->tcd[ch].biter);
    - edma_writew(edma, (s16)tcd->doff, &regs->tcd[ch].doff);
    + edma_write_tcdreg(fsl_chan, (s16)tcd->citer, citer);
    + edma_write_tcdreg(fsl_chan, (s16)tcd->biter, biter);
    + edma_write_tcdreg(fsl_chan, (s16)tcd->doff, doff);

    - edma_writel(edma, (s32)tcd->dlast_sga,
    - &regs->tcd[ch].dlast_sga);
    + edma_write_tcdreg(fsl_chan, (s32)tcd->dlast_sga, dlast_sga);

    if (fsl_chan->is_sw) {
    csr = le16_to_cpu(tcd->csr);
    @@ -393,7 +385,7 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
    tcd->csr = cpu_to_le16(csr);
    }

    - edma_writew(edma, (s16)tcd->csr, &regs->tcd[ch].csr);
    + edma_write_tcdreg(fsl_chan, (s16)tcd->csr, csr);
    }

    static inline
    @@ -745,7 +737,5 @@ void fsl_edma_setup_regs(struct fsl_edma_engine *edma)
    edma->regs.errh = edma->membase + EDMA64_ERRH;
    edma->regs.inth = edma->membase + EDMA64_INTH;
    }
    -
    - edma->regs.tcd = edma->membase + EDMA_TCD;
    }

    diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
    index 39b5f903ba87..0a95fd5d74f5 100644
    --- a/drivers/dma/fsl-edma-common.h
    +++ b/drivers/dma/fsl-edma-common.h
    @@ -48,6 +48,8 @@

    #define DMAMUX_NR 2

    +#define EDMA_TCD 0x1000
    +
    #define FSL_EDMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
    BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
    BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
    @@ -93,7 +95,6 @@ struct edma_regs {
    void __iomem *intl;
    void __iomem *errh;
    void __iomem *errl;
    - struct fsl_edma_hw_tcd __iomem *tcd;
    };

    struct fsl_edma_sw_tcd {
    @@ -117,6 +118,7 @@ struct fsl_edma_chan {
    u32 dma_dev_size;
    enum dma_data_direction dma_dir;
    char chan_name[32];
    + struct fsl_edma_hw_tcd __iomem *tcd;
    };

    struct fsl_edma_desc {
    @@ -160,6 +162,16 @@ struct fsl_edma_engine {
    struct fsl_edma_chan chans[];
    };

    +#define edma_read_tcdreg(chan, __name) \
    +(sizeof(chan->tcd->__name) == sizeof(u32) ? \
    + edma_readl(chan->edma, &chan->tcd->__name) : \
    + edma_readw(chan->edma, &chan->tcd->__name))
    +
    +#define edma_write_tcdreg(chan, val, __name) \
    +(sizeof(chan->tcd->__name) == sizeof(u32) ? \
    + edma_writel(chan->edma, val, &chan->tcd->__name) : \
    + edma_writew(chan->edma, val, &chan->tcd->__name))
    +
    /*
    * R/W functions for big- or little-endian registers:
    * The eDMA controller's endian is independent of the CPU core's endian.
    @@ -174,6 +186,14 @@ static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
    return ioread32(addr);
    }

    +static inline u16 edma_readw(struct fsl_edma_engine *edma, void __iomem *addr)
    +{
    + if (edma->big_endian)
    + return ioread16be(addr);
    + else
    + return ioread16(addr);
    +}
    +
    static inline void edma_writeb(struct fsl_edma_engine *edma,
    u8 val, void __iomem *addr)
    {
    diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
    index 722ebecdc894..8d1d0100f6e6 100644
    --- a/drivers/dma/fsl-edma-main.c
    +++ b/drivers/dma/fsl-edma-main.c
    @@ -312,9 +312,11 @@ static int fsl_edma_probe(struct platform_device *pdev)
    fsl_chan->idle = true;
    fsl_chan->dma_dir = DMA_NONE;
    fsl_chan->vchan.desc_free = fsl_edma_free_desc;
    + fsl_chan->tcd = fsl_edma->membase + EDMA_TCD
    + + i * sizeof(struct fsl_edma_hw_tcd);
    vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);

    - edma_writew(fsl_edma, 0x0, &regs->tcd[i].csr);
    + edma_write_tcdreg(fsl_chan, 0, csr);
    fsl_edma_chan_mux(fsl_chan, 0, false);
    }

    @@ -421,7 +423,7 @@ static int fsl_edma_resume_early(struct device *dev)
    for (i = 0; i < fsl_edma->n_chans; i++) {
    fsl_chan = &fsl_edma->chans[i];
    fsl_chan->pm_state = RUNNING;
    - edma_writew(fsl_edma, 0x0, &regs->tcd[i].csr);
    + edma_write_tcdreg(fsl_chan, 0, csr);
    if (fsl_chan->slave_id != 0)
    fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id, true);
    }
    diff --git a/drivers/dma/mcf-edma-main.c b/drivers/dma/mcf-edma-main.c
    index af1b0e8a3021..d79a04a03fda 100644
    --- a/drivers/dma/mcf-edma-main.c
    +++ b/drivers/dma/mcf-edma-main.c
    @@ -200,7 +200,9 @@ static int mcf_edma_probe(struct platform_device *pdev)
    mcf_chan->dma_dir = DMA_NONE;
    mcf_chan->vchan.desc_free = fsl_edma_free_desc;
    vchan_init(&mcf_chan->vchan, &mcf_edma->dma_dev);
    - iowrite32(0x0, &regs->tcd[i].csr);
    + mcf_chan->tcd = mcf_edma->membase + EDMA_TCD
    + + i * sizeof(struct fsl_edma_hw_tcd);
    + iowrite32(0x0, &mcf_chan->tcd->csr);
    }

    iowrite32(~0, regs->inth);
    --
    2.34.1
    \
     
     \ /
      Last update: 2023-05-26 16:40    [W:5.315 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site