Linked List Mode Use Case

Versal Adaptive SoC Technical Reference Manual (AM011)

Document ID
AM011
Release Date
2023-10-05
Revision
1.6 English

Linear mode is used when software can find a contiguous set of memory to accommodate all the buffer descriptors necessary (source and destination) as an array. The flowchart in the following figure captures the main steps.

Figure 1. Linked List Flowchart

Step 1

Ensure that the DMA is not in a busy state by reading the [STATE] field of CH_STATUS register and ensuring that it is not 10. If DMA is in the pause state, follow the steps to bring it out of the pause state as described in Channel Pause.

Step 2

  1. Ensure the [POINT_TYPE] bit in CH_CTRL0 register is set to 1.
  2. Allocate the source buffer descriptor objects in memory. Ensure that the buffer descriptor object address is 256-bit aligned.
  3. If the source and destination buffer are allocated in non-cacheable memory or software flushes the caches, then:
    • Set the DMA_Route [routing] bit.
    • Program the [ARCACHE] and [AWCACHE] bits in the CH_DATA_ATTR register to indicate a cacheable transaction (e.g., 1111h).
  4. Allocate the destination buffer descriptor objects in memory. Ensure that the buffer descriptor object address is 256-bit aligned. The address of the first buffer descriptor in a list is written to CH_DST_START_L and CH_DST_START_U registers.
Tip: The buffer descriptors can also be pre-allocated during initialization time.

Step 3

For each allocated source buffer descriptor object, program the following.
  1. Program the source data fragment to transfer into the source buffer descriptor object. The ADDR LSB and ADDR MSB fields are programmed.
  2. Program the size of each source data fragment to transfer into the source buffer descriptor object. The size field is programmed.
  3. Set the coherency bit if the source data buffer uses the FPD memory coherent interconnect hardware. Set the ARCACHE field in the CH_DATA_ATTR register to indicate a cacheable transaction with a value such as 1111b.
  4. Set the DSCR element type to 0.
  5. Set the INTR field if an interrupt is required after the data is read for transfer. Typically, this can be set for the buffer descriptor object corresponding to the last source data fragment. Setting the last source descriptor for interrupt reduces the number of interrupts received.
  6. The non-final buffer descriptor command field can be set to 00 for the next descriptor valid. For the final buffer descriptor, set the command field to 10 for STOP after completing this descriptor.
    Tip: If desired, set 01 to pause after completing the descriptor to put the DMA in a paused state after completing the final buffer descriptor. The steps to bring a channel out of pause into a enabled/disabled state are described in Channel Pause.
  7. Program the NEXT ADDR LSB and NEXT ADDR MSB to point to the next source buffer descriptor. If this is the last buffer descriptor in a linked list, these fields must be null.

Step 4

For each allocated destination buffer descriptor object, program the following.
  1. Program the destination data fragment to transfer into the destination buffer descriptor object. The ADDR LSB and ADDR MSB fields are programmed.
  2. Program the size of each destination data fragment to transfer into each respective destination buffer descriptor. The size field is programmed.
  3. If the source and destination buffer are allocated in non-cacheable memory or software flushes the caches, then:
    • Set the DMA_Route [routing] bit.
    • Program the [ARCACHE] and [AWCACHE] bits in the CH_DATA_ATTR register to indicate a cacheable transaction (e.g., 1111h).
  4. Set the DSCR element type to 0.
  5. Setting the last source descriptor for interrupt reduces the number of interrupts received. Set the INTR field if an interrupt is required after the data is read for a transfer. Typically, this is set for the buffer descriptor corresponding to the last source data fragment. Setting the last destination descriptor for interrupt reduces the number of interrupts received.
  6. The non-final buffer descriptor command field can be set to 00 for the next descriptor valid. For the final buffer descriptor, set the command field to 10 for STOP after completing this descriptor.
    Tip: If desired, set 01 to pause after completing the descriptor to put the DMA in a paused state after completing the final buffer descriptor. The steps to bring a channel out of pause into a enabled/disabled state are described in Channel Pause.
  7. Program the NEXT ADDR LSB and NEXT ADDR MSB to point to the next destination buffer descriptor. If this is the last buffer descriptor in a linked list, these fields must be null.

Step 5

Enable the DMA channel by writing into the control register CH_CTRL2 . This initiates the DMA data transfer.

Step 6

Upon transfer completion, the DMA channel provides interrupts to the processor depending on how the INTR field of the buffer descriptors are set. For information on handling interrupts, see Interrupt Handling.

Software can use CH_IRQ_DST_ACCT and CH_IRQ_SRC_ACCT registers to decipher the number of processed buffer descriptors on the source and destination sides. Software can internally maintain counters of both the number of source and destination buffer descriptors configured for the data transfer. Upon updating the registers with an equal count, software can infer that the data transfer is complete. Software should count only those descriptors for which interrupts are enabled.

Step 7

After the DMA transfers are done, disable the DMA channel. See Channel Disabled for more information.