只有 3 个可写的寄存器。
DMA Channel 0 is located at the address of 0x7E007000, Channel 1 at 0x7E007100, Channel
2 at 0x7E007200 and so on. Thus adjacent DMA Channels are offset by 0x100.
DMA Channel 15 however, is physically removed from the other DMA Channels and so has
a different address base of 0x7EE05000.
Base 地址偏移 8 位:
/* valid only for channels 0 - 14, 15 has its own base address */
#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */
#define BCM2708_DMA_CHANIO(dma_base, n) \
((
void
__iomem *)((
char
*)(dma_base)+BCM2708_DMA_CHAN(n)))
static
struct
resource bcm2708_dmaman_resources[] = {
{
.start = DMA_BASE,
.end = DMA_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
}
};
static
struct
platform_device bcm2708_dmaman_device = {
.name = BCM_DMAMAN_DRIVER_NAME,
.id = 0,
/* first bcm2708_dma */
.resource = bcm2708_dmaman_resources,
.num_resources = ARRAY_SIZE(bcm2708_dmaman_resources),
};
#define BCM2708_PERI_BASE 0x20000000
#define IC0_BASE (BCM2708_PERI_BASE + 0x2000)
#define ST_BASE (BCM2708_PERI_BASE + 0x3000) /* System Timer */
#define MPHI_BASE (BCM2708_PERI_BASE + 0x6000) /* Message -based Parallel Host Interface */
#define DMA_BASE (BCM2708_PERI_BASE + 0x7000) /* DMA controller */
启动 DMA
Each DMA channel operates by loading a Control Block (CB) data structure from memory
into internal registers. The Control Block defines the required DMA operation. Each Control
Block can point to a further Control Block to be loaded and executed once the operation
described in the current Control Block has completed. In this way a linked list of Control
Blocks can be constructed in order to execute a sequence of DMA operations without
software intervention.
写入 CB 数据到 CB 地址寄存器,并设置 active 位就会启动对应的 DMA
extern
void
bcm_dma_start(
void
__iomem *dma_chan_base, dma_addr_t control_block)
{
dsb();
/* ARM data synchronization (push) operation */
writel(control_block, dma_chan_base + BCM2708_DMA_ADDR);
writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS);
}