linux dma的使用

发布于:2024-05-01 ⋅ 阅读:(81) ⋅ 点赞:(0)

设备树配置

驱动代码

static void bcm2835_dma_init(struct spi_master *master, struct device *dev)

{

        struct dma_slave_config slave_config;

        const __be32 *addr;

        dma_addr_t dma_reg_base;

        int ret;

        /* base address in dma-space */

        addr = of_get_address(master->dev.of_node, 0, NULL, NULL);

        dma_reg_base = be32_to_cpup(addr);

        /* get tx/rx dma */    //根据dmas 和dma-names属性

        master->dma_tx = dma_request_slave_channel(dev, "tx"); 

        master->dma_rx = dma_request_slave_channel(dev, "rx");

        ...

        /* configure DMAs tx */

        slave_config.direction = DMA_MEM_TO_DEV;

        slave_config.dst_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO);

        slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;

        ret = dmaengine_slave_config(master->dma_tx, &slave_config);

        /* configure DMAs rx */

         slave_config.direction = DMA_DEV_TO_MEM;

        slave_config.src_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO);

        slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;

        ret = dmaengine_slave_config(master->dma_rx, &slave_config);

    

        /* all went well, so set can_dma */

        master->can_dma = bcm2835_spi_can_dma;

        master->max_dma_len = 65535; /* limitation by BCM2835_SPI_DLEN */

        /* need to do TX AND RX DMA, so we need dummy buffers */

        master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;

        return;

}