diff options
Diffstat (limited to 'drivers/hwqueue/keystone_hwqueue.h')
-rw-r--r-- | drivers/hwqueue/keystone_hwqueue.h | 316 |
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 | |||
55 | enum 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 | |||
67 | struct 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 | |||
78 | struct khwq_reg_region { | ||
79 | u32 base; | ||
80 | u32 start_index; | ||
81 | u32 size_count; | ||
82 | u32 __pad; | ||
83 | }; | ||
84 | |||
85 | struct khwq_reg_queue { | ||
86 | u32 entry_count; | ||
87 | u32 byte_count; | ||
88 | u32 packet_size; | ||
89 | u32 ptr_size_thresh; | ||
90 | }; | ||
91 | |||
92 | struct khwq_reg_pdsp_regs { | ||
93 | u32 control; | ||
94 | u32 status; | ||
95 | u32 cycle_count; | ||
96 | u32 stall_count; | ||
97 | }; | ||
98 | |||
99 | struct 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 | |||
107 | struct 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 | |||
121 | struct 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 | |||
132 | struct khwq_link_ram_block { | ||
133 | dma_addr_t phys; | ||
134 | void *virt; | ||
135 | size_t size; | ||
136 | }; | ||
137 | |||
138 | struct 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 | |||
149 | struct 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 | |||
159 | struct 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 | |||
175 | struct khwq_range_ops; | ||
176 | |||
177 | struct khwq_irq_info { | ||
178 | int irq; | ||
179 | u32 cpu_map; | ||
180 | }; | ||
181 | |||
182 | struct 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 | |||
198 | struct 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 | |||
216 | struct 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 | |||
226 | struct 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 | |||
240 | struct khwq_desc { | ||
241 | u32 val; | ||
242 | unsigned size; | ||
243 | struct list_head list; | ||
244 | }; | ||
245 | |||
246 | struct 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 | |||
283 | static inline struct khwq_pdsp_info * | ||
284 | khwq_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 | |||
294 | static inline struct khwq_qmgr_info * | ||
295 | khwq_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 | |||
310 | int khwq_init_acc_range(struct khwq_device *kdev, struct device_node *node, | ||
311 | struct khwq_range_info *range); | ||
312 | |||
313 | int khwq_init_qos_range(struct khwq_device *kdev, struct device_node *node, | ||
314 | struct khwq_range_info *range); | ||
315 | |||
316 | #endif /* __KEYSTONE_HWQUEUE_H__ */ | ||