Tux
Communication
Mailing lists
Documentation
User Manual
Target board info.
Target chip info.
Support
Linux support
Bugzilla
Downloads
STLinux
Updates
Search
Google


The web
stlinux.com
Distribution Guide
Device drivers
STMicroelectronics DMA API
ST Logo
Previous   Contents   Next

Please note there are wholly different API's available for the LDDE 2.2 and the STLinux2.0 distributions. The information on this page relates solely to API available in LDDE2.2.

Try here for the legacy API documentation relating to STLinux2.0.

Index

Introduction

The STMicroelectronics DMA API provides a kernel-space API to access the functionality of the FlexibleDMA engine, and also provides a generic mode capable of standard memory-memory moves that is compatible with the original SHDMA-API. In the STMicroelectronics specific mode, support is given to paced transfers to and from peripherals. Additionally Free-running transfers from mem-mem and scatter-gather to and from memory is possible. No explicit support is provided for pacing a scatter-gather transfer either to of from a peripheral. Additionally no support is provided for PES scanning or SPDIF compressed audio formatting which has native support in the Firmware of the STB710x series CPU's. Though generic SPDIF transfers (PCM) are supported.

Channels are still reserved by drivers in a similar method to the legacy system:- a request/free pair will ensure that a given channel is reserved for use by the requestee until a free calls returns it to the available pool. However in addition to reserving channels specifically by number, or by the next available channel, it is now possible to reserve by channel capability. Some channels in the FDMA FW have been optimized for particular application requirements, such as memory bandwidth and buffer space.

For those familiar with the previous API, the architecture of configuring and executing a transfer has changed considerably, so here follows a brief explanation:

Configuring a transfer is now an independent operation from any particular channel, transfer descriptors can be configured asynchronously from execution of a transfer. So transfers can be configured / reconfigured whilst the dma channel is active. Only when the transfer is initiated is it tied to a particular channel, this association persists until the entire transfer ( either single node or linked list)is completed. This transfer can then be re-associated with the same, or any other channel for the next execution.

This allows a device driver to pre-allocate a number of transfers of different configurations and utilize them as required. Memory for the fdma descriptor is allocated as the node is compiled, and is associated with the transfer descriptor at that time, and persists until the user explicitly destroys the descriptor they have allocated.

This allows compiled transfers to be re-compiled with new parameters. Within certain limitations - parameters such as size and address can be modified, but not those which change the mode of the transfer. Thus the burden of managing the descriptor memory is shifted into the user domain to provide greater flexibility.

Nodes of heterogenous types can now be linked in an arbitrary way providing a more flexible model. As an example you would be able to configure a transfer that would scatter-gather memory from user-space into a kernel buffer, then link that transfer to a paced one which fed a particular peripheral. Both open ended and circular linked lists are available, although circular lists can only be linked back to the first node in a chain, and only the last node in the chain is capable of linking back.

Configuring the DMA system for your driver

To enable the STM_DMA API and driver two options must be selected, both of these are enabled in the default configuration. Bring up the Linux Kernel Configuration (Try Kernel Configuration) and enable:-

  • Device Drivers ---> STM Specific Devices --> STMicroelectronics DMA API
  • Device Drivers ---> STM Specific Devices -- > Lowest STM FDMAC Channel
  • Device Drivers ---> STM Specific Devices -- > Highest STM FDMAC Channel

The latter two options should reflect the channel mapping you wish to use. The default configuration is to allocate all channels provided by the SoC.

Additionally debugging prints can be enabled which print messages to the serial console in case of error. The default state is disabled This functionality is enabled by: -

  • Device Drivers ---> STM Specific Devices -- > STMicroelectronics DMA Debug

It is now possible to have several DMAC's installed on top of a single DMA engine, such that they share the SoC's DMA channels between them. As such when the STM_DMA is enabled it is necessary to specify the range of channels which are to be allocated to the native Linux driver. These can be any number of channels >= 0 and =< the total available, which for the 710x is 16, please refer to the datasheets of particular SoC's for the number of channels provided by the on-chip FDMA for that part ( N.B. all 710x series have 16 channels). The default is to allocate all channels to the native DMA driver. Please note however that channels assigned to the STM driver must be in a contiguous range. Allocating 0 channels will cause the controller to be disabled.

