EDMA3驱动的API:
(一):
static void __init map_dmach_param(unsigned ctlr)//map_dmach_param - Maps channel number to param entry number——映射通道号到参数的通道号,也就是说,使用通道参数映射寄存器,可以将通道的参数配置映射到任何一个通道,callers负责将通道的映射逻辑包含特定设备的变量中。
static inline void setup_dma_interrupt(unsigned lch,void (*callback)(unsigned channel, u16 ch_status, void *data),void *data)
static int irq2ctlr(int irq)
(二):DMA interrupt handler——DMA中断的句柄
static irqreturn_t dma_irq_handler(int irq, void *data)
(三): DMA error interrupt handler——DMA错误中断的句柄
(四):Transfer controller error interrupt handlers——传输控制错误中断句柄
static irqreturn_t dma_tc0err_handler(int irq, void *data)
static irqreturn_t dma_tc1err_handler(int irq, void *data)
static int reserve_contiguous_slots(int ctlr, unsigned int id,unsigned int num_slots,unsigned int start_slot)
/*
* We have to clear any bits that we set
* if we run out parameter RAM slots, i.e we do find a set
* of contiguous parameter RAM slots but do not find the exact number
* requested as we may reach the total number of parameter RAM slots
*/
如果我们用完了参数RAM槽的每一位,必须清理掉所设置的每一位,换言之,我们确实找到了一系列连续的参数RAM槽,但是没有找到确切的请求数字因为我们可能达到了它可以设置的数目的最大值。
static int prepare_unused_channel_list(struct device *dev, void *data)
(五)
/*-----------------------------------------------------------------------*/
static bool unused_chan_list_done;
/* Resource alloc/free: dma channels, parameter RAM slots */
/**
* edma_alloc_channel - allocate DMA channel and paired parameter RAM
* @channel: specific channel to allocate; negative for "any unmapped channel"
* @callback: optional; to be issued on DMA completion or errors
* @data: passed to callback
* @eventq_no: an EVENTQ_* constant, used to choose which Transfer
* Controller (TC) executes requests using this channel. Use
* EVENTQ_DEFAULT unless you really need a high priority queue.
*
* This allocates a DMA channel and its associated parameter RAM slot.
* The parameter RAM is initialized to hold a dummy transfer.
*
* Normal use is to pass a specific channel number as @channel, to make
* use of hardware events mapped to that channel. When the channel will
* be used only for software triggering or event chaining, channels not
* mapped to hardware events (or mapped to unused events) are preferable.
*
* DMA transfers start from a channel using edma_start(), or by
* chaining. When the transfer described in that channel's parameter RAM
* slot completes, that slot's data may be reloaded through a link.
*
* DMA errors are only reported to the @callback associated with the
* channel driving that transfer, but transfer completion callbacks can
* be sent to another channel under control of the TCC field in
* the option word of the transfer's parameter RAM set. Drivers must not
* use DMA transfer completion callbacks for channels they did not allocate.
* (The same applies to TCC codes used in transfer chaining.)
*
* Returns the number of the channel, else negative errno.
*/
EDMA分配通道-分配DMA通道和成对的参数RAM
Channel:特定的通道去分配;对于任何没有映射的通道是无效的
Callback:可选择的;在DMA完成后或者发生错误时会出现
Data:进入callback
Eventq_no:一个事件队列的常量,用来选择哪个传输通道控制器来用这个通道发送请求。一般情况下选择默认的事件队列,除非真的需要一个较高优先级的队列。
它能够分配一个DMA的通道和它的关联的参数RAM槽。这个参数RAM是用傀儡传输来初始化的。
正常使用是通过一个特定的参数号作为通道,利用硬件事件映射到那个通道。当通道将被只用在软件触发或者事件链的情况下时,没有被映射到硬件事件的通道时更适合的。
DMA传输从一个通道使用 edma_start( )开始,或者通过链接。当由那个通道参数RAM槽描述的传输结束了之后,这个槽的数据可能会通过一个link重新加载。
DMA的错误仅能通过与驱动那个传输相关联的callback函数报告。但是传输完成的callback能够在传输通道控制器filed的参数RAM里面的option进行控制被发送到别的通道。驱动不能对它们没有分配的通道使用DMA传输控制完成的callback。(同样适用于在传输控制链TCC下的代码)
能够返回申请好的通道号,否则就是一个负的表示错误的代号
(六)
/**
* edma_free_channel - deallocate DMA channel
* @channel: dma channel returned from edma_alloc_channel()
*
* This deallocates the DMA channel and associated parameter RAM slot
* allocated by edma_alloc_channel().
*
* Callers are responsible for ensuring the channel is inactive, and
* will not be reactivated by linking, chaining, or software calls to
* edma_start().
*/
EDMA释放通道-解除DMA通道
@channel:从edma_alloc_channel()返回的dma通道号
这个函数能够解除对DMA通道的分配和与之相关的参数的RAM槽。
void edma_free_channel(unsigned channel)
(七)
/**
* edma_alloc_slot - allocate DMA parameter RAM
* @slot: specific slot to allocate; negative for "any unused slot"
*
* This allocates a parameter RAM slot, initializing it to hold a
* dummy transfer. Slots allocated using this routine have not been
* mapped to a hardware DMA channel, and will normally be used by
* linking to them from a slot associated with a DMA channel.
*
* Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific
* slots may be allocated on behalf of DSP firmware.
*
* Returns the number of the slot, else negative errno.
*/
分配DMA通道参数RAM
@slot:特定的槽被用来分配;对任何没有使用到的槽来说是负的
这个函数分配一个参数RAM槽,通过傀儡传输来将它初始化。被用这个规则分配的slot还没有被映射到一个硬件的DMA通道上,通常通过一个相关DMA通道来对它进行链接后使用。
通常的使用是通过使用EDMA_SLOT_ANY来作为@slot,但是特定的slot可能被分配用来代表DSP的固件。
返回slot的数量,否则是复数的错误返回值。
int edma_alloc_slot(unsigned ctlr, int slot)
(八)
/**
* edma_free_slot - deallocate DMA parameter RAM
* @slot: parameter RAM slot returned from edma_alloc_slot()
*
* This deallocates the parameter RAM slot allocated by edma_alloc_slot().
* Callers are responsible for ensuring the slot is inactive, and will
* not be activated.
*/
edma_free_slot-释放DMA的参数RAM
@slot:edma_alloc_slot()的返回值
这个函数可以释放由edma_alloc_slot()分配的参数RAM槽
调用者要确保这个slot是不活跃的,而且未来也不会被触发的
void edma_free_slot(unsigned slot)
(九)
/**
* edma_alloc_cont_slots- alloc contiguous parameter RAM slots
* The API will return the starting point of a set of
* contiguous parameter RAM slots that have been requested
*
* @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
* or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
* @count: number of contiguous Paramter RAM slots
* @slot - the start value of Parameter RAM slot that should be passed if id
* is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
*
* If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of
* contiguous Parameter RAM slots from parameter RAM 64 in the case of
* DaVinci SOCs and 32 in the case of DA8xx SOCs.
*
* If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a
* set of contiguous parameter RAM slots from the "slot" that is passed as an
* argument to the API.
*
* If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries
* starts looking for a set of contiguous parameter RAMs from the "slot"
* that is passed as an argument to the API. On failure the API will try to
* find a set of contiguous Parameter RAM slots from the remaining Parameter
* RAM slots
*/
edma_alloc_cont_slots-分配连续的参数RAM槽。这个函数将会返回被请求的一系列连续参数RAM的起始点。
@id:只能是EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
* or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
@count:连续参数RAM槽的数目
@slot-如果id 是EDMA_CONT_PARAMS_FIXED_EXACT
or EDMA_CONT_PARAMS_FIXED_NOT_EXACT,应该采用参数RAM slot的起始值。
如果id是EDMA_CONT_PARAMS_ANY,然后它会从参数RAM 64里面开始寻找一系列连续的参数RAM,如果是达芬奇的片上芯片的话。
如果id是EDMA_CONT_PARAMS_FIXED_EXACT,然后它会从传递slot参数里面开始寻找一系列连续的参数RAM。
如果id是EDMA_CONT_PARAMS_FIXED_NOT_EXACT然后这个函数会从传递slot参数里面开始寻找一系列连续的参数RAM在失败的时候,这个函数会尝试从现有的参数RAMslot里面找到一系列连续的参数RAM。
int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
/*
* The start slot requested should be greater than
* the number of channels and lesser than the total number
* of slots
*/
开始的被申请的slot应该比通道的数目多并且比slot的总数目少
/*
* The number of parameter RAM slots requested cannot be less than 1
* and cannot be more than the number of slots minus the number of
* channels
*/
被请求的参数RAMslot的数目不能比1小并且不能比超过slots的数量减去通道的数量
(十)
/**
* edma_free_cont_slots - deallocate DMA parameter RAM slots
* @slot: first parameter RAM of a set of parameter RAM slots to be freed
* @count: the number of contiguous parameter RAM slots to be freed
*
* This deallocates the parameter RAM slots allocated by
* edma_alloc_cont_slots.
* Callers/applications need to keep track of sets of contiguous
* parameter RAM slots that have been allocated using the edma_alloc_cont_slots
* API.
* Callers are responsible for ensuring the slots are inactive, and will
* not be activated.
*/
edma_free_cont_slots-释放DMA参数RAM的slots。
@slot:一系列即将被释放的参数RAMslots里面的第一个参数RAM。
@count:将要被释放的连续参数RAM的数目。
调用者和应用需要追踪一系列连续的已经被用the edma_alloc_cont_slots分配的参数RAM的slots。
(十一)
/*-----------------------------------------------------------------------*/
/* Parameter RAM operations (i) -- read/write partial slots */
/**
* edma_set_src - set initial DMA source address in parameter RAM slot
* @slot: parameter RAM slot being configured
* @src_port: physical address of source (memory, controller FIFO, etc)
* @addressMode: INCR, except in very rare cases
* @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
* width to use when addressing the fifo (e.g. W8BIT, W32BIT)
*
* Note that the source address is modified during the DMA transfer
* according to edma_set_src_index().
*/
参数RAM的操作-读或者写部分的slots.
edma_set_src-在参数RAMslot里面设置初始的DMA源地址。
@slot:正在被配置的参数RAMslot.
@src_port:物理源地址(内存、FIFO控制器等等)
@地址模式:INCR,除非在极少数的情况下
@fifo宽度:通常被忽略,除非地址模式是FIFO,当地址是FIFO的时候,可以指定宽度是W8bit,W32bit.
注意:源地址在DMA传输期间可以根据edma_set_src_index()的值进行修正。
(十二)
/**
* edma_set_dest - set initial DMA destination address in parameter RAM slot
* @slot: parameter RAM slot being configured
* @dest_port: physical address of destination (memory, controller FIFO, etc)
* @addressMode: INCR, except in very rare cases
* @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
* width to use when addressing the fifo (e.g. W8BIT, W32BIT)
*
* Note that the destination address is modified during the DMA transfer
* according to edma_set_dest_index().
*/
void edma_set_dest(unsigned slot, dma_addr_t dest_port,
enum address_mode mode, enum fifo_width width)
(十三)
/**
* edma_get_position - returns the current transfer points
* @slot: parameter RAM slot being examined
* @src: pointer to source port position
* @dst: pointer to destination port position
*
* Returns current source and destination addresses for a particular
* parameter RAM slot. Its channel should not be active when this is called.
*/
edma_get_position-返回当前的传输点
@slot:正在被测试的参数RAMslot.
@src:指向源端位置
@dst:指向目标端位置
对特定的参数RAMslot返回当前的源地址和目的地址。当被调用的时候,它的通道不应当是活跃的。
void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst)
(十四)
/**
* edma_set_src_index - configure DMA source address indexing
* @slot: parameter RAM slot being configured
* @src_bidx: byte offset between source arrays in a frame
* @src_cidx: byte offset between source frames in a block
*
* Offsets are specified to support either contiguous or discontiguous
* memory transfers, or repeated access to a hardware register, as needed.
* When accessing hardware registers, both offsets are normally zero.
*/
edma_set_src_index-配置DMA源地址索引
@slot:正在被配置的参数RAMslot
@src_bidx:在一帧里面源数列的偏移字节
@src_cidx:在一块里面源帧的偏移字节
偏移通常被指定支持连续和不连续的内存传输。或者根据需要重复进入一个硬件寄存器的入口,当需要访问硬件寄存器的时候,两个偏移通常都是零。
(十五)
/**
* edma_set_dest_index - configure DMA destination address indexing
* @slot: parameter RAM slot being configured
* @dest_bidx: byte offset between destination arrays in a frame
* @dest_cidx: byte offset between destination frames in a block
*
* Offsets are specified to support either contiguous or discontiguous
* memory transfers, or repeated access to a hardware register, as needed.
* When accessing hardware registers, both offsets are normally zero.
*/
void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
(十六)
/**
* edma_set_transfer_params - configure DMA transfer parameters
* @slot: parameter RAM slot being configured
* @acnt: how many bytes per array (at least one)
* @bcnt: how many arrays per frame (at least one)
* @ccnt: how many frames per block (at least one)
* @bcnt_rld: used only for A-Synchronized transfers; this specifies
* the value to reload into bcnt when it decrements to zero
* @sync_mode: ASYNC or ABSYNC
*
* See the EDMA3 documentation to understand how to configure and link
* transfers using the fields in PaRAM slots. If you are not doing it
* all at once with edma_write_slot(), you will use this routine
* plus two calls each for source and destination, setting the initial
* address and saying how to index that address.
*
* An example of an A-Synchronized transfer is a serial link using a
* single word shift register. In that case, @acnt would be equal to
* that word size; the serial controller issues a DMA synchronization
* event to transfer each word, and memory access by the DMA transfer
* controller will be word-at-a-time.
*
* An example of an AB-Synchronized transfer is a device using a FIFO.
* In that case, @acnt equals the FIFO width and @bcnt equals its depth.
* The controller with the FIFO issues DMA synchronization events when
* the FIFO threshold is reached, and the DMA transfer controller will
* transfer one frame to (or from) the FIFO. It will probably use
* efficient burst modes to access memory.
*/
edma_set_transfer_params-配置DMA传输参数
@slot:正在被配置的参数RAMslot
@acnt:每一个数列的字节数目(最少一个)
@bcnt:每一帧的数列数目(最少一个)
@ccnt:每一块的帧的数目(最少一个)
@bcnt_rld:仅仅用在A类同步传输中;当bcnt减小到零的时候,它指定了重载到bcnt的值的大小。
@sync_mode:A类同步传输模式或者AB类同步传输模式
看EDMA3的手册来理解如何配置和链接传输利用PaRam的slots.如果不是正在用edma_write_slots()一次性的解决这个问题。将使用这种规则加上对源地址和目的地址的两次回调,设置初始地址,并且说明如何索引这个地址。
一个利用A类同步传输的例子是一个串行的连接使用单字移动寄存器。在那个情况下,@acnt将等同于字的大小;串行控制器使能一个DMA同步事件来传输每一个字,并且由DMA传输控制器决定的内存通道将是每次一个字。
void edma_set_transfer_params(unsigned slot,u16 acnt, u16 bcnt, u16 ccnt,
u16 bcnt_rld, enum sync_dimension sync_mode)
(十七)
/**
* edma_link - link one parameter RAM slot to another
* @from: parameter RAM slot originating the link
* @to: parameter RAM slot which is the link target
*
* The originating slot should not be part of any active DMA transfer.
*/
edma_link-链接一个参数RAMslot到另外一个
@from:参数RAMslot中link的开始端
@to:参数RAMslot中的link目标
开始端的Slot不能是任何活跃的DMA传输
void edma_link(unsigned from, unsigned to)
(十八)
/**
* edma_unlink - cut link from one parameter RAM slot
* @from: parameter RAM slot originating the link
*
* The originating slot should not be part of any active DMA transfer.
* Its link is set to 0xffff.
*/
edma_unlink-切断从某一个参数RAM slot的链接
@from:link起始的参数RAM slot
这个起始的slot不应当是任何活跃的DMA传输的一部分
它的链接被设置在0xffff.
void edma_unlink(unsigned from)
(十九)
/* Parameter RAM operations (ii) -- read/write whole parameter sets */
/**
* edma_write_slot - write parameter RAM data for slot
* @slot: number of parameter RAM slot being modified
* @param: data to be written into parameter RAM slot
*
* Use this to assign all parameters of a transfer at once. This
* allows more efficient setup of transfers than issuing multiple
* calls to set up those parameters in small pieces, and provides
* complete control over all transfer options.
*/
Parameter RAM operations-读或者写整个参数设置
edma_write_slot-为slot写参数RAM数据
@slot:正在修正的参数RAMslot的数目
@param:要写到参数RAMslot里面的数据
通过这个函数来一次性指定传输的所有参数。它比引起多次回调小范围的设置那些参数更加高效,而且提供了对整个传输选项的完全控制。
void edma_write_slot(unsigned slot, const struct edmacc_param *param)
(二十)
/**
* edma_read_slot - read parameter RAM data from slot
* @slot: number of parameter RAM slot being copied
* @param: where to store copy of parameter RAM data
*
* Use this to read data from a parameter RAM slot, perhaps to
* save them as a template for later reuse.
*/
void edma_read_slot(unsigned slot, struct edmacc_param *param)
(二十一)
/*-----------------------------------------------------------------------*/
/* Various EDMA channel control operations */
/**
* edma_pause - pause dma on a channel
* @channel: on which edma_start() has been called
*
* This temporarily disables EDMA hardware events on the specified channel,
* preventing them from triggering new transfers on its behalf
*/
void edma_pause(unsigned channel)
(二十二)
/**
* edma_resume - resumes dma on a paused channel
* @channel: on which edma_pause() has been called
*
* This re-enables EDMA hardware events on the specified channel.
*/
void edma_resume(unsigned channel)
(二十三)
/**
* edma_start - start dma on a channel
* @channel: channel being activated
*
* Channels with event associations will be triggered by their hardware
* events, and channels without such associations will be triggered by
* software. (At this writing there is no interface for using software
* triggers except with channels that don't support hardware triggers.)
*
* Returns zero on success, else negative errno.
*/
有事件联系的将会被它们的硬件事件触发,没有这种联系的将被软件触发。(在这个函数里使用软件触发没有接口,除非是不支持硬件触发的那些通道)
int edma_start(unsigned channel)
(二十四)
/**
* edma_stop - stops dma on the channel passed
* @channel: channel being deactivated
*
* When @lch is a channel, any active transfer is paused and
* all pending hardware events are cleared. The current transfer
* may not be resumed, and the channel's Parameter RAM should be
* reinitialized before being reused.
*/
停止通道传输的DMA
当@lch是一个通道的时候,任何激活的传输都被暂停并且所有挂起的中断事件都要被清除。当前的传输可能不会被恢复,并且这个通道的参数RAM应该在被重新使用后重新初始化。
void edma_stop(unsigned channel)
(二十五)
/******************************************************************************
*
* It cleans ParamEntry qand bring back EDMA to initial state if media has
* been removed before EDMA has finished.It is usedful for removable media.
* Arguments:
* ch_no - channel no
*
* Return: zero on success, or corresponding error no on failure
*
* FIXME this should not be needed ... edma_stop() should suffice.
*
*****************************************************************************/
它清除了参数入口并且如果媒体在EDMA在它没有被完成之前就会返回到EDMA的初始状态,它对于可移除的媒体是有用的。
void edma_clean_channel(unsigned channel)
(二十六)
/*
* edma_clear_event - clear an outstanding event on the DMA channel
* Arguments:
* channel - channel number
*/
void edma_clear_event(unsigned channel)
(二十七)
static int __init edma_probe(struct platform_device *pdev)
EDMA3驱动的API
最新推荐文章于 2021-07-24 16:47:47 发布