366628bf5a
Signed-off-by: xucheng5 <xucheng5@xiaomi.com>
327 lines
11 KiB
C
327 lines
11 KiB
C
/****************************************************************************
|
|
* include/nuttx/dma/dma.h
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __INCLUDE_NUTTX_DMA_DMA_H
|
|
#define __INCLUDE_NUTTX_DMA_DMA_H
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
#include <stdint.h>
|
|
#include <sys/types.h>
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
/* DMA transfer direction indicator */
|
|
|
|
#define DMA_MEM_TO_MEM 1
|
|
#define DMA_MEM_TO_DEV 2
|
|
#define DMA_DEV_TO_MEM 3
|
|
#define DMA_DEV_TO_DEV 4
|
|
|
|
#ifdef CONFIG_DMA_LINK
|
|
# define DMA_BLOCK_MODE 0
|
|
# define DMA_SRC_LINK_MODE 1
|
|
# define DMA_DST_LINK_MODE 2
|
|
# define DMA_DUAL_LINK_MODE 3
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_GET_CHAN
|
|
*
|
|
* Description:
|
|
* Get a DMA channel. This function gives the caller mutually exclusive
|
|
* access to the DMA channel specified by the 'ident' argument.
|
|
*
|
|
* If the DMA channel is not available, then DMA_GET_CHAN will wait
|
|
* until the holder of the channel relinquishes the channel by calling
|
|
* DMA_PUT_CHAN(). WARNING: If you have two devices sharing a DMA
|
|
* channel and the code never releases the channel, the DMA_GET_CHAN
|
|
* call for the other will hang forever in this function!
|
|
*
|
|
* Input Parameters:
|
|
* ident - Identifies the channel resource
|
|
*
|
|
* Returned Value:
|
|
* Provided that 'ident' is valid, this function ALWAYS returns a non-NULL,
|
|
* dma_chan_s instance. (If 'ident' is invalid, the function will assert
|
|
* if debug is enabled or do something ignorant otherwise).
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_GET_CHAN(dev, ident) (dev)->get_chan(dev, ident)
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_PUT_CHAN
|
|
*
|
|
* Description:
|
|
* Release a DMA channel. If another thread is waiting for this DMA channel
|
|
* in a call to DMA_GET_CHAN, then this function will re-assign the DMA
|
|
* channel to that thread and wake it up. NOTE: The 'chan' used in this
|
|
* argument must NEVER be used again until DMA_GET_CHAN() is called again
|
|
* to re-gain access to the channel.
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_PUT_CHAN(dev, chan) (dev)->put_chan(dev, chan)
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_CONFIG
|
|
*
|
|
* Description:
|
|
* Configure DMA before using
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_CONFIG(chan, cfg) (chan)->ops->config(chan, cfg)
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_START
|
|
*
|
|
* Description:
|
|
* Start the DMA transfer. NOTE: The DMA module does *NOT* perform any
|
|
* cache operations. It is the responsibility of the DMA client to clean
|
|
* DMA buffers after staring of the DMA TX operations.
|
|
*
|
|
* Input Parameters:
|
|
* chan - The channel to start
|
|
* callback - The callback when the transfer finish
|
|
* arg - The argument will pass to callback
|
|
* dst - The destination address
|
|
* src - The source address
|
|
* len - The length to transfer
|
|
*
|
|
* Returned Value:
|
|
* The error code
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_START(chan, callback, arg, dst, src, len) \
|
|
(chan)->ops->start(chan, callback, arg, dst, src, len)
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_START_CYCLIC
|
|
*
|
|
* Description:
|
|
* Start the cyclic DMA transfer.
|
|
*
|
|
* Note: callback get called for each period length data DMA transfer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_START_CYCLIC(chan, callback, arg, dst, src, len, period_len) \
|
|
(chan)->ops->start_cyclic(chan, callback, arg, dst, src, len, period_len)
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_START_LINK
|
|
*
|
|
* Description:
|
|
* Start the DMA link transfer.
|
|
*
|
|
* Note: callback get called when the DMA link transfer finish.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_DMA_LINK
|
|
# define DMA_START_LINK(chan, callback, arg, mode, link_cfg) \
|
|
(chan)->ops->start_link(chan, callback, arg, mode, link_cfg)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_PAUSE
|
|
*
|
|
* Description:
|
|
* Pause the DMA transfer. After DMA_PAUSE() is called, DMA_RESUME() must
|
|
* be called to restart the transfer again.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_PAUSE(chan) (chan)->ops->pause(chan)
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_RESUME
|
|
*
|
|
* Description:
|
|
* Resume the DMA transfer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_RESUME(chan) (chan)->ops->resume(chan)
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_STOP
|
|
*
|
|
* Description:
|
|
* Stop the DMA transfer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_STOP(chan) (chan)->ops->stop(chan)
|
|
|
|
/****************************************************************************
|
|
* Name: DMA_RESIDUAL
|
|
*
|
|
* Description:
|
|
* Returns the number of bytes remaining to be transferred.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define DMA_RESIDUAL(chan) (chan)->ops->residual(chan)
|
|
|
|
/****************************************************************************
|
|
* Public Types
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* This is the type of the callback that is used to inform the user of the
|
|
* completion of the DMA. NOTE: The DMA module does *NOT* perform any cache
|
|
* operations. It is the responsibility of the DMA client to invalidate DMA
|
|
* buffers after completion of the DMA RX operations.
|
|
*
|
|
* Input Parameters:
|
|
* chan - Refers to the DMA channel.
|
|
* arg - A user-provided value that was provided when start() was called.
|
|
* len - Positive value represent the transfer length, negative is error
|
|
* code.
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
struct dma_chan_s;
|
|
typedef CODE void (*dma_callback_t)(FAR struct dma_chan_s *chan,
|
|
FAR void *arg, ssize_t len);
|
|
|
|
/* This struct is passed in as configuration data to a DMA engine
|
|
* in order to set up a certain channel for DMA transport at runtime.
|
|
*
|
|
* The rationale for adding configuration information to this struct is as
|
|
* follows: if it is likely that more than one DMA controllers in the world
|
|
* will support the configuration option, then make it generic. If not: if
|
|
* it is fixed so that it be sent in static from the platform data, then
|
|
* prefer to do that.
|
|
*
|
|
* direction - whether the data shall go in or out on this channel.
|
|
* priority - the bus priority compare with other active channel.
|
|
* timeout - abort if the source can't prepare data within this value.
|
|
* option - used to configuration for this dma channel which is optional
|
|
* dst_width - this is the width in bytes of destination target(TX) register
|
|
* where DMA data shall be read. If the source is memory this
|
|
* may be ignored. Legal values: 1, 2, 4, 8.
|
|
* src_width - same as dst_width but for the source(RX) mutatis mutandis.
|
|
* dst_drq - physical destination DMA request ID for this channel.
|
|
* src_drq - physical source DMA request ID for this channel.
|
|
* dst_step - after each DMA transfer, destination addr should increase
|
|
* dst_step (> 0) or decrease dst_step (< 0)
|
|
* src_step - after each DMA transfer, source addr should increase
|
|
* dst_step (> 0) or decrease dst_step (< 0)
|
|
*
|
|
* Note: the special value zero means to keep the current value without
|
|
* change.
|
|
*
|
|
****************************************************************************/
|
|
|
|
struct dma_config_s
|
|
{
|
|
unsigned int direction;
|
|
unsigned int priority;
|
|
unsigned int timeout;
|
|
unsigned int option;
|
|
unsigned int dst_width;
|
|
unsigned int src_width;
|
|
unsigned int dst_drq;
|
|
unsigned int src_drq;
|
|
int dst_step;
|
|
int src_step;
|
|
};
|
|
|
|
#ifdef CONFIG_DMA_LINK
|
|
struct dma_link_s
|
|
{
|
|
uintptr_t addr;
|
|
union
|
|
{
|
|
unsigned int link_num;
|
|
unsigned int link_size;
|
|
};
|
|
};
|
|
|
|
struct dma_link_config_s
|
|
{
|
|
unsigned int dst_link_num;
|
|
unsigned int src_link_num;
|
|
FAR struct dma_link_s *dst_link;
|
|
FAR struct dma_link_s *src_link;
|
|
};
|
|
#endif
|
|
|
|
/* The DMA vtable */
|
|
|
|
struct dma_ops_s
|
|
{
|
|
CODE int (*config)(FAR struct dma_chan_s *chan,
|
|
FAR const struct dma_config_s *cfg);
|
|
CODE int (*start)(FAR struct dma_chan_s *chan,
|
|
dma_callback_t callback, FAR void *arg,
|
|
uintptr_t dst, uintptr_t src, size_t len);
|
|
CODE int (*start_cyclic)(FAR struct dma_chan_s *chan,
|
|
dma_callback_t callback, FAR void *arg,
|
|
uintptr_t dst, uintptr_t src,
|
|
size_t len, size_t period_len);
|
|
#ifdef CONFIG_DMA_LINK
|
|
CODE int (*start_link)(FAR struct dma_chan_s *chan,
|
|
dma_callback_t callback, FAR void *arg,
|
|
unsigned int work_mode,
|
|
FAR struct dma_link_config_s *cfg);
|
|
#endif
|
|
CODE int (*stop)(FAR struct dma_chan_s *chan);
|
|
CODE int (*pause)(FAR struct dma_chan_s *chan);
|
|
CODE int (*resume)(FAR struct dma_chan_s *chan);
|
|
CODE size_t (*residual)(FAR struct dma_chan_s *chan);
|
|
};
|
|
|
|
/* This structure only defines the initial fields of the structure
|
|
* visible to the DMA client. The specific implementation may add
|
|
* additional device specific fields after the vtable.
|
|
*/
|
|
|
|
struct dma_chan_s
|
|
{
|
|
FAR const struct dma_ops_s *ops;
|
|
};
|
|
|
|
struct dma_dev_s
|
|
{
|
|
CODE FAR struct dma_chan_s *(*get_chan)(FAR struct dma_dev_s *dev,
|
|
unsigned int ident);
|
|
CODE void (*put_chan)(FAR struct dma_dev_s *dev,
|
|
FAR struct dma_chan_s *chan);
|
|
};
|
|
|
|
#endif /* __INCLUDE_NUTTX_DMA_DMA_H */
|