In order to make the API visible from your driver, three headers must be included

  • /asm/dma.h
  • /linux/stm/stm-dma.h
and
  • /linux/stm/"platform_specific_dma_header" at this time the only available is 710x_fdma.h which supports the 7100 and 7109(exc cut <=1 of 7109).

This makes API functions available from in-kernel drivers and kernel modules.

As a general note, the explanations of the functions given below lack information about behaviour on error and return values. It can be assumed that all operations will return zero success, and in the case of error a -STDERR value, which are available from asm-generic/errno.h. Descriptions of exact behaviour and return codes for the functions can be found in linux/stm/stm-dma.h and asm/dma.h.

Configuring a Transfer

The initial operation is to declare a new transfer descriptor, and fill it with the mode parameters for your transfer. This is done via the declare_dma_parms() helper function. At this stage it is necessary to associate this transfer to a particular DMA controller, as there may be more than one available in the system. Note that attempting to recompile a transfer with different values than those given in declare_dma_params() without a call to dma_free_descriptor() is an undefined operation.

The declare function takes 6 parameters as below.

	
	static inline void declare_dma_parms(	
					struct stm_dma_params * p,
					unsigned long mode,
					unsigned long list_type,
					unsigned long context,
					unsigned long blocking,
					char * name)

	p 		is a pointer to an empty stm_dma_params structure, 
			though it need not be initialized.

	mode 		is the operating mode of the transfer, which may be one of 
								MODE_FREERUNNING
								MODE_PACED
								MODE_SH_COMPATIBILITY 
								MODE_SRC_SCATTER 
								MODE_DST_SCATTER
		

	list_type - specifies whether the last node, or only node in the singleton case 
			links back to the first in the list, creating a continuously iterating 
			transfer, valid values are STM_DMA_LIST_CIRC or STM_DMA_LIST_OPEN.


	context -	specifies whether the function which dma_compile_params() is called 
			from is executing in task or interrupt context,	valid values are 
			STM_DMA_SETUP_CONTEXT_TASK or STM_DMA_SETUP_CONTEXT_ISR.


	blocking -  specifies if upon transfer start, in the case that the selected 
			channel is busy, whether the dma_xfer_list() function will 
			sleep until the channel becomes free or return immediately 
			with error (-BUSY). It should be noted that blocking cannot 
			be used from interrupt context.

	name -	is the string associated with the FDMA controller, and must 
			match the name registered by the DMAC in question.	For the 
			STM_DMA controller the only valid string is  exported from 
			linux/stm/smt-dma.h as STM_DMAC_ID. Max 30 chars.

Next we must specify our transfer specific params and configuration. This is done with a number of inline functions.

	
	static inline void dma_parms_addrs(	
					struct stm_dma_params *p,
					unsigned long src,
					unsigned long dst,
					unsigned long bytes)

Is essential to all transfers, and the parameters represent source(src) and destination(dst) address', which must be bus address' pointing to physically contiguous, uncached regions. The bytes parameter is the total number of bytes to transfer. The transfer will be more efficient if these buffers are aligned on a 32 byte boundary - but this is not mandatory.

