Documentation/arch/arm/stm32/stm32-dma-mdma-chaining.rst

Source file repositories/reference/linux-study-clean/Documentation/arch/arm/stm32/stm32-dma-mdma-chaining.rst

File Facts

System
Linux kernel
Corpus path
Documentation/arch/arm/stm32/stm32-dma-mdma-chaining.rst
Extension
.rst
Size
18565 bytes
Lines
415
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

for_each_sg(new_dma_sgt.sgl, s, new_dma_sgt.nents, i) {
              _sgl = sgl;
              sg_dma_len(s) = min(sg_dma_len(_sgl), sram_period);
              /* Targets the beginning = first half of the sram_buf */
              s->dma_address = sram_buf;
              /*
                * Targets the second half of the sram_buf
                * for odd indexes of the item of the sg_list
                */
              if (i & 1)
                      s->dma_address += sram_period;
      }

      /* Create sg table for STM32 MDMA channel */
      ret = sg_alloc_table(&new_mdma_sgt, new_nents, GFP_ATOMIC);
      if (ret)
              dev_err(dev, "MDMA sg_table alloc failed\n");

      _sgl = sgl;
      len = sg_dma_len(sgl);
      ddr_dma_buf = sg_dma_address(sgl);
      for_each_sg(mdma_sgt.sgl, s, mdma_sgt.nents, i) {
              size_t bytes = min_t(size_t, len, sram_period);

              sg_dma_len(s) = bytes;
              sg_dma_address(s) = ddr_dma_buf;
              len -= bytes;

              if (!len && sg_next(_sgl)) {
                      _sgl = sg_next(_sgl);
                      len = sg_dma_len(_sgl);
                      ddr_dma_buf = sg_dma_address(_sgl);
              } else {
                      ddr_dma_buf += bytes;
              }
      }

    Don't forget to release these new sg_tables after getting the descriptors
    with dmaengine_prep_slave_sg().

  **1. Set controller specific parameters**

    First, use dmaengine_slave_config() with a struct dma_slave_config to
    configure STM32 DMA channel. You just have to take care of DMA addresses,
    the memory address (depending on the transfer direction) must point on your
    SRAM buffer, and set (struct dma_slave_config).peripheral_size != 0.

    STM32 DMA driver will check (struct dma_slave_config).peripheral_size to
    determine if chaining is being used or not. If it is used, then STM32 DMA
    driver fills (struct dma_slave_config).peripheral_config with an array of
    three u32 : the first one containing STM32 DMAMUX channel ID, the second one
    the channel interrupt flag clear register address, and the third one the
    channel Transfer Complete flag mask.

    Then, use dmaengine_slave_config with another struct dma_slave_config to
    configure STM32 MDMA channel. Take care of DMA addresses, the device address
    (depending on the transfer direction) must point on your SRAM buffer, and
    the memory address must point to the buffer originally used for "classic"
    DMA operation. Use the previous (struct dma_slave_config).peripheral_size
    and .peripheral_config that have been updated by STM32 DMA driver, to set
    (struct dma_slave_config).peripheral_size and .peripheral_config of the
    struct dma_slave_config to configure STM32 MDMA channel.
    ::

      struct dma_slave_config dma_conf;
      struct dma_slave_config mdma_conf;

      memset(&dma_conf, 0, sizeof(dma_conf));
      [...]
      config.direction = DMA_DEV_TO_MEM;

Annotation

Implementation Notes