forked from hzeller/spixels
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrpi-dma.h
92 lines (80 loc) · 3.38 KB
/
rpi-dma.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
// SPI Pixels - Control SPI LED strips (spixels)
// Copyright (C) 2016 Henner Zeller <h.zeller@acm.org>
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
// BCM2385 ARM Peripherals 4.2.1.2
#define DMA_CB_TI_NO_WIDE_BURSTS (1<<26)
#define DMA_CB_TI_SRC_INC (1<<8)
#define DMA_CB_TI_DEST_INC (1<<4)
#define DMA_CB_TI_TDMODE (1<<1)
#define DMA_CS_RESET (1<<31)
#define DMA_CS_ABORT (1<<30)
#define DMA_CS_DISDEBUG (1<<28)
#define DMA_CS_ERROR (1<<8)
#define DMA_CS_END (1<<1)
#define DMA_CS_ACTIVE (1<<0)
#define DMA_CB_TXFR_LEN_YLENGTH(y) (((y-1)&0x4fff) << 16)
#define DMA_CB_TXFR_LEN_XLENGTH(x) ((x)&0xffff)
#define DMA_CB_STRIDE_D_STRIDE(x) (((x)&0xffff) << 16)
#define DMA_CB_STRIDE_S_STRIDE(x) ((x)&0xffff)
#define DMA_CS_PRIORITY(x) ((x)&0xf << 16)
#define DMA_CS_PANIC_PRIORITY(x) ((x)&0xf << 20)
// Documentation: BCM2835 ARM Peripherals @4.2.1.2
struct dma_channel_header {
uint32_t cs; // control and status.
uint32_t cblock; // control block address.
};
// @4.2.1.1
struct dma_cb { // 32 bytes.
uint32_t info; // transfer information.
uint32_t src; // physical source address.
uint32_t dst; // physical destination address.
uint32_t length; // transfer length.
uint32_t stride; // stride mode.
uint32_t next; // next control block; Physical address. 32 byte aligned.
uint32_t pad[2];
};
// A memory block that represents memory that is allocated in physical
// memory and locked there so that it is not swapped out.
// It is not backed by any L1 or L2 cache, so writing to it will directly
// modify the physical memory (and it is slower of course to do so).
// This is memory needed with DMA applications so that we can write through
// with the CPU and have the DMA controller 'see' the data.
// The UncachedMemBlock_{alloc,free,to_physical}
// functions are meant to operate on these.
struct UncachedMemBlock {
void *mem; // User visible value: the memory to use.
//-- Internal representation.
uint32_t bus_addr;
uint32_t mem_handle;
size_t size;
};
// Allocate a block of memory of the given size (which is rounded up to the next
// full page). The memory will be aligned on a page boundary and zeroed out.
struct UncachedMemBlock UncachedMemBlock_alloc(size_t size);
// Free block previously allocated with UncachedMemBlock_alloc()
void UncachedMemBlock_free(struct UncachedMemBlock *block);
// Given a pointer to memory that is in the allocated block, return the
// physical bus addresse needed by DMA operations.
uintptr_t UncachedMemBlock_to_physical(const struct UncachedMemBlock *blk,
void *p);
#ifdef __cplusplus
}
#endif