The other functions required are specific to the transfer mode, for example if configuring a freerunning 0x1 move you would use dma_parms_DIM_0_x_1() and dma_parms_paced() for a paced transfer etc. And a complete list pulled from stm-dma.h is below.

	
A breakdown of parameters for these 
functions are as follows:

	p		-  	pointer to the stm_dma_params structure
	srcsize -  	size in bytes of the src location
	dstsize -  	size in bytes of dst location
	dstride -  	the stride between lines in the dst buffer in a 2D transfer
	sstride -  	the stride between lines in the src buffer in a 2D transfer
	sg	-  	pointer to a populated struct scatterlist pointer
			to describe the sg list
	nents	-  	number of entries in the scatterlist


	static inline void dma_parms_DIM_0_x_1(	
							struct stm_dma_params *p,
							unsigned long srcsize)
	
	static inline void dma_parms_DIM_0_x_0(	
							struct stm_dma_params *p,
							unsigned long srcsize)
	
	static inline void dma_parms_DIM_0_x_1(	
							struct stm_dma_params *p,
							unsigned long srcsize)
	
	static inline void dma_parms_DIM_0_x_2(	
							struct stm_dma_params *p,
							unsigned long srcsize,
							unsigned long dstride)
	
	static inline void dma_parms_DIM_1_x_0(	
							struct stm_dma_params *p,
							unsigned long srcsize)
	
	static inline void dma_parms_DIM_1_x_1(	
							struct stm_dma_params *p,
							unsigned long srcsize)
	
	static inline void dma_parms_DIM_1_x_2(	
							struct stm_dma_params *p,
							unsigned long dstsize,
							unsigned long dstride)
	
	static inline void dma_parms_DIM_2_x_0(	
							struct stm_dma_params *p,
							unsigned long srcsize,
							unsigned long sstride)
	
	static inline void dma_parms_DIM_2_x_1(	
							struct stm_dma_params *p,
							unsigned long srcsize,
							unsigned long sstride)
	
	static inline  void dma_parms_sg(	
							struct stm_dma_params *p,
							struct scatterlist * sg,
							int nents)

If you wish to specify a bespoke configuration the following can be used

	static inline void dma_parms_manual_dim_parms(	
						struct stm_dma_params *p,
						unsigned long length,
						unsigned long sstride,
						unsigned long dstride,
						unsigned long dim)
where

	Length - 	length of a line in 2D transfer in bytes, and  0  if the transfer is not 2D
	sstride - 	the stride between lines in the src buffer in a 2D transfer, 0 if not 2d
	dstride - 	the stride between lines in the dst buffer in a 2D transfer, 0 if not 2d
	dim - 	dimensionality specifier - may be 	
						DIM_0_x_0
						DIM_0_x_1
						DIM_0_x_2
						DIM_1_x_0
						DIM_1_x_1
						DIM_1_x_2
						DIM_2_x_0
						DIM_2_x_1
						DIM_2_x_2
						DIM_REQ_SEL -  for paced transfers

	

There are also a number of optional parameters which enable additional functionality such as callback processing, interrupt configuration and node linking.

	static inline void dma_link_nodes(
						struct stm_dma_params * parent,
						struct stm_dma_params * child)

where:-
	parent  	- 	parent node in the linked list 
	child   	- 	child node in the linked list

Provides the method for users to compile arbitrary linked lists of transfers. This function sets the 'child' to be the subsequent transfer from the node 'parent'. The node linkage must be set up before any transfers are compiled with dma_compile_list(). If the transfer ordering is modified after a call to dma_compile_list(), all node descriptors must be freed with dma_free_descriptor

FDMA Interrupt Generation

	

	static inline void dma_parms_interrupts(struct stm_dma_params *p,unsigned long isrflag)

where
	isrflag 	- 	bitmask representing the interrupt mode selected

This will enable FDMA interrupts, and based on the isrflag param, which is a bitmask, two behaviours are possible. Specifying STM_DMA_INTER_NODE_PAUSE will cause the FDMA to interrupt and pause the transfer after each node. The user is then for responsible for restarting paused transfers, this is described in the Control and Status functions section. for scatter-gather transfers this will illicit an interrupt for each element of the scatterlist. For circular transfers, an interrupt is generated each time a node is processed.

Specifying the STM_DMA_LIST_COMP_INT mask will precipitate the generation of an interrupt to the FDMA after the last byte of a single node or last byte of the last node of a linked list.

If both are required the two values should be 'or'ed into the isrflag parameter.

Callbacks

Two functions enable the callback mechanism of the FDMA driver. These can be executed in either interrupt or BH-tasklet context, after each node, or at the end of a list / singleton node or in case of an error.

	

	static inline void dma_parms_comp_cb(
							struct stm_dma_params *p,
							void (*fn)(void* param),
							void* param,
							int isr_context)

	static inline void dma_parms_err_cb(
							struct stm_dma_params *p,
							void (*fn)(void* param),
							void* param,
							int isr_context)

