PebbleOS v4.43.0-67-g6ab408441
Loading...
Searching...
No Matches

DMA controller class. More...

Modules

 SF32LB52 DMAC
 DMA controller of the SF32LB52 HPSYS (DMAC1).
 

Data Structures

struct  pbl_dma_slave_config
 Peripheral side of a channel. More...
 
struct  pbl_dma_chan
 A channel, as used by a consumer. More...
 
struct  pbl_dma_controller_ops
 DMA controller driver operations. More...
 
struct  pbl_dma_chan_state
 Runtime state of a channel. More...
 
struct  pbl_dma_controller
 A DMA controller. More...
 

Macros

#define PBL_DMA_CHAN(_ctrl, _channel, _request, _config)    {.ctrl = (_ctrl), .channel = (_channel), .request = (_request), .config = (_config)}
 Initializer for a struct pbl_dma_chan.
 
#define PBL_DMA_CONTROLLER_STATE_DEFINE(sym, _num_channels)
 Define the class state of DMA controller sym, for the driver's define macro.
 
#define PBL_DMA_CONTROLLER_INIT(sym, _name, _init, _ops)
 Initializer for the struct pbl_dma_controller of controller sym.
 

Typedefs

typedef void(* pbl_dma_callback_t) (void *arg, int status)
 Transfer end callback, called from interrupt context.
 

Enumerations

enum  pbl_dma_dir { PBL_DMA_MEM_TO_DEV , PBL_DMA_DEV_TO_MEM }
 Transfer direction. More...
 
enum  pbl_dma_slave_buswidth { PBL_DMA_SLAVE_BUSWIDTH_1_BYTE = 1 , PBL_DMA_SLAVE_BUSWIDTH_2_BYTES = 2 , PBL_DMA_SLAVE_BUSWIDTH_4_BYTES = 4 }
 Peripheral register width, in bytes. More...
 

Functions

int pbl_dma_slave_config (const struct pbl_dma_chan *chan, const struct pbl_dma_slave_config *cfg)
 Set the peripheral side of a stopped channel up.
 
int pbl_dma_prep_slave_single (const struct pbl_dma_chan *chan, void *buf, size_t len, enum pbl_dma_dir dir, pbl_dma_callback_t callback, void *arg)
 Start a transfer between a buffer and the peripheral.
 
int pbl_dma_terminate (const struct pbl_dma_chan *chan)
 Stop a channel.
 
int pbl_dma_tx_status (const struct pbl_dma_chan *chan, size_t *residue)
 Read the bytes left of a channel's transfer.
 
void pbl_dma_complete (const struct pbl_dma_controller *ctrl, uint8_t channel, int status)
 Report the end of a channel's transfer, calling its callback.
 

Variables

const struct pbl_device_class pbl_dma_class
 Class of the DMA controllers.
 

Detailed Description

DMA controller class.

A reduced Linux dmaengine for peripheral (slave) transfers. A DMA controller is a struct pbl_dma_controller device with numbered channels. A consumer holds a struct pbl_dma_chan, what a devicetree dmas entry describes: controller, channel, request line of the peripheral and controller-specific configuration such as the priority. It sets the peripheral side of the channel up once, then starts one transfer at a time on a memory buffer:

