23
When we’re done, it’s done! DMA Survival Guide

DMA Survival Guide

Embed Size (px)

Citation preview

Page 1: DMA Survival Guide

When we’re done, it’s done!

DMA Survival Guide

Page 2: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Ramon Fried Developer and hacker since 1983 B.sc in computer science Expertise in Embedded systems and Linux

system and kernel development. Currently Embedded Linux Team Leader in

TandemG

Page 3: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

TandemG TandemG is Israel’s leading Software, Hardware and

Systems R&D center, acting as a one-stop-shop for our range of partners, from prominent start-ups through to market leaders

In the embedded domain, TandemG tailors solutions spanning across RTOS, Embedded Linux, low-level Android and DSP.

For the second year in a row, TandemG has been selected to Delloite’s Israel Technology Fast50 list in the 23rd place

Visit us at www.tandemG.com, for additional details.

Page 4: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Agenda What is DMA DMA Buffer allocation

— Coherent— Streaming

Scatter Gather mapping DMA pools DMA Triggering

— PCI— dmaengine

Page 5: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

What is DMA Direct memory access Feature of computer systems that allows

certain hardware subsystems to access main system memory (RAM), independent of the central processing unit (CPU).

CPU can be notified on the end of operation by IRQ.

Page 6: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

What is DMA

Photo from: http://encyclopedia2.thefreedictionary.com/DMA

Page 7: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

DMA Buffer allocation DMA controller works on physical

addresses Physical memory needs to be accessible

by DMA controller Memory must be continuous

Page 8: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

DMA Buffer allocation Coherent DMA mapping

— Usually long lasting. — Can be accessed by both ends. — No-caching *— At least page sized.

Streaming DMA mapping— Usually singly used and freed.— Architecture/Platform optimized.— direction must be defined explicitly.

Page 9: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

DMA access mask#include <linux/dma-mapping.h>

int dma_set_mask_and_coherent(struct device *dev, u64 mask);

int dma_set_mask (struct device *dev, u64 mask);

int dma_set_coherent_mask(struct device *dev, u64 mask);

Page 10: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Coherent DMA mapping#include <linux/dma-mapping.h>

void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag);

void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle);

Page 11: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Streaming DMA mapping#include <linux/dma-mapping.h>

dma_addr_t dma_map_single(struct device *dev, void *ptr,size_t size,

enum dma_data_direction dir);

void dma_unmap_single(struct device *dev, dma_addr_t addr,

size_t size,

enum dma_data_direction dir);

Page 12: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Streaming DMA mapping (cont’d) enum dma_data_direction

— DMA_TO_DEVICE— DMA_FROM_DEVICE— DMA_BIDIRECTIONAL

Page 13: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Streaming DMA usage Buffer Ownership

— Buffer is owned by the device.— Altering the buffer can be done only after

acquiring ownership dma_sync_single_for_cpu()

— After altering the buffer, the ownership needs to be returned to the device. dma_sync_single_for_device()

Page 14: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Scatter gather buffers

Special type of streaming DMA writev, readv, clustered buffers (YUV

plannar, non continuous memory, etc.)

Page 15: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Scatter/Gather API#include linux/dma-mapping.h

int dma_map_sg( struct device *dev,struct scatterlist *sg,int nents, enum dma_data_direction

dir);

void dma_unmap_sg(struct device *dev, struct scatterlist

*list,int nents, enum dma_data_direction

dir);

Page 16: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Don’t forget to sync#include linux/dma-mapping.h

void dma_sync_sg_for_cpu(struct device *dev,

struct scatterlist *sg,int nelems,enum dma_data_direction dir);

void dma_sync_sg_for_device(struct device *dev,

struct scatterlist *sg,int nelems,enum dma_data_direction dir);

Page 17: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

DMA Pools DMA Pools

— Coherent— Used to allocate buffers smaller than a page.— dma_pool_create()— dma_pool_destroy()— dma_pool_alloc()— dma_pool_free()

Page 18: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Start the DMA operation

Page 19: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

Triggering the DMA operation PCI dmaengine

Page 20: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

PCI Wrappers PCI wrappers

— pci_alloc_consistent()— pci_free_consistent()— pci_set_dma_mask()— pci_pool_create()— …

Page 21: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

PCI DMA transaction exampledma_addr_t bus_addr;

bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count, DMA_TO_DEVICE);

writeb(dev->registers.command, DAD_CMD_DISABLEDMA);

writeb(dev->registers.command, DAD_CMD_WR);

writel(dev->registers.addr, cpu_to_le32(bus_addr));

writel(dev->registers.len, cpu_to_le32(count));

writeb(dev->registers.command, DAD_CMD_ENABLEDMA);

Page 22: DMA Survival Guide

Property of Tandem Group

When we’re done, it’s done!

DMA Engine Subsystem to handle memory-to-device

transfers Exists since 2.6.18 (2006) Code in “drivers/dma” Documentation in “dmaengine/*”

Poorly documented

Page 23: DMA Survival Guide

THANK YOU!