where
	fn		- 	function pointer of the type void fn(void*) to be allocated 
				to callback processing 
	
	param		- 	the void * parameter to the above callback function.
	
	isr_context - 	the context in which the callback should be executed 
				( interrupt of BH-tasklet)

If the fn parameters are not specified it will be taken that callbacks are disabled. Likewise if the 'param' parameter is NULL then the callback function will be executed without parameters. It may be necessary for your transfer to specify whether the callback be executed in task let or interrupt context. Specifying :-

  • STM_DMA_CB_CONTEXT_ISR
  • STM_DMA_CB_CONTEXT_TASKLET

to the isr_context param achieves this. Specifying nothing assumes the default behaviour of tasklet context processing.

If tasklet mode is chosen the callback will be scheduled at the time of the FDMA interrupt and executed as soon as Linux has no further pending interrupts. In isr context the callback is executed from within the FDMA interrupt handler. So be careful not to include any blocking operations in your callback function in this mode !

Callbacks will happen in two scenario's, when the transfer( end of single node / end of list) has completed(or node if STM_DMA_INTER_NODE_PAUSE is specified) or if the FDMA driver detects an error in the transfer ( note this does not include data / formatting errors, merely errors flagged by the FDMA engine). In this latter case, the current transfer will be aborted before the callback happens, and no further nodes in a linked list will be processed.

Compiling a transfer or transfer list

Once the required parameters have been selected, the transfer must be compiled from the meta-descriptor in the stm_dma_params * struct into a linked list of nodes executable by the fdma. This is done with the dma_compile_list() function. Failure to specify valid or a complete set of parameters will cause this function to fail,and perhaps logging a msg to the serial console if the error is a fatal one.

	static inline int dma_compile_list(struct stm_dma_params *params)

Compiling a transfer causes the fdma driver to allocate memory for a node, or nodelist and populate that list in accordance with the parameters in the stm_dma_params structure. This operation may fail if sufficient memory is not available in the system or if the parameters are incorrect.

In the case of a linked list of nodes, once linking has been established, dma_compile_list() should only be called for the first transfer descriptor in the list. The dma driver will then walk through the list of transfer descriptors and compile a self consistent nodelist.

Executing a transfer

In order to execute a compiled transfer on a particular channel, it is necessary first to request that channel for use by your driver. This can be done in a number of ways. Once a channel has been successfully requested, it is ensured that the channel is reserved for exclusive use by the requestee, until a matching call to free is executed.

Channels can be claimed using three methods, by capability, by channel number, or by next available. for particular channels, and these can be claimed by specifying the capability string to the request_dma_bycap() function. Available capabilities are exported from linux/stm/stm-dma.h. Specifying a NULL string to this function searches and returns the lowest channel available.

	extern int request_dma_bycap(
					const char** dmac, 
					const char** caps,
					const char *dev_id);

	extern int request_dma(unsigned int chan, const char *dev_id);

where
	dmac -		dma controller string ID - exported from stm-dma.h as 
				STM_DMAC_ID(Only for use by the STlinux FDMAC).

	caps - 		capability string exported for the channel, may be one of; 

								STM_DMA_CAP_HIGH_BW
								STM_DMA_CAP_LOW_BW
								NULL

				which specifies whether be channel be low or high bandwidth.  
				NULL will return the next lowest numbered channel available.
				It should also be used if no specific capabilities are needed.

	dev_id -		A string unique to your device driver to register the channel/driver 
				combination against the dmac.

	chan   - 		Channel number in the available range.

It is important to release the channel back to the pool when it is no longer needed so it can be used by other devices.

A typical usage scenario for the compile - transfer model may be as follows:

		declare transfer *input*
		declare transfer *output*
	
		specify params *input*
		specify params *output*
		
		link transfer input - > output
	
		compile transfer *input*

		request channel
			transfer *input*
			transfer *input*

		free channel 
		free transfer *input*
		free transfer *output*