static const struct pbl_dma_chan s_rx =
const struct pbl_dma_slave_config cfg = {
.src_addr = fifo_addr,
.src_addr_width = PBL_DMA_SLAVE_BUSWIDTH_1_BYTE,
};
ret = pbl_dma_slave_config(&s_rx, &cfg);
ret = pbl_dma_prep_slave_single(&s_rx, buf, len, PBL_DMA_DEV_TO_MEM, nullptr, nullptr);
...
ret = pbl_dma_terminate(&s_rx);
#define SF32LB52_DMA_PL_HIGH
High priority.
Definition sf32lb52.h:40
#define SF32LB52_DMAC1
HPSYS DMA controller.
Definition sf32lb52.h:111
#define SF32LB52_DMA_REQ_I2C2
Definition sf32lb52.h:71
uintptr_t src_addr
Peripheral register read from, for PBL_DMA_DEV_TO_MEM transfers.
Definition dma.h:71
A channel, as used by a consumer.
Definition dma.h:89
Peripheral side of a channel.
Definition dma.h:69
int pbl_dma_prep_slave_single(const struct pbl_dma_chan *chan, void *buf, size_t len, enum pbl_dma_dir dir, pbl_dma_callback_t callback, void *arg)
Start a transfer between a buffer and the peripheral.
#define PBL_DMA_CHAN(_ctrl, _channel, _request, _config)
Initializer for a struct pbl_dma_chan.
Definition dma.h:108
int pbl_dma_terminate(const struct pbl_dma_chan *chan)
Stop a channel.
@ PBL_DMA_SLAVE_BUSWIDTH_1_BYTE
1 byte.
Definition dma.h:61
@ PBL_DMA_DEV_TO_MEM
Peripheral to memory.
Definition dma.h:55

Unlike dmaengine there is no descriptor queue: preparing a transfer starts it, and a channel runs one transfer at a time. The memory side uses the peripheral's bus width, so lengths are a multiple of it. Buffers must be reachable by the controller; cache maintenance is up to the consumer. Calls may be made from interrupt context; a channel belongs to one consumer.


Data Structure Documentation

◆ pbl_dma_slave_config

struct pbl_dma_slave_config

Peripheral side of a channel.

Data Fields
uintptr_t dst_addr Peripheral register written to, for PBL_DMA_MEM_TO_DEV transfers.
enum pbl_dma_slave_buswidth dst_addr_width Width of dst_addr.
uintptr_t src_addr Peripheral register read from, for PBL_DMA_DEV_TO_MEM transfers.
enum pbl_dma_slave_buswidth src_addr_width Width of src_addr.

◆ pbl_dma_chan

struct pbl_dma_chan

A channel, as used by a consumer.

Data Fields
uint8_t channel Channel number, from 0.
uint32_t config Controller-specific configuration, from the controller's header.
const struct pbl_dma_controller * ctrl Controller.
uint8_t request Request line of the peripheral, from the controller's header.

◆ pbl_dma_chan_state

struct pbl_dma_chan_state

Runtime state of a channel.

Data Fields
void * arg Callback argument.
pbl_dma_callback_t callback Transfer end callback, or NULL.
struct pbl_dma_slave_config cfg Peripheral side, from pbl_dma_slave_config().

◆ pbl_dma_controller

struct pbl_dma_controller

A DMA controller.

Data Fields
struct pbl_dma_chan_state * chans State of each channel.
struct pbl_device dev Device.
uint8_t num_channels Number of channels.
const struct pbl_dma_controller_ops * ops Driver operations.

Macro Definition Documentation

◆ PBL_DMA_CHAN

#define PBL_DMA_CHAN (   _ctrl,
  _channel,
  _request,
  _config 
)     {.ctrl = (_ctrl), .channel = (_channel), .request = (_request), .config = (_config)}

Initializer for a struct pbl_dma_chan.

Parameters
_ctrlController.
_channelChannel number, from 0.
_requestRequest line of the peripheral.
_configController-specific configuration.

◆ PBL_DMA_CONTROLLER_INIT

