|
@@ -188,25 +188,6 @@ enum dma_ctrl_flags {
|
|
DMA_PREP_FENCE = (1 << 5),
|
|
DMA_PREP_FENCE = (1 << 5),
|
|
};
|
|
};
|
|
|
|
|
|
-/**
|
|
|
|
- * enum dma_ctrl_cmd - DMA operations that can optionally be exercised
|
|
|
|
- * on a running channel.
|
|
|
|
- * @DMA_TERMINATE_ALL: terminate all ongoing transfers
|
|
|
|
- * @DMA_PAUSE: pause ongoing transfers
|
|
|
|
- * @DMA_RESUME: resume paused transfer
|
|
|
|
- * @DMA_SLAVE_CONFIG: this command is only implemented by DMA controllers
|
|
|
|
- * that need to runtime reconfigure the slave channels (as opposed to passing
|
|
|
|
- * configuration data in statically from the platform). An additional
|
|
|
|
- * argument of struct dma_slave_config must be passed in with this
|
|
|
|
- * command.
|
|
|
|
- */
|
|
|
|
-enum dma_ctrl_cmd {
|
|
|
|
- DMA_TERMINATE_ALL,
|
|
|
|
- DMA_PAUSE,
|
|
|
|
- DMA_RESUME,
|
|
|
|
- DMA_SLAVE_CONFIG,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* enum sum_check_bits - bit position of pq_check_flags
|
|
* enum sum_check_bits - bit position of pq_check_flags
|
|
*/
|
|
*/
|
|
@@ -336,9 +317,8 @@ enum dma_slave_buswidth {
|
|
* This struct is passed in as configuration data to a DMA engine
|
|
* 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.
|
|
* in order to set up a certain channel for DMA transport at runtime.
|
|
* The DMA device/engine has to provide support for an additional
|
|
* The DMA device/engine has to provide support for an additional
|
|
- * command in the channel config interface, DMA_SLAVE_CONFIG
|
|
|
|
- * and this struct will then be passed in as an argument to the
|
|
|
|
- * DMA engine device_control() function.
|
|
|
|
|
|
+ * callback in the dma_device structure, device_config and this struct
|
|
|
|
+ * will then be passed in as an argument to the function.
|
|
*
|
|
*
|
|
* The rationale for adding configuration information to this struct is as
|
|
* The rationale for adding configuration information to this struct is as
|
|
* follows: if it is likely that more than one DMA slave controllers in
|
|
* follows: if it is likely that more than one DMA slave controllers in
|
|
@@ -387,7 +367,7 @@ enum dma_residue_granularity {
|
|
/* struct dma_slave_caps - expose capabilities of a slave channel only
|
|
/* struct dma_slave_caps - expose capabilities of a slave channel only
|
|
*
|
|
*
|
|
* @src_addr_widths: bit mask of src addr widths the channel supports
|
|
* @src_addr_widths: bit mask of src addr widths the channel supports
|
|
- * @dstn_addr_widths: bit mask of dstn addr widths the channel supports
|
|
|
|
|
|
+ * @dst_addr_widths: bit mask of dstn addr widths the channel supports
|
|
* @directions: bit mask of slave direction the channel supported
|
|
* @directions: bit mask of slave direction the channel supported
|
|
* since the enum dma_transfer_direction is not defined as bits for each
|
|
* since the enum dma_transfer_direction is not defined as bits for each
|
|
* type of direction, the dma controller should fill (1 << <TYPE>) and same
|
|
* type of direction, the dma controller should fill (1 << <TYPE>) and same
|
|
@@ -398,7 +378,7 @@ enum dma_residue_granularity {
|
|
*/
|
|
*/
|
|
struct dma_slave_caps {
|
|
struct dma_slave_caps {
|
|
u32 src_addr_widths;
|
|
u32 src_addr_widths;
|
|
- u32 dstn_addr_widths;
|
|
|
|
|
|
+ u32 dst_addr_widths;
|
|
u32 directions;
|
|
u32 directions;
|
|
bool cmd_pause;
|
|
bool cmd_pause;
|
|
bool cmd_terminate;
|
|
bool cmd_terminate;
|
|
@@ -594,6 +574,14 @@ struct dma_tx_state {
|
|
* @fill_align: alignment shift for memset operations
|
|
* @fill_align: alignment shift for memset operations
|
|
* @dev_id: unique device ID
|
|
* @dev_id: unique device ID
|
|
* @dev: struct device reference for dma mapping api
|
|
* @dev: struct device reference for dma mapping api
|
|
|
|
+ * @src_addr_widths: bit mask of src addr widths the device supports
|
|
|
|
+ * @dst_addr_widths: bit mask of dst addr widths the device supports
|
|
|
|
+ * @directions: bit mask of slave direction the device supports since
|
|
|
|
+ * the enum dma_transfer_direction is not defined as bits for
|
|
|
|
+ * each type of direction, the dma controller should fill (1 <<
|
|
|
|
+ * <TYPE>) and same should be checked by controller as well
|
|
|
|
+ * @residue_granularity: granularity of the transfer residue reported
|
|
|
|
+ * by tx_status
|
|
* @device_alloc_chan_resources: allocate resources and return the
|
|
* @device_alloc_chan_resources: allocate resources and return the
|
|
* number of allocated descriptors
|
|
* number of allocated descriptors
|
|
* @device_free_chan_resources: release DMA channel's resources
|
|
* @device_free_chan_resources: release DMA channel's resources
|
|
@@ -608,14 +596,19 @@ struct dma_tx_state {
|
|
* The function takes a buffer of size buf_len. The callback function will
|
|
* The function takes a buffer of size buf_len. The callback function will
|
|
* be called after period_len bytes have been transferred.
|
|
* be called after period_len bytes have been transferred.
|
|
* @device_prep_interleaved_dma: Transfer expression in a generic way.
|
|
* @device_prep_interleaved_dma: Transfer expression in a generic way.
|
|
- * @device_control: manipulate all pending operations on a channel, returns
|
|
|
|
- * zero or error code
|
|
|
|
|
|
+ * @device_config: Pushes a new configuration to a channel, return 0 or an error
|
|
|
|
+ * code
|
|
|
|
+ * @device_pause: Pauses any transfer happening on a channel. Returns
|
|
|
|
+ * 0 or an error code
|
|
|
|
+ * @device_resume: Resumes any transfer on a channel previously
|
|
|
|
+ * paused. Returns 0 or an error code
|
|
|
|
+ * @device_terminate_all: Aborts all transfers on a channel. Returns 0
|
|
|
|
+ * or an error code
|
|
* @device_tx_status: poll for transaction completion, the optional
|
|
* @device_tx_status: poll for transaction completion, the optional
|
|
* txstate parameter can be supplied with a pointer to get a
|
|
* txstate parameter can be supplied with a pointer to get a
|
|
* struct with auxiliary transfer status information, otherwise the call
|
|
* struct with auxiliary transfer status information, otherwise the call
|
|
* will just return a simple status code
|
|
* will just return a simple status code
|
|
* @device_issue_pending: push pending transactions to hardware
|
|
* @device_issue_pending: push pending transactions to hardware
|
|
- * @device_slave_caps: return the slave channel capabilities
|
|
|
|
*/
|
|
*/
|
|
struct dma_device {
|
|
struct dma_device {
|
|
|
|
|
|
@@ -635,14 +628,19 @@ struct dma_device {
|
|
int dev_id;
|
|
int dev_id;
|
|
struct device *dev;
|
|
struct device *dev;
|
|
|
|
|
|
|
|
+ u32 src_addr_widths;
|
|
|
|
+ u32 dst_addr_widths;
|
|
|
|
+ u32 directions;
|
|
|
|
+ enum dma_residue_granularity residue_granularity;
|
|
|
|
+
|
|
int (*device_alloc_chan_resources)(struct dma_chan *chan);
|
|
int (*device_alloc_chan_resources)(struct dma_chan *chan);
|
|
void (*device_free_chan_resources)(struct dma_chan *chan);
|
|
void (*device_free_chan_resources)(struct dma_chan *chan);
|
|
|
|
|
|
struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)(
|
|
struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)(
|
|
- struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
|
|
|
|
|
|
+ struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
|
|
size_t len, unsigned long flags);
|
|
size_t len, unsigned long flags);
|
|
struct dma_async_tx_descriptor *(*device_prep_dma_xor)(
|
|
struct dma_async_tx_descriptor *(*device_prep_dma_xor)(
|
|
- struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
|
|
|
|
|
|
+ struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
|
|
unsigned int src_cnt, size_t len, unsigned long flags);
|
|
unsigned int src_cnt, size_t len, unsigned long flags);
|
|
struct dma_async_tx_descriptor *(*device_prep_dma_xor_val)(
|
|
struct dma_async_tx_descriptor *(*device_prep_dma_xor_val)(
|
|
struct dma_chan *chan, dma_addr_t *src, unsigned int src_cnt,
|
|
struct dma_chan *chan, dma_addr_t *src, unsigned int src_cnt,
|
|
@@ -674,31 +672,26 @@ struct dma_device {
|
|
struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
|
|
struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
|
|
struct dma_chan *chan, struct dma_interleaved_template *xt,
|
|
struct dma_chan *chan, struct dma_interleaved_template *xt,
|
|
unsigned long flags);
|
|
unsigned long flags);
|
|
- int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
|
|
|
|
- unsigned long arg);
|
|
|
|
|
|
+
|
|
|
|
+ int (*device_config)(struct dma_chan *chan,
|
|
|
|
+ struct dma_slave_config *config);
|
|
|
|
+ int (*device_pause)(struct dma_chan *chan);
|
|
|
|
+ int (*device_resume)(struct dma_chan *chan);
|
|
|
|
+ int (*device_terminate_all)(struct dma_chan *chan);
|
|
|
|
|
|
enum dma_status (*device_tx_status)(struct dma_chan *chan,
|
|
enum dma_status (*device_tx_status)(struct dma_chan *chan,
|
|
dma_cookie_t cookie,
|
|
dma_cookie_t cookie,
|
|
struct dma_tx_state *txstate);
|
|
struct dma_tx_state *txstate);
|
|
void (*device_issue_pending)(struct dma_chan *chan);
|
|
void (*device_issue_pending)(struct dma_chan *chan);
|
|
- int (*device_slave_caps)(struct dma_chan *chan, struct dma_slave_caps *caps);
|
|
|
|
};
|
|
};
|
|
|
|
|
|
-static inline int dmaengine_device_control(struct dma_chan *chan,
|
|
|
|
- enum dma_ctrl_cmd cmd,
|
|
|
|
- unsigned long arg)
|
|
|
|
-{
|
|
|
|
- if (chan->device->device_control)
|
|
|
|
- return chan->device->device_control(chan, cmd, arg);
|
|
|
|
-
|
|
|
|
- return -ENOSYS;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static inline int dmaengine_slave_config(struct dma_chan *chan,
|
|
static inline int dmaengine_slave_config(struct dma_chan *chan,
|
|
struct dma_slave_config *config)
|
|
struct dma_slave_config *config)
|
|
{
|
|
{
|
|
- return dmaengine_device_control(chan, DMA_SLAVE_CONFIG,
|
|
|
|
- (unsigned long)config);
|
|
|
|
|
|
+ if (chan->device->device_config)
|
|
|
|
+ return chan->device->device_config(chan, config);
|
|
|
|
+
|
|
|
|
+ return -ENOSYS;
|
|
}
|
|
}
|
|
|
|
|
|
static inline bool is_slave_direction(enum dma_transfer_direction direction)
|
|
static inline bool is_slave_direction(enum dma_transfer_direction direction)
|
|
@@ -765,34 +758,28 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg(
|
|
src_sg, src_nents, flags);
|
|
src_sg, src_nents, flags);
|
|
}
|
|
}
|
|
|
|
|
|
-static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
|
|
|
|
-{
|
|
|
|
- if (!chan || !caps)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- /* check if the channel supports slave transactions */
|
|
|
|
- if (!test_bit(DMA_SLAVE, chan->device->cap_mask.bits))
|
|
|
|
- return -ENXIO;
|
|
|
|
-
|
|
|
|
- if (chan->device->device_slave_caps)
|
|
|
|
- return chan->device->device_slave_caps(chan, caps);
|
|
|
|
-
|
|
|
|
- return -ENXIO;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static inline int dmaengine_terminate_all(struct dma_chan *chan)
|
|
static inline int dmaengine_terminate_all(struct dma_chan *chan)
|
|
{
|
|
{
|
|
- return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
|
|
|
|
|
|
+ if (chan->device->device_terminate_all)
|
|
|
|
+ return chan->device->device_terminate_all(chan);
|
|
|
|
+
|
|
|
|
+ return -ENOSYS;
|
|
}
|
|
}
|
|
|
|
|
|
static inline int dmaengine_pause(struct dma_chan *chan)
|
|
static inline int dmaengine_pause(struct dma_chan *chan)
|
|
{
|
|
{
|
|
- return dmaengine_device_control(chan, DMA_PAUSE, 0);
|
|
|
|
|
|
+ if (chan->device->device_pause)
|
|
|
|
+ return chan->device->device_pause(chan);
|
|
|
|
+
|
|
|
|
+ return -ENOSYS;
|
|
}
|
|
}
|
|
|
|
|
|
static inline int dmaengine_resume(struct dma_chan *chan)
|
|
static inline int dmaengine_resume(struct dma_chan *chan)
|
|
{
|
|
{
|
|
- return dmaengine_device_control(chan, DMA_RESUME, 0);
|
|
|
|
|
|
+ if (chan->device->device_resume)
|
|
|
|
+ return chan->device->device_resume(chan);
|
|
|
|
+
|
|
|
|
+ return -ENOSYS;
|
|
}
|
|
}
|
|
|
|
|
|
static inline enum dma_status dmaengine_tx_status(struct dma_chan *chan,
|
|
static inline enum dma_status dmaengine_tx_status(struct dma_chan *chan,
|
|
@@ -1059,6 +1046,7 @@ struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
|
|
const char *name);
|
|
const char *name);
|
|
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
|
|
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
|
|
void dma_release_channel(struct dma_chan *chan);
|
|
void dma_release_channel(struct dma_chan *chan);
|
|
|
|
+int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
|
|
#else
|
|
#else
|
|
static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
|
|
static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
|
|
{
|
|
{
|
|
@@ -1093,6 +1081,11 @@ static inline struct dma_chan *dma_request_slave_channel(struct device *dev,
|
|
static inline void dma_release_channel(struct dma_chan *chan)
|
|
static inline void dma_release_channel(struct dma_chan *chan)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
+static inline int dma_get_slave_caps(struct dma_chan *chan,
|
|
|
|
+ struct dma_slave_caps *caps)
|
|
|
|
+{
|
|
|
|
+ return -ENXIO;
|
|
|
|
+}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* --- DMA device --- */
|
|
/* --- DMA device --- */
|