Although there is no ordering requirement between channel request and node compile - Node compilation and linking is independent of any channel. ordering constraints do exist between the following:

where -> - happens before

  • dma_declare_params() -> dma_compile_list()
  • dma_link_nodes() -> dma_compile_list()
  • dma_compile_list() -> dma_transfer_list()
  • request_dma_*() -> dma_transfer_list()
  • dma_compile_list() -> dma_free_descriptor()
  • request_dma_*() -> free_dma()

A correctly compiled descriptor can be executed on a requested channel by the dma_xfer_list() function. The behaviour will be to start execution on the first node of the transfer, or block or return error in the case of a busy channel depending on the status input params (blocking), or an error value in the case of bad input parameters.

static inline int dma_xfer_list(unsigned int chan,stm_dma_params * p)

where
	chan	-	A reserved channel number in the range available to the dmac 
			specified by the dmac_name param of 'p'.

	p	-	Pointer to a compile transfer structure. 

Recompiling and re-executing a transfer

Any transfer that has been executed can be either re-executed with no change in parameters, on the same, or any other reserved channel, or re-compiled with different parameters, please note changing any of the parameters of the transfer requires it to be re-compiled. This is a lightweight operation where new parameters are inserted directly into the existing nodelist. It should also be noted that scatter-gather transfers should be re-compiled every time the parameters or length of the scatterlist struct are changed, as this will alter the length of the nodelist required to describe the transfer.

Changing the ordering of the nodelist, or any of the mode parameters given in the dma_declare_params() function require a dma_free_descriptor() call on each of the descriptors before a further call(s) to dma_compile_list().

Transfer cleanup & de-init

Once the transfer is no longer required, or any of the major parameters have changed, the descriptor should be freed. This is done with a call to

	dma_free_descriptor(struct stm_dma_params *params)

which frees all allocated node memory,and resets structure parameters, ready for the structure to be either re-used in an alternative mode or discarded.

Additionally any reserved channels should be freed when they are no longer required, this is done with a call to:

	extern void free_dma(unsigned int chan);

which will release the channel if it is idle, or if it is busy, attempt to stop the channel, and then release.

SH DMA API Backwards Compatibility

The API for STLinux2.2 has been regressed to include a compatibility mode for any devices already using the existing SH-DMA API. Due to the limited applicability of this API to STMicroelectronics DMA controllers, only a small subset of mode and configurations are possible. For example it is not possible to perform paced, scatter-gather, or linked list transfers. Only memory-memory in freerunning mode is possible.

The method for describing a transfer in this mode is considerably different to the rest of the API and is explained below. In this use case, configuration cannot be achieved while a transfer is in operation, as the descriptor is associated with the channel at the first instance. This forces a sequential mode of operation for compilation and execution of a dma transfer.

It is still necessary to reserve a channel from the dma-controller. The compatible function is request_dma - where the parameter may be any integer in the valid range, or the flag DMA_REQ_ANY_CHANNEL. Next you need to gain the default status of the channel from the controller.

This is done with a call to get_dma_channel() specifying the channel number which has previously been reserved

Next a call to dma_configure_channel() is required, here we associate the channel number with the mode of operation. The flags parameter must contain a bitmask of three values -

  • task or interrupt setup mode
  • a dimensionality parameter
  • a mode - the only available is MODE_SH_COMPATIBILITY

next we call the transfer function(dma_xfer()) with our src and destination address', plus channel number and the mode. The same memory space constraints on src and dst locations apply as with other transfer modes.

Function prototypes are given below.

	extern struct dma_channel *get_dma_channel(unsigned int chan);

	extern void dma_configure_channel(
			unsigned int chan, 
			unsigned long flags);

	extern int dma_xfer(
			unsigned int chan, 
			unsigned long from, 
			unsigned long to, 
			size_t size, 
			unsigned int mode);
	
where 
	chan -  	Integer channel number
	flags - 	Mode parmaters muxed into a bitmask
	from - 		src addr of transfer
	to	-		dst addr of transfer
	size - 		number of bytes to transfer			

