aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc/ti/knav_qmss.h
diff options
context:
space:
mode:
authorSandeep Nair <sandeep_n@ti.com>2014-02-28 10:47:50 -0500
committerSantosh Shilimkar <santosh.shilimkar@ti.com>2014-09-24 09:49:14 -0400
commit41f93af900a20d1a0a358b522b5129c89677e9dc (patch)
tree5f859b162874bd8ea22a71582b1cada01b2ec3f5 /drivers/soc/ti/knav_qmss.h
parenta4dfb8c41043dd6c2b9defbe846c44389c4b6f02 (diff)
soc: ti: add Keystone Navigator QMSS driver
The QMSS (Queue Manager Sub System) found on Keystone SOCs is one of the main hardware sub system which forms the backbone of the Keystone Multi-core Navigator. QMSS consist of queue managers, packed-data structure processors(PDSP), linking RAM, descriptor pools and infrastructure Packet DMA. The Queue Manager is a hardware module that is responsible for accelerating management of the packet queues. Packets are queued/de-queued by writing or reading descriptor address to a particular memory mapped location. The PDSPs perform QMSS related functions like accumulation, QoS, or event management. Linking RAM registers are used to link the descriptors which are stored in descriptor RAM. Descriptor RAM is configurable as internal or external memory. The QMSS driver manages the PDSP setups, linking RAM regions, queue pool management (allocation, push, pop and notify) and descriptor pool management. The specifics on the device tree bindings for QMSS can be found in: Documentation/devicetree/bindings/soc/keystone-navigator-qmss.txt Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Kumar Gala <galak@codeaurora.org> Cc: Olof Johansson <olof@lixom.net> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Grant Likely <grant.likely@linaro.org> Cc: Rob Herring <robh+dt@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Sandeep Nair <sandeep_n@ti.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Diffstat (limited to 'drivers/soc/ti/knav_qmss.h')
-rw-r--r--drivers/soc/ti/knav_qmss.h386
1 files changed, 386 insertions, 0 deletions
diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h
new file mode 100644
index 000000000000..bc9dcc8cc3ce
--- /dev/null
+++ b/drivers/soc/ti/knav_qmss.h
@@ -0,0 +1,386 @@
1/*
2 * Keystone Navigator QMSS driver internal header
3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
5 * Author: Sandeep Nair <sandeep_n@ti.com>
6 * Cyril Chemparathy <cyril@ti.com>
7 * Santosh Shilimkar <santosh.shilimkar@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#ifndef __KNAV_QMSS_H__
20#define __KNAV_QMSS_H__
21
22#define THRESH_GTE BIT(7)
23#define THRESH_LT 0
24
25#define PDSP_CTRL_PC_MASK 0xffff0000
26#define PDSP_CTRL_SOFT_RESET BIT(0)
27#define PDSP_CTRL_ENABLE BIT(1)
28#define PDSP_CTRL_RUNNING BIT(15)
29
30#define ACC_MAX_CHANNEL 48
31#define ACC_DEFAULT_PERIOD 25 /* usecs */
32
33#define ACC_CHANNEL_INT_BASE 2
34
35#define ACC_LIST_ENTRY_TYPE 1
36#define ACC_LIST_ENTRY_WORDS (1 << ACC_LIST_ENTRY_TYPE)
37#define ACC_LIST_ENTRY_QUEUE_IDX 0
38#define ACC_LIST_ENTRY_DESC_IDX (ACC_LIST_ENTRY_WORDS - 1)
39
40#define ACC_CMD_DISABLE_CHANNEL 0x80
41#define ACC_CMD_ENABLE_CHANNEL 0x81
42#define ACC_CFG_MULTI_QUEUE BIT(21)
43
44#define ACC_INTD_OFFSET_EOI (0x0010)
45#define ACC_INTD_OFFSET_COUNT(ch) (0x0300 + 4 * (ch))
46#define ACC_INTD_OFFSET_STATUS(ch) (0x0200 + 4 * ((ch) / 32))
47
48#define RANGE_MAX_IRQS 64
49
50#define ACC_DESCS_MAX SZ_1K
51#define ACC_DESCS_MASK (ACC_DESCS_MAX - 1)
52#define DESC_SIZE_MASK 0xful
53#define DESC_PTR_MASK (~DESC_SIZE_MASK)
54
55#define KNAV_NAME_SIZE 32
56
57enum knav_acc_result {
58 ACC_RET_IDLE,
59 ACC_RET_SUCCESS,
60 ACC_RET_INVALID_COMMAND,
61 ACC_RET_INVALID_CHANNEL,
62 ACC_RET_INACTIVE_CHANNEL,
63 ACC_RET_ACTIVE_CHANNEL,
64 ACC_RET_INVALID_QUEUE,
65 ACC_RET_INVALID_RET,
66};
67
68struct knav_reg_config {
69 u32 revision;
70 u32 __pad1;
71 u32 divert;
72 u32 link_ram_base0;
73 u32 link_ram_size0;
74 u32 link_ram_base1;
75 u32 __pad2[2];
76 u32 starvation[0];
77};
78
79struct knav_reg_region {
80 u32 base;
81 u32 start_index;
82 u32 size_count;
83 u32 __pad;
84};
85
86struct knav_reg_pdsp_regs {
87 u32 control;
88 u32 status;
89 u32 cycle_count;
90 u32 stall_count;
91};
92
93struct knav_reg_acc_command {
94 u32 command;
95 u32 queue_mask;
96 u32 list_phys;
97 u32 queue_num;
98 u32 timer_config;
99};
100
101struct knav_link_ram_block {
102 dma_addr_t phys;
103 void *virt;
104 size_t size;
105};
106
107struct knav_acc_info {
108 u32 pdsp_id;
109 u32 start_channel;
110 u32 list_entries;
111 u32 pacing_mode;
112 u32 timer_count;
113 int mem_size;
114 int list_size;
115 struct knav_pdsp_info *pdsp;
116};
117
118struct knav_acc_channel {
119 u32 channel;
120 u32 list_index;
121 u32 open_mask;
122 u32 *list_cpu[2];
123 dma_addr_t list_dma[2];
124 char name[KNAV_NAME_SIZE];
125 atomic_t retrigger_count;
126};
127
128struct knav_pdsp_info {
129 const char *name;
130 struct knav_reg_pdsp_regs __iomem *regs;
131 union {
132 void __iomem *command;
133 struct knav_reg_acc_command __iomem *acc_command;
134 u32 __iomem *qos_command;
135 };
136 void __iomem *intd;
137 u32 __iomem *iram;
138 const char *firmware;
139 u32 id;
140 struct list_head list;
141};
142
143struct knav_qmgr_info {
144 unsigned start_queue;
145 unsigned num_queues;
146 struct knav_reg_config __iomem *reg_config;
147 struct knav_reg_region __iomem *reg_region;
148 struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
149 void __iomem *reg_status;
150 struct list_head list;
151};
152
153#define KNAV_NUM_LINKRAM 2
154
155/**
156 * struct knav_queue_stats: queue statistics
157 * pushes: number of push operations
158 * pops: number of pop operations
159 * push_errors: number of push errors
160 * pop_errors: number of pop errors
161 * notifies: notifier counts
162 */
163struct knav_queue_stats {
164 atomic_t pushes;
165 atomic_t pops;
166 atomic_t push_errors;
167 atomic_t pop_errors;
168 atomic_t notifies;
169};
170
171/**
172 * struct knav_reg_queue: queue registers
173 * @entry_count: valid entries in the queue
174 * @byte_count: total byte count in thhe queue
175 * @packet_size: packet size for the queue
176 * @ptr_size_thresh: packet pointer size threshold
177 */
178struct knav_reg_queue {
179 u32 entry_count;
180 u32 byte_count;
181 u32 packet_size;
182 u32 ptr_size_thresh;
183};
184
185/**
186 * struct knav_region: qmss region info
187 * @dma_start, dma_end: start and end dma address
188 * @virt_start, virt_end: start and end virtual address
189 * @desc_size: descriptor size
190 * @used_desc: consumed descriptors
191 * @id: region number
192 * @num_desc: total descriptors
193 * @link_index: index of the first descriptor
194 * @name: region name
195 * @list: instance in the device's region list
196 * @pools: list of descriptor pools in the region
197 */
198struct knav_region {
199 dma_addr_t dma_start, dma_end;
200 void *virt_start, *virt_end;
201 unsigned desc_size;
202 unsigned used_desc;
203 unsigned id;
204 unsigned num_desc;
205 unsigned link_index;
206 const char *name;
207 struct list_head list;
208 struct list_head pools;
209};
210
211/**
212 * struct knav_pool: qmss pools
213 * @dev: device pointer
214 * @region: qmss region info
215 * @queue: queue registers
216 * @kdev: qmss device pointer
217 * @region_offset: offset from the base
218 * @num_desc: total descriptors
219 * @desc_size: descriptor size
220 * @region_id: region number
221 * @name: pool name
222 * @list: list head
223 * @region_inst: instance in the region's pool list
224 */
225struct knav_pool {
226 struct device *dev;
227 struct knav_region *region;
228 struct knav_queue *queue;
229 struct knav_device *kdev;
230 int region_offset;
231 int num_desc;
232 int desc_size;
233 int region_id;
234 const char *name;
235 struct list_head list;
236 struct list_head region_inst;
237};
238
239/**
240 * struct knav_queue_inst: qmss queue instace properties
241 * @descs: descriptor pointer
242 * @desc_head, desc_tail, desc_count: descriptor counters
243 * @acc: accumulator channel pointer
244 * @kdev: qmss device pointer
245 * @range: range info
246 * @qmgr: queue manager info
247 * @id: queue instace id
248 * @irq_num: irq line number
249 * @notify_needed: notifier needed based on queue type
250 * @num_notifiers: total notifiers
251 * @handles: list head
252 * @name: queue instance name
253 * @irq_name: irq line name
254 */
255struct knav_queue_inst {
256 u32 *descs;
257 atomic_t desc_head, desc_tail, desc_count;
258 struct knav_acc_channel *acc;
259 struct knav_device *kdev;
260 struct knav_range_info *range;
261 struct knav_qmgr_info *qmgr;
262 u32 id;
263 int irq_num;
264 int notify_needed;
265 atomic_t num_notifiers;
266 struct list_head handles;
267 const char *name;
268 const char *irq_name;
269};
270
271/**
272 * struct knav_queue: qmss queue properties
273 * @reg_push, reg_pop, reg_peek: push, pop queue registers
274 * @inst: qmss queue instace properties
275 * @notifier_fn: notifier function
276 * @notifier_fn_arg: notifier function argument
277 * @notifier_enabled: notier enabled for a give queue
278 * @rcu: rcu head
279 * @flags: queue flags
280 * @list: list head
281 */
282struct knav_queue {
283 struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
284 struct knav_queue_inst *inst;
285 struct knav_queue_stats stats;
286 knav_queue_notify_fn notifier_fn;
287 void *notifier_fn_arg;
288 atomic_t notifier_enabled;
289 struct rcu_head rcu;
290 unsigned flags;
291 struct list_head list;
292};
293
294struct knav_device {
295 struct device *dev;
296 unsigned base_id;
297 unsigned num_queues;
298 unsigned num_queues_in_use;
299 unsigned inst_shift;
300 struct knav_link_ram_block link_rams[KNAV_NUM_LINKRAM];
301 void *instances;
302 struct list_head regions;
303 struct list_head queue_ranges;
304 struct list_head pools;
305 struct list_head pdsps;
306 struct list_head qmgrs;
307};
308
309struct knav_range_ops {
310 int (*init_range)(struct knav_range_info *range);
311 int (*free_range)(struct knav_range_info *range);
312 int (*init_queue)(struct knav_range_info *range,
313 struct knav_queue_inst *inst);
314 int (*open_queue)(struct knav_range_info *range,
315 struct knav_queue_inst *inst, unsigned flags);
316 int (*close_queue)(struct knav_range_info *range,
317 struct knav_queue_inst *inst);
318 int (*set_notify)(struct knav_range_info *range,
319 struct knav_queue_inst *inst, bool enabled);
320};
321
322struct knav_irq_info {
323 int irq;
324 u32 cpu_map;
325};
326
327struct knav_range_info {
328 const char *name;
329 struct knav_device *kdev;
330 unsigned queue_base;
331 unsigned num_queues;
332 void *queue_base_inst;
333 unsigned flags;
334 struct list_head list;
335 struct knav_range_ops *ops;
336 struct knav_acc_info acc_info;
337 struct knav_acc_channel *acc;
338 unsigned num_irqs;
339 struct knav_irq_info irqs[RANGE_MAX_IRQS];
340};
341
342#define RANGE_RESERVED BIT(0)
343#define RANGE_HAS_IRQ BIT(1)
344#define RANGE_HAS_ACCUMULATOR BIT(2)
345#define RANGE_MULTI_QUEUE BIT(3)
346
347#define for_each_region(kdev, region) \
348 list_for_each_entry(region, &kdev->regions, list)
349
350#define first_region(kdev) \
351 list_first_entry(&kdev->regions, \
352 struct knav_region, list)
353
354#define for_each_queue_range(kdev, range) \
355 list_for_each_entry(range, &kdev->queue_ranges, list)
356
357#define first_queue_range(kdev) \
358 list_first_entry(&kdev->queue_ranges, \
359 struct knav_range_info, list)
360
361#define for_each_pool(kdev, pool) \
362 list_for_each_entry(pool, &kdev->pools, list)
363
364#define for_each_pdsp(kdev, pdsp) \
365 list_for_each_entry(pdsp, &kdev->pdsps, list)
366
367#define for_each_qmgr(kdev, qmgr) \
368 list_for_each_entry(qmgr, &kdev->qmgrs, list)
369
370static inline struct knav_pdsp_info *
371knav_find_pdsp(struct knav_device *kdev, unsigned pdsp_id)
372{
373 struct knav_pdsp_info *pdsp;
374
375 for_each_pdsp(kdev, pdsp)
376 if (pdsp_id == pdsp->id)
377 return pdsp;
378 return NULL;
379}
380
381extern int knav_init_acc_range(struct knav_device *kdev,
382 struct device_node *node,
383 struct knav_range_info *range);
384extern void knav_queue_notify(struct knav_queue_inst *inst);
385
386#endif /* __KNAV_QMSS_H__ */