1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#ifndef QCOM_HIDMA_H
17#define QCOM_HIDMA_H
18
19#include <linux/kfifo.h>
20#include <linux/interrupt.h>
21#include <linux/dmaengine.h>
22
23#define HIDMA_TRE_SIZE 32
24#define HIDMA_TRE_CFG_IDX 0
25#define HIDMA_TRE_LEN_IDX 1
26#define HIDMA_TRE_SRC_LOW_IDX 2
27#define HIDMA_TRE_SRC_HI_IDX 3
28#define HIDMA_TRE_DEST_LOW_IDX 4
29#define HIDMA_TRE_DEST_HI_IDX 5
30
31enum tre_type {
32 HIDMA_TRE_MEMCPY = 3,
33 HIDMA_TRE_MEMSET = 4,
34};
35
36struct hidma_tre {
37 atomic_t allocated;
38 bool queued;
39 u16 status;
40 u32 idx;
41 u32 dma_sig;
42 const char *dev_name;
43 void (*callback)(void *data);
44 void *data;
45 struct hidma_lldev *lldev;
46 u32 tre_local[HIDMA_TRE_SIZE / sizeof(u32) + 1];
47 u32 tre_index;
48 u32 int_flags;
49 u8 err_info;
50 u8 err_code;
51};
52
53struct hidma_lldev {
54 bool msi_support;
55 bool initialized;
56 u8 trch_state;
57 u8 evch_state;
58 u8 chidx;
59 u32 nr_tres;
60 spinlock_t lock;
61 struct hidma_tre *trepool;
62 struct device *dev;
63 void __iomem *trca;
64 void __iomem *evca;
65 struct hidma_tre
66 **pending_tre_list;
67 atomic_t pending_tre_count;
68
69 void *tre_ring;
70 dma_addr_t tre_dma;
71 u32 tre_ring_size;
72 u32 tre_processed_off;
73
74 void *evre_ring;
75 dma_addr_t evre_dma;
76 u32 evre_ring_size;
77 u32 evre_processed_off;
78
79 u32 tre_write_offset;
80 struct tasklet_struct task;
81 DECLARE_KFIFO_PTR(handoff_fifo,
82 struct hidma_tre *);
83};
84
85struct hidma_desc {
86 struct dma_async_tx_descriptor desc;
87
88 struct list_head node;
89 u32 tre_ch;
90};
91
92struct hidma_chan {
93 bool paused;
94 bool allocated;
95 char dbg_name[16];
96 u32 dma_sig;
97 dma_cookie_t last_success;
98
99
100
101
102
103
104 struct dentry *debugfs;
105 struct dentry *stats;
106 struct hidma_dev *dmadev;
107 struct hidma_desc *running;
108
109 struct dma_chan chan;
110 struct list_head free;
111 struct list_head prepared;
112 struct list_head queued;
113 struct list_head active;
114 struct list_head completed;
115
116
117 spinlock_t lock;
118};
119
120struct hidma_dev {
121 int irq;
122 int chidx;
123 u32 nr_descriptors;
124 int msi_virqbase;
125
126 struct hidma_lldev *lldev;
127 void __iomem *dev_trca;
128 struct resource *trca_resource;
129 void __iomem *dev_evca;
130 struct resource *evca_resource;
131
132
133 spinlock_t lock;
134 struct dma_device ddev;
135
136 struct dentry *debugfs;
137 struct dentry *stats;
138
139
140 struct device_attribute *chid_attrs;
141
142
143 struct tasklet_struct task;
144};
145
146int hidma_ll_request(struct hidma_lldev *llhndl, u32 dev_id,
147 const char *dev_name,
148 void (*callback)(void *data), void *data, u32 *tre_ch);
149
150void hidma_ll_free(struct hidma_lldev *llhndl, u32 tre_ch);
151enum dma_status hidma_ll_status(struct hidma_lldev *llhndl, u32 tre_ch);
152bool hidma_ll_isenabled(struct hidma_lldev *llhndl);
153void hidma_ll_queue_request(struct hidma_lldev *llhndl, u32 tre_ch);
154void hidma_ll_start(struct hidma_lldev *llhndl);
155int hidma_ll_disable(struct hidma_lldev *lldev);
156int hidma_ll_enable(struct hidma_lldev *llhndl);
157void hidma_ll_set_transfer_params(struct hidma_lldev *llhndl, u32 tre_ch,
158 dma_addr_t src, dma_addr_t dest, u32 len, u32 flags, u32 txntype);
159void hidma_ll_setup_irq(struct hidma_lldev *lldev, bool msi);
160int hidma_ll_setup(struct hidma_lldev *lldev);
161struct hidma_lldev *hidma_ll_init(struct device *dev, u32 max_channels,
162 void __iomem *trca, void __iomem *evca,
163 u8 chidx);
164int hidma_ll_uninit(struct hidma_lldev *llhndl);
165irqreturn_t hidma_ll_inthandler(int irq, void *arg);
166irqreturn_t hidma_ll_inthandler_msi(int irq, void *arg, int cause);
167void hidma_cleanup_pending_tre(struct hidma_lldev *llhndl, u8 err_info,
168 u8 err_code);
169int hidma_debug_init(struct hidma_dev *dmadev);
170void hidma_debug_uninit(struct hidma_dev *dmadev);
171#endif
172