Notification of completion can only be via the dma_wait_for_completion() API A worked example can be found here

Freerunning Mode

This modes provides basic memory-memory move functionality. Transfers can be configured for Single location, linear or rectangular arrays. The method of specifying transfer parameters has been described in the Compiling a transfer or transfer list section.

Further information about what linear and rectangular arrays are can be found in the STb7100 datasheet in section 47.4.1. It is possible to mix dimensions in source and destination, so we could for example, specify a 2d-0d transfer, or a 1d-1d transfer.

A code example can be found here

Scatter-Gather Mode

Scatter Gather transfers are supported in memory to memory mode, allowing buffer collation from non-contiguous memory areas. It is also possible to specify transfer to or from blocks of 0/1/2 Dimensional memory, as in Freerunning Mode. There is currently no explicit support for gathering directly into a paced peripheral or vice versa.

The STM DMA API uses the generic Linux struct scatterlist support, and so a working knowledge of scatterlists and how to compile them is required to configure transfers in this mode correctly. Documentation on this system can be found in the Linux Kernel Documentation on DMA. This is available in the kernel sources at /Documentation/DMA-mapping.txt & DMA-API.txt.

Scatter Gather is either from a non-contiguous memory area to a contiguous one or vice versa, it is not possible to transfer between two non-contiguous areas in this mode, though a linked list of generic memory-memory transfer could achieve this functionality. Therefore given the two modes of operation, the Mode parameter given to dma_declare_params() should either be

  • MODE_SRC_SCATTER - for non-contiguous - contiguous transfers
  • MODE_DST_SCATTER - for contiguous - non-contiguous transfers
For an example see here

Paced Mode

Paced mode provides a way to connect a cpu to a peripheral and feed data in the correct format and rate for the device in question without cpu intervention. A number of different on-chip peripherals are supported. Which peripherals are available depends on cpu and revision number, so check your SoC's datasheet FDMA section for a mapping of the devices supported.

When operating in paced mode, the dma system will traditionally be transferring to or from a peripheral's FIFO. Signals are generated by the peripheral to flag a data request(either read / write) which are sampled by the FDMA and a chunk of data transferred and the signal lowered. In this way peripheral's can be fed at the correct rate with no FIFO over/underrun or lost update at the peripheral. For each peripheral a default pacing configuration is supplied, which specifies the data format at the peripheral. For example, parameters such as data width and depth of the FIFO, size of data chunks issued by the FDMA etc. This is explained in more detail below.