#define PBL_DMA_CONTROLLER_INIT (   sym,
  _name,
  _init,
  _ops 
)
Value:
{ \
.dev = PBL_DEVICE_INIT_CLASS(sym, _name, _init, nullptr, nullptr, &pbl_dma_class), \
.ops = (_ops), \
.chans = sym##_dma_chans, \
.num_channels = sizeof(sym##_dma_chans) / sizeof(sym##_dma_chans[0]), \
}
#define PBL_DEVICE_INIT_CLASS(sym, _name, _init, _parent, _deps, _cls)
Initializer for the struct pbl_device of device instance sym, in class _cls.
Definition device.h:123
const struct pbl_device_class pbl_dma_class
Class of the DMA controllers.

Initializer for the struct pbl_dma_controller of controller sym.

Parameters
symSymbol of the controller instance, with its state defined by PBL_DMA_CONTROLLER_STATE_DEFINE().
_nameName.
_initDevice init function, or NULL.
_opsDriver operations.

◆ PBL_DMA_CONTROLLER_STATE_DEFINE

#define PBL_DMA_CONTROLLER_STATE_DEFINE (   sym,
  _num_channels 
)
Value:
static struct pbl_dma_chan_state sym##_dma_chans[_num_channels]
#define PBL_DEVICE_STATE_DEFINE(sym)
Define the runtime state of device instance sym.
Definition device.h:109
Runtime state of a channel.
Definition dma.h:126

Define the class state of DMA controller sym, for the driver's define macro.

Parameters
symSymbol of the controller instance.
_num_channelsNumber of channels.

Typedef Documentation

◆ pbl_dma_callback_t

typedef void(* pbl_dma_callback_t) (void *arg, int status)

Transfer end callback, called from interrupt context.

Parameters
argCallback argument.
status0 when the transfer completed, or a negative errno.

Enumeration Type Documentation

◆ pbl_dma_dir

Transfer direction.

Enumerator
PBL_DMA_MEM_TO_DEV 

Memory to the peripheral.

PBL_DMA_DEV_TO_MEM 

Peripheral to memory.

◆ pbl_dma_slave_buswidth

Peripheral register width, in bytes.

Enumerator
PBL_DMA_SLAVE_BUSWIDTH_1_BYTE 

1 byte.

PBL_DMA_SLAVE_BUSWIDTH_2_BYTES 

2 bytes.

PBL_DMA_SLAVE_BUSWIDTH_4_BYTES 

4 bytes.

Function Documentation

◆ pbl_dma_complete()

void pbl_dma_complete ( const struct pbl_dma_controller *  ctrl,
uint8_t  channel,
int  status 
)

Report the end of a channel's transfer, calling its callback.

Called by controller drivers from their interrupt handlers.

Parameters
ctrlController.
channelChannel.
status0 when the transfer completed, or a negative errno.

◆ pbl_dma_prep_slave_single()

int pbl_dma_prep_slave_single ( const struct pbl_dma_chan *  chan,
void *  buf,
size_t  len,
enum pbl_dma_dir  dir,
pbl_dma_callback_t  callback,
void *  arg 
)

Start a transfer between a buffer and the peripheral.

Parameters
chanChannel, set up with pbl_dma_slave_config().
bufBuffer.
lenLength in bytes, a multiple of the peripheral's bus width.
dirDirection.
callbackCalled when the transfer ends, or NULL.
argCallback argument.
Returns
0, -EBUSY if a transfer is running, -EINVAL for a transfer the controller cannot do, or another negative errno.

◆ pbl_dma_slave_config()

int pbl_dma_slave_config ( const struct pbl_dma_chan *  chan,
const struct pbl_dma_slave_config *  cfg 
)

Set the peripheral side of a stopped channel up.

Parameters
chanChannel.
cfgPeripheral side.
Returns
0, -EINVAL for a configuration the controller cannot do, or another negative errno.

◆ pbl_dma_terminate()

int pbl_dma_terminate ( const struct pbl_dma_chan *  chan)

Stop a channel.

No callback is called for the transfer it stops.

Parameters
chanChannel.
Returns
0 or a negative errno.

◆ pbl_dma_tx_status()

int pbl_dma_tx_status ( const struct pbl_dma_chan *  chan,
size_t *  residue 
)

Read the bytes left of a channel's transfer.

Parameters
chanChannel.
[out]residueBytes not transferred yet.
Returns
0 or a negative errno.

Variable Documentation

◆ pbl_dma_class

const struct pbl_device_class pbl_dma_class
extern

Class of the DMA controllers.