1/*
2 * Copyright (c) 2014 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#ifndef DMA_CHANNEL_INTERNAL_H
11#define DMA_CHANNEL_INTERNAL_H
12
13#include <dma/dma_channel.h>
14
15struct dma_req_setup;
16
17/*
18 *
19 */
20typedef errval_t (*memcpy_fn_t)(struct dma_channel *chan,
21                                struct dma_req_setup *setup,
22                                dma_req_id_t *id);
23
24typedef errval_t (*memset_fn_t)(struct dma_channel *chan,
25                                struct dma_req_setup *setup,
26                                dma_req_id_t *id);
27
28typedef errval_t (*chan_poll_fn_t)(struct dma_channel *chan);
29
30/**
31 *
32 */
33struct dma_channel_fn
34{
35    memcpy_fn_t memcpy;
36    memset_fn_t memset;
37    chan_poll_fn_t poll;
38};
39
40/**
41 * Represents the generic part of a DMA channel
42 */
43struct dma_channel
44{
45    dma_chan_id_t id;               ///< unique DMA channel id
46    dma_chan_st_t state;            ///< channel state
47    struct dma_device *device;      ///< DMA device this channel belongs to
48    uint32_t max_xfer_size;         ///< maximum number of bytes per transfer
49
50    struct dma_mem mmio;
51
52    struct {
53        dma_irq_t type;
54        dma_irq_fn_t fn;
55        void *arg;
56    } irq;                          ///< Device level interrupt
57
58    struct {
59        uint32_t count;             ///< number of requests in the list
60        struct dma_request *head;   ///< start of the request list
61        struct dma_request *tail;   ///< end of the request list
62    } req_list;                     ///< list of submitted requests
63
64    uint64_t req_counter;           ///< number of requests issued so far
65
66    struct dma_channel_fn f;        ///< function pointers to channels
67};
68
69/*
70 * ----------------------------------------------------------------------------
71 * Request List Management
72 * ----------------------------------------------------------------------------
73 */
74
75/**
76 * \brief returns the first request on the submitted request queue of the channel
77 *
78 * \param chan  DMA channel
79 *
80 * \returns pointer to the DMA request
81 *          NULL if queue was empty
82 */
83struct dma_request *dma_channel_deq_request_head(struct dma_channel *chan);
84
85/**
86 * \brief returns the request with the given request ID
87 *
88 * \param chan  DMA channel
89 * \param id    DMA request id
90 *
91 * \returns pointer to the DMA request
92 *          NULL if queue was empty
93 */
94struct dma_request *dma_channel_deq_request_by_id(struct dma_channel *chan,
95                                                  dma_req_id_t id);
96
97/**
98 * \brief inserts a request into the head of a channel's request list
99 *
100 * \param chan  DMA channel
101 * \param req   DMA request to be inserted
102 */
103void dma_channel_enq_request_head(struct dma_channel *chan,
104                                  struct dma_request *req);
105
106/**
107 * \brief inserts a request at the end of the channels request list
108 *
109 * \param chan  DMA channel
110 * \param req   DMA request to be inserted
111 */
112void dma_channel_enq_request_tail(struct dma_channel *chan,
113                                  struct dma_request *req);
114
115/**
116 * \brief Submits the pending descriptors to the hardware queue
117 *
118 * \param chan  IOAT DMA channel
119 *
120 * \returns number of submitted descriptors
121 */
122uint16_t dma_channel_submit_pending(struct dma_channel *chan);
123
124
125/**
126 * \brief returns the next DMA request counter value to generate the req id.
127 *
128 * \param chan  DMA channel
129 *
130 * \returns request counter value
131 */
132static inline uint64_t dma_channel_incr_req_count(struct dma_channel *chan)
133{
134    return ++chan->req_counter;
135}
136
137
138#endif /* DMA_CHANNEL_INTERNAL_H */
139