A paced dma transfer must be mapped against a particular device. An integer mapping exists for each peripheral. This is the req_line value. The values are exported from linux/stm/*cpu specific header*.h. The value corresponding to the peripheral is used as the req_line parameter of the function below.

	static inline void dma_parms_paced(	
						struct stm_dma_params *p,
						unsigned long xfer_size,
						int req_line)

Here we are specifying only the total number of bytes for the transfer, with pacing transfers we are assuming a model of 1x0 if writing from a memory area to a peripheral, or 0x1 if reading from a peripheral into memory.

Therefore in this instance the xfer_size parameter is specifying both the line length of the memory side, and the total length of the transfer. Configuration of the peripheral side is selected by associating the transfer with a particular req_line mapping. This gives a default setup for each peripheral, it is however possible to specify these parameters manually if you wish.

A code example which gives an example of a paced, circular, singleton transfer that feeds the pcm players can be found here

If you wish to perform a transfer that is not 0x1 or 1x0, you must set up all node params manually with the manual_dim_params() function. Usage of this function implies knowledge of how the transfer is to increment through memory, and how the peripheral in question operates(FIFO size / trigger limit etc). Depending on transfer dimensions, some of the parameters may not be required, if unsure please refer to the (FDMA) driver implementation.

	static inline int dma_manual_stbus_pacing(
						struct stm_dma_params *params,
						struct fmdareq_RequestConfig_s * rq)

where 
	rq -	specifies the new configuration for the request line. Defined as follows
			typedef struct fmdareq_RequestConfig_s -see below for 
			structure def and available	values.

Please be aware that this is specific to the 710x series of CPU's. where

Table 1 : fmdareq_RequestConfig_s definition

member comment valid values
char Index Request line index number see cpu header
char Access Access type Read or Write READ
WRITE
char OpCode STBUS LoadStore Word Size OPCODE_1
OPCODE_2
OPCODE_4
OPCODE_8
OPCODE_16
OPCODE_32
Char Count Iterations of opcode user define
char Increment Increment peripheral side addr by bytes between STBUS packets ENABLE_FLG
DISABLE_FLAG
char HoldOff min time between req signal resample in microseconds HOLDOFF_0US
HOLDOFF_1US
HOLDOFF_2US
char Initiator STBUS target for transactions STBUS_INT0
STBUS_INT1

Control and Status functions

It is possible to manipulate individual channels through the API, as well as gain current state information. It is possible to pause / unpause, stop, and sleep until completion.

There are two methods for gaining the state of a particular channel, or ongoing transfer, these provide the activity status (running/paused/idle), and the number of bytes remaining to be transferred on that channel. These are the dma_get_status() and dma_get_residue() functions. A description of each follows.

	
	extern int get_dma_residue(unsigned int chan);

where
	chan -  channel number to interrogate


This functions returns the number of bytes remaining to be processed for the current transfer, or for linked list transfers the number returned will be a total for the current transfer plus the total bytes for all remaining transfers. If the channel is currently inactive or completed zero will be returned.

	static inline int dma_get_status(unsigned int chan)

This functions returns the current activity state of the channel specified in chan. It will be one of three values

  • DMA_CHANNEL_STATUS_IDLE (0)
  • DMA_CHANNEL_STATUS_RUNNING (2)
  • DMA_CHANNEL_STATUS_PAUSED (3)

	static inline int dma_pause_channel(int flags, unsigned int chan)

where
	chan  - channel number to pause
	
	flags - one of 	STM_DMA_CHANNEL_PAUSE_FLUSH 
				STM_DMA_CHANNEL_PAUSE_NOFLUSH

This function will pause any active channel, the flags parameter specifies whether to flush the current operation from the DMA-engine's memory. In the case of an unpause after a flush operation, on a linked list with remaining transfers, the next transfer in the list will be loaded and executed automatically. In the case of the last element of a list, or singleton, the current operation is flushed and the FDMA returned to idle. A flush will cause the DMA engine to lapse into idle. If flush is not specified, the fdma will continue with its currently loaded transfer - from the point it was paused. It is possible for this operation to fail, if either the channel is not in a running state, or if the DMA engine fails to respond to the command.

	static inline void dma_unpause_channel(unsigned int chan)

where 
	chan -  channel number to unpause

This function will unpause any currently pause channel. If it is not in the paused state, then the operation equates to nop.

	extern void dma_wait_for_completion(unsigned int chan);

where
	chan  - 	The channel number to wait on.

This function implements a wait_event call that will put the calling process to sleep while the given channel is in operation. As such it is not safe to call from interrupt context. The wake_up signal is raised after DMA engine completion interrupt generation and handling but before the processing of any callbacks associated with that channel.

Caviats

  • There is a maximal size of memory that can be allocated to dma-descriptors, though this should not be a problem in practical terms. The limit is the 128kbyte upper limit of kmalloc, and given that each transfer element (note scatter-gather transfers contain a number of sub-elements equal to the sg_length parameter) requires 32 bytes this provides space for a 4096 element linked list.
  • Source and destination address parameters must be uncached physical format (P1 space - SH4) and be aligned to 32 bytes.
  • Source and destination memory regions must be in uncached memory and physically contiguous.
  • peripheral paced transfers must be an exact multiple of the peripheral register/FIFO size.
  • Currently STM_DMA is supported only on the Stb710x series, with the exception of stb7109_C1.
Previous   Contents   Next
Valid HTML 4.01! Last updated: 2006/11/15 13:50:11
© Copyright STMicroelectronics Limited, 2005
Printer