aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwqueue/keystone_hwqueue.h')
-rw-r--r--drivers/hwqueue/keystone_hwqueue.h316
1 files changed, 316 insertions, 0 deletions
diff --git a/drivers/hwqueue/keystone_hwqueue.h b/drivers/hwqueue/keystone_hwqueue.h
new file mode 100644
index 00000000000..d8bd74d2b0a
--- /dev/null
+++ b/drivers/hwqueue/keystone_hwqueue.h
@@ -0,0 +1,316 @@
1/*
2 * Keystone hardware queue driver
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
5 * Contact: Prabhu Kuttiyam <pkuttiyam@ti.com>
6 * Cyril Chemparathy <cyril@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __KEYSTONE_HWQUEUE_H__
19#define __KEYSTONE_HWQUEUE_H__
20
21#define DESC_SIZE_MASK 0xful
22#define DESC_PTR_MASK (~DESC_SIZE_MASK)
23
24#define BITS(x) (BIT(x) - 1)
25
26#define THRESH_GTE BIT(7)
27#define THRESH_LT 0
28
29#define PDSP_CTRL_PC_MASK 0xffff0000
30#define PDSP_CTRL_SOFT_RESET BIT(0)
31#define PDSP_CTRL_ENABLE BIT(1)
32#define PDSP_CTRL_RUNNING BIT(15)
33
34#define ACC_MAX_CHANNEL 48
35#define ACC_DEFAULT_PERIOD 25 /* usecs */
36#define ACC_DESCS_MAX SZ_1K
37#define ACC_DESCS_MASK (ACC_DESCS_MAX - 1)
38#define ACC_CHANNEL_INT_BASE 2
39
40#define ACC_LIST_ENTRY_TYPE 1
41#define ACC_LIST_ENTRY_WORDS (1 << ACC_LIST_ENTRY_TYPE)
42#define ACC_LIST_ENTRY_QUEUE_IDX 0
43#define ACC_LIST_ENTRY_DESC_IDX (ACC_LIST_ENTRY_WORDS - 1)
44
45#define ACC_CMD_DISABLE_CHANNEL 0x80
46#define ACC_CMD_ENABLE_CHANNEL 0x81
47#define ACC_CFG_MULTI_QUEUE BIT(21)
48
49#define ACC_INTD_OFFSET_EOI (0x0010)
50#define ACC_INTD_OFFSET_COUNT(ch) (0x0300 + 4 * (ch))
51#define ACC_INTD_OFFSET_STATUS(ch) (0x0200 + 4 * ((ch) / 32))
52
53#define RANGE_MAX_IRQS 64
54
55enum khwq_acc_result {
56 ACC_RET_IDLE,
57 ACC_RET_SUCCESS,
58 ACC_RET_INVALID_COMMAND,
59 ACC_RET_INVALID_CHANNEL,
60 ACC_RET_INACTIVE_CHANNEL,
61 ACC_RET_ACTIVE_CHANNEL,
62 ACC_RET_INVALID_QUEUE,
63
64 ACC_RET_INVALID_RET,
65};
66
67struct khwq_reg_config {
68 u32 revision;
69 u32 __pad1;
70 u32 divert;
71 u32 link_ram_base0;
72 u32 link_ram_size0;
73 u32 link_ram_base1;
74 u32 __pad2[2];
75 u32 starvation[0];
76};
77
78struct khwq_reg_region {
79 u32 base;
80 u32 start_index;
81 u32 size_count;
82 u32 __pad;
83};
84
85struct khwq_reg_queue {
86 u32 entry_count;
87 u32 byte_count;
88 u32 packet_size;
89 u32 ptr_size_thresh;
90};
91
92struct khwq_reg_pdsp_regs {
93 u32 control;
94 u32 status;
95 u32 cycle_count;
96 u32 stall_count;
97};
98
99struct khwq_reg_acc_command {
100 u32 command;
101 u32 queue_mask;
102 u32 list_phys;
103 u32 queue_num;
104 u32 timer_config;
105};
106
107struct khwq_region {
108 const char *name;
109 unsigned used_desc;
110 struct list_head list;
111 unsigned id;
112 unsigned desc_size;
113 unsigned num_desc;
114 unsigned fixed_mem;
115 dma_addr_t next_pool_addr;
116 dma_addr_t dma_start, dma_end;
117 void *virt_start, *virt_end;
118 unsigned link_index;
119};
120
121struct khwq_pool_info {
122 const char *name;
123 struct khwq_region *region;
124 int region_offset;
125 int num_desc;
126 int desc_size;
127 int region_id;
128 struct hwqueue *queue;
129 struct list_head list;
130};
131
132struct khwq_link_ram_block {
133 dma_addr_t phys;
134 void *virt;
135 size_t size;
136};
137
138struct khwq_acc_info {
139 u32 pdsp_id;
140 u32 start_channel;
141 u32 list_entries;
142 u32 pacing_mode;
143 u32 timer_count;
144 int mem_size;
145 int list_size;
146 struct khwq_pdsp_info *pdsp;
147};
148
149struct khwq_acc_channel {
150 u32 channel;
151 u32 list_index;
152 u32 open_mask;
153 u32 *list_cpu[2];
154 dma_addr_t list_dma[2];
155 char name[32];
156 atomic_t retrigger_count;
157};
158
159struct khwq_pdsp_info {
160 const char *name;
161 struct khwq_reg_pdsp_regs __iomem *regs;
162 union {
163 void __iomem *command;
164 struct khwq_reg_acc_command __iomem *acc_command;
165 u32 __iomem *qos_command;
166 };
167 void __iomem *intd;
168 u32 __iomem *iram;
169 const char *firmware;
170 u32 id;
171 struct list_head list;
172 struct khwq_qos_info *qos_info;
173};
174
175struct khwq_range_ops;
176
177struct khwq_irq_info {
178 int irq;
179 u32 cpu_map;
180};
181
182struct khwq_range_info {
183 const char *name;
184 struct khwq_device *kdev;
185 unsigned queue_base;
186 unsigned num_queues;
187 unsigned flags;
188 struct list_head list;
189 struct khwq_range_ops *ops;
190 struct hwqueue_inst_ops inst_ops;
191 struct khwq_acc_info acc_info;
192 struct khwq_acc_channel *acc;
193 struct khwq_qos_info *qos_info;
194 unsigned num_irqs;
195 struct khwq_irq_info irqs[RANGE_MAX_IRQS];
196};
197
198struct khwq_range_ops {
199 int (*init_range)(struct khwq_range_info *range);
200 int (*free_range)(struct khwq_range_info *range);
201 int (*init_queue)(struct khwq_range_info *range,
202 struct hwqueue_instance *inst);
203 int (*open_queue)(struct khwq_range_info *range,
204 struct hwqueue_instance *inst, unsigned flags);
205 int (*close_queue)(struct khwq_range_info *range,
206 struct hwqueue_instance *inst);
207 int (*set_notify)(struct khwq_range_info *range,
208 struct hwqueue_instance *inst, bool enabled);
209};
210
211#define RANGE_RESERVED BIT(0)
212#define RANGE_HAS_IRQ BIT(1)
213#define RANGE_HAS_ACCUMULATOR BIT(2)
214#define RANGE_MULTI_QUEUE BIT(3)
215
216struct khwq_qmgr_info {
217 unsigned start_queue;
218 unsigned num_queues;
219 struct khwq_reg_config __iomem *reg_config;
220 struct khwq_reg_region __iomem *reg_region;
221 struct khwq_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
222 void __iomem *reg_status;
223 struct list_head list;
224};
225
226struct khwq_device {
227 struct device *dev;
228 struct clk *clk;
229 struct hwqueue_device hdev;
230 struct list_head regions;
231 struct khwq_link_ram_block link_rams[2];
232 unsigned num_queues;
233 unsigned base_id;
234 struct list_head queue_ranges;
235 struct list_head pools;
236 struct list_head pdsps;
237 struct list_head qmgrs;
238};
239
240struct khwq_desc {
241 u32 val;
242 unsigned size;
243 struct list_head list;
244};
245
246struct khwq_instance {
247 struct khwq_device *kdev;
248 struct khwq_range_info *range;
249 u32 *descs;
250 atomic_t desc_head, desc_tail, desc_count;
251 struct khwq_acc_channel *acc;
252 struct khwq_region *last; /* cache last region used */
253 struct khwq_qmgr_info *qmgr; /* cache qmgr for the instance */
254 int notify_needed;
255 int irq_num; /*irq num -ve for non-irq queues */
256 char irq_name[32];
257};
258
259#define to_hdev(_kdev) (&(_kdev)->hdev)
260#define from_hdev(_hdev) container_of(_hdev, struct khwq_device, hdev)
261
262#define for_each_region(kdev, region) \
263 list_for_each_entry(region, &kdev->regions, list)
264
265#define for_each_queue_range(kdev, range) \
266 list_for_each_entry(range, &kdev->queue_ranges, list)
267
268#define first_queue_range(kdev) \
269 list_first_entry(&kdev->queue_ranges, struct khwq_range_info, list)
270
271#define for_each_pool(kdev, pool) \
272 list_for_each_entry(pool, &kdev->pools, list)
273
274#define for_each_pdsp(kdev, pdsp) \
275 list_for_each_entry(pdsp, &kdev->pdsps, list)
276
277#define for_each_qmgr(kdev, qmgr) \
278 list_for_each_entry(qmgr, &kdev->qmgrs, list)
279
280#define for_each_policy(info, policy) \
281 list_for_each_entry(policy, &info->drop_policies, list)
282
283static inline struct khwq_pdsp_info *
284khwq_find_pdsp(struct khwq_device *kdev, unsigned pdsp_id)
285{
286 struct khwq_pdsp_info *pdsp;
287
288 for_each_pdsp(kdev, pdsp)
289 if (pdsp_id == pdsp->id)
290 return pdsp;
291 return NULL;
292}
293
294static inline struct khwq_qmgr_info *
295khwq_find_qmgr(struct hwqueue_instance *inst)
296{
297 struct khwq_device *kdev = from_hdev(inst->hdev);
298 unsigned id = hwqueue_inst_to_id(inst);
299 struct khwq_qmgr_info *qmgr;
300
301 for_each_qmgr(kdev, qmgr) {
302 if ((id >= qmgr->start_queue) &&
303 (id < qmgr->start_queue + qmgr->num_queues))
304 return qmgr;
305 }
306
307 return NULL;
308}
309
310int khwq_init_acc_range(struct khwq_device *kdev, struct device_node *node,
311 struct khwq_range_info *range);
312
313int khwq_init_qos_range(struct khwq_device *kdev, struct device_node *node,
314 struct khwq_range_info *range);
315
316#endif /* __KEYSTONE_HWQUEUE_H__ */