1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Keystone Navigator QMSS driver internal header
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
6*4882a593Smuzhiyun * Author: Sandeep Nair <sandeep_n@ti.com>
7*4882a593Smuzhiyun * Cyril Chemparathy <cyril@ti.com>
8*4882a593Smuzhiyun * Santosh Shilimkar <santosh.shilimkar@ti.com>
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #ifndef __KNAV_QMSS_H__
12*4882a593Smuzhiyun #define __KNAV_QMSS_H__
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #include <linux/percpu.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define THRESH_GTE BIT(7)
17*4882a593Smuzhiyun #define THRESH_LT 0
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #define PDSP_CTRL_PC_MASK 0xffff0000
20*4882a593Smuzhiyun #define PDSP_CTRL_SOFT_RESET BIT(0)
21*4882a593Smuzhiyun #define PDSP_CTRL_ENABLE BIT(1)
22*4882a593Smuzhiyun #define PDSP_CTRL_RUNNING BIT(15)
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #define ACC_MAX_CHANNEL 48
25*4882a593Smuzhiyun #define ACC_DEFAULT_PERIOD 25 /* usecs */
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #define ACC_CHANNEL_INT_BASE 2
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define ACC_LIST_ENTRY_TYPE 1
30*4882a593Smuzhiyun #define ACC_LIST_ENTRY_WORDS (1 << ACC_LIST_ENTRY_TYPE)
31*4882a593Smuzhiyun #define ACC_LIST_ENTRY_QUEUE_IDX 0
32*4882a593Smuzhiyun #define ACC_LIST_ENTRY_DESC_IDX (ACC_LIST_ENTRY_WORDS - 1)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define ACC_CMD_DISABLE_CHANNEL 0x80
35*4882a593Smuzhiyun #define ACC_CMD_ENABLE_CHANNEL 0x81
36*4882a593Smuzhiyun #define ACC_CFG_MULTI_QUEUE BIT(21)
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #define ACC_INTD_OFFSET_EOI (0x0010)
39*4882a593Smuzhiyun #define ACC_INTD_OFFSET_COUNT(ch) (0x0300 + 4 * (ch))
40*4882a593Smuzhiyun #define ACC_INTD_OFFSET_STATUS(ch) (0x0200 + 4 * ((ch) / 32))
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #define RANGE_MAX_IRQS 64
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define ACC_DESCS_MAX SZ_1K
45*4882a593Smuzhiyun #define ACC_DESCS_MASK (ACC_DESCS_MAX - 1)
46*4882a593Smuzhiyun #define DESC_SIZE_MASK 0xful
47*4882a593Smuzhiyun #define DESC_PTR_MASK (~DESC_SIZE_MASK)
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #define KNAV_NAME_SIZE 32
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun enum knav_acc_result {
52*4882a593Smuzhiyun ACC_RET_IDLE,
53*4882a593Smuzhiyun ACC_RET_SUCCESS,
54*4882a593Smuzhiyun ACC_RET_INVALID_COMMAND,
55*4882a593Smuzhiyun ACC_RET_INVALID_CHANNEL,
56*4882a593Smuzhiyun ACC_RET_INACTIVE_CHANNEL,
57*4882a593Smuzhiyun ACC_RET_ACTIVE_CHANNEL,
58*4882a593Smuzhiyun ACC_RET_INVALID_QUEUE,
59*4882a593Smuzhiyun ACC_RET_INVALID_RET,
60*4882a593Smuzhiyun };
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun struct knav_reg_config {
63*4882a593Smuzhiyun u32 revision;
64*4882a593Smuzhiyun u32 __pad1;
65*4882a593Smuzhiyun u32 divert;
66*4882a593Smuzhiyun u32 link_ram_base0;
67*4882a593Smuzhiyun u32 link_ram_size0;
68*4882a593Smuzhiyun u32 link_ram_base1;
69*4882a593Smuzhiyun u32 __pad2[2];
70*4882a593Smuzhiyun u32 starvation[];
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun struct knav_reg_region {
74*4882a593Smuzhiyun u32 base;
75*4882a593Smuzhiyun u32 start_index;
76*4882a593Smuzhiyun u32 size_count;
77*4882a593Smuzhiyun u32 __pad;
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun struct knav_reg_pdsp_regs {
81*4882a593Smuzhiyun u32 control;
82*4882a593Smuzhiyun u32 status;
83*4882a593Smuzhiyun u32 cycle_count;
84*4882a593Smuzhiyun u32 stall_count;
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun struct knav_reg_acc_command {
88*4882a593Smuzhiyun u32 command;
89*4882a593Smuzhiyun u32 queue_mask;
90*4882a593Smuzhiyun u32 list_dma;
91*4882a593Smuzhiyun u32 queue_num;
92*4882a593Smuzhiyun u32 timer_config;
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun struct knav_link_ram_block {
96*4882a593Smuzhiyun dma_addr_t dma;
97*4882a593Smuzhiyun void *virt;
98*4882a593Smuzhiyun size_t size;
99*4882a593Smuzhiyun };
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun struct knav_acc_info {
102*4882a593Smuzhiyun u32 pdsp_id;
103*4882a593Smuzhiyun u32 start_channel;
104*4882a593Smuzhiyun u32 list_entries;
105*4882a593Smuzhiyun u32 pacing_mode;
106*4882a593Smuzhiyun u32 timer_count;
107*4882a593Smuzhiyun int mem_size;
108*4882a593Smuzhiyun int list_size;
109*4882a593Smuzhiyun struct knav_pdsp_info *pdsp;
110*4882a593Smuzhiyun };
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun struct knav_acc_channel {
113*4882a593Smuzhiyun u32 channel;
114*4882a593Smuzhiyun u32 list_index;
115*4882a593Smuzhiyun u32 open_mask;
116*4882a593Smuzhiyun u32 *list_cpu[2];
117*4882a593Smuzhiyun dma_addr_t list_dma[2];
118*4882a593Smuzhiyun char name[KNAV_NAME_SIZE];
119*4882a593Smuzhiyun atomic_t retrigger_count;
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun struct knav_pdsp_info {
123*4882a593Smuzhiyun const char *name;
124*4882a593Smuzhiyun struct knav_reg_pdsp_regs __iomem *regs;
125*4882a593Smuzhiyun union {
126*4882a593Smuzhiyun void __iomem *command;
127*4882a593Smuzhiyun struct knav_reg_acc_command __iomem *acc_command;
128*4882a593Smuzhiyun u32 __iomem *qos_command;
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun void __iomem *intd;
131*4882a593Smuzhiyun u32 __iomem *iram;
132*4882a593Smuzhiyun u32 id;
133*4882a593Smuzhiyun struct list_head list;
134*4882a593Smuzhiyun bool loaded;
135*4882a593Smuzhiyun bool started;
136*4882a593Smuzhiyun };
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun struct knav_qmgr_info {
139*4882a593Smuzhiyun unsigned start_queue;
140*4882a593Smuzhiyun unsigned num_queues;
141*4882a593Smuzhiyun struct knav_reg_config __iomem *reg_config;
142*4882a593Smuzhiyun struct knav_reg_region __iomem *reg_region;
143*4882a593Smuzhiyun struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
144*4882a593Smuzhiyun void __iomem *reg_status;
145*4882a593Smuzhiyun struct list_head list;
146*4882a593Smuzhiyun };
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun #define KNAV_NUM_LINKRAM 2
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun /**
151*4882a593Smuzhiyun * struct knav_queue_stats: queue statistics
152*4882a593Smuzhiyun * pushes: number of push operations
153*4882a593Smuzhiyun * pops: number of pop operations
154*4882a593Smuzhiyun * push_errors: number of push errors
155*4882a593Smuzhiyun * pop_errors: number of pop errors
156*4882a593Smuzhiyun * notifies: notifier counts
157*4882a593Smuzhiyun */
158*4882a593Smuzhiyun struct knav_queue_stats {
159*4882a593Smuzhiyun unsigned int pushes;
160*4882a593Smuzhiyun unsigned int pops;
161*4882a593Smuzhiyun unsigned int push_errors;
162*4882a593Smuzhiyun unsigned int pop_errors;
163*4882a593Smuzhiyun unsigned int notifies;
164*4882a593Smuzhiyun };
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun /**
167*4882a593Smuzhiyun * struct knav_reg_queue: queue registers
168*4882a593Smuzhiyun * @entry_count: valid entries in the queue
169*4882a593Smuzhiyun * @byte_count: total byte count in thhe queue
170*4882a593Smuzhiyun * @packet_size: packet size for the queue
171*4882a593Smuzhiyun * @ptr_size_thresh: packet pointer size threshold
172*4882a593Smuzhiyun */
173*4882a593Smuzhiyun struct knav_reg_queue {
174*4882a593Smuzhiyun u32 entry_count;
175*4882a593Smuzhiyun u32 byte_count;
176*4882a593Smuzhiyun u32 packet_size;
177*4882a593Smuzhiyun u32 ptr_size_thresh;
178*4882a593Smuzhiyun };
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun /**
181*4882a593Smuzhiyun * struct knav_region: qmss region info
182*4882a593Smuzhiyun * @dma_start, dma_end: start and end dma address
183*4882a593Smuzhiyun * @virt_start, virt_end: start and end virtual address
184*4882a593Smuzhiyun * @desc_size: descriptor size
185*4882a593Smuzhiyun * @used_desc: consumed descriptors
186*4882a593Smuzhiyun * @id: region number
187*4882a593Smuzhiyun * @num_desc: total descriptors
188*4882a593Smuzhiyun * @link_index: index of the first descriptor
189*4882a593Smuzhiyun * @name: region name
190*4882a593Smuzhiyun * @list: instance in the device's region list
191*4882a593Smuzhiyun * @pools: list of descriptor pools in the region
192*4882a593Smuzhiyun */
193*4882a593Smuzhiyun struct knav_region {
194*4882a593Smuzhiyun dma_addr_t dma_start, dma_end;
195*4882a593Smuzhiyun void *virt_start, *virt_end;
196*4882a593Smuzhiyun unsigned desc_size;
197*4882a593Smuzhiyun unsigned used_desc;
198*4882a593Smuzhiyun unsigned id;
199*4882a593Smuzhiyun unsigned num_desc;
200*4882a593Smuzhiyun unsigned link_index;
201*4882a593Smuzhiyun const char *name;
202*4882a593Smuzhiyun struct list_head list;
203*4882a593Smuzhiyun struct list_head pools;
204*4882a593Smuzhiyun };
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun /**
207*4882a593Smuzhiyun * struct knav_pool: qmss pools
208*4882a593Smuzhiyun * @dev: device pointer
209*4882a593Smuzhiyun * @region: qmss region info
210*4882a593Smuzhiyun * @queue: queue registers
211*4882a593Smuzhiyun * @kdev: qmss device pointer
212*4882a593Smuzhiyun * @region_offset: offset from the base
213*4882a593Smuzhiyun * @num_desc: total descriptors
214*4882a593Smuzhiyun * @desc_size: descriptor size
215*4882a593Smuzhiyun * @region_id: region number
216*4882a593Smuzhiyun * @name: pool name
217*4882a593Smuzhiyun * @list: list head
218*4882a593Smuzhiyun * @region_inst: instance in the region's pool list
219*4882a593Smuzhiyun */
220*4882a593Smuzhiyun struct knav_pool {
221*4882a593Smuzhiyun struct device *dev;
222*4882a593Smuzhiyun struct knav_region *region;
223*4882a593Smuzhiyun struct knav_queue *queue;
224*4882a593Smuzhiyun struct knav_device *kdev;
225*4882a593Smuzhiyun int region_offset;
226*4882a593Smuzhiyun int num_desc;
227*4882a593Smuzhiyun int desc_size;
228*4882a593Smuzhiyun int region_id;
229*4882a593Smuzhiyun const char *name;
230*4882a593Smuzhiyun struct list_head list;
231*4882a593Smuzhiyun struct list_head region_inst;
232*4882a593Smuzhiyun };
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun /**
235*4882a593Smuzhiyun * struct knav_queue_inst: qmss queue instance properties
236*4882a593Smuzhiyun * @descs: descriptor pointer
237*4882a593Smuzhiyun * @desc_head, desc_tail, desc_count: descriptor counters
238*4882a593Smuzhiyun * @acc: accumulator channel pointer
239*4882a593Smuzhiyun * @kdev: qmss device pointer
240*4882a593Smuzhiyun * @range: range info
241*4882a593Smuzhiyun * @qmgr: queue manager info
242*4882a593Smuzhiyun * @id: queue instance id
243*4882a593Smuzhiyun * @irq_num: irq line number
244*4882a593Smuzhiyun * @notify_needed: notifier needed based on queue type
245*4882a593Smuzhiyun * @num_notifiers: total notifiers
246*4882a593Smuzhiyun * @handles: list head
247*4882a593Smuzhiyun * @name: queue instance name
248*4882a593Smuzhiyun * @irq_name: irq line name
249*4882a593Smuzhiyun */
250*4882a593Smuzhiyun struct knav_queue_inst {
251*4882a593Smuzhiyun u32 *descs;
252*4882a593Smuzhiyun atomic_t desc_head, desc_tail, desc_count;
253*4882a593Smuzhiyun struct knav_acc_channel *acc;
254*4882a593Smuzhiyun struct knav_device *kdev;
255*4882a593Smuzhiyun struct knav_range_info *range;
256*4882a593Smuzhiyun struct knav_qmgr_info *qmgr;
257*4882a593Smuzhiyun u32 id;
258*4882a593Smuzhiyun int irq_num;
259*4882a593Smuzhiyun int notify_needed;
260*4882a593Smuzhiyun atomic_t num_notifiers;
261*4882a593Smuzhiyun struct list_head handles;
262*4882a593Smuzhiyun const char *name;
263*4882a593Smuzhiyun const char *irq_name;
264*4882a593Smuzhiyun };
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun /**
267*4882a593Smuzhiyun * struct knav_queue: qmss queue properties
268*4882a593Smuzhiyun * @reg_push, reg_pop, reg_peek: push, pop queue registers
269*4882a593Smuzhiyun * @inst: qmss queue instance properties
270*4882a593Smuzhiyun * @notifier_fn: notifier function
271*4882a593Smuzhiyun * @notifier_fn_arg: notifier function argument
272*4882a593Smuzhiyun * @notifier_enabled: notier enabled for a give queue
273*4882a593Smuzhiyun * @rcu: rcu head
274*4882a593Smuzhiyun * @flags: queue flags
275*4882a593Smuzhiyun * @list: list head
276*4882a593Smuzhiyun */
277*4882a593Smuzhiyun struct knav_queue {
278*4882a593Smuzhiyun struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
279*4882a593Smuzhiyun struct knav_queue_inst *inst;
280*4882a593Smuzhiyun struct knav_queue_stats __percpu *stats;
281*4882a593Smuzhiyun knav_queue_notify_fn notifier_fn;
282*4882a593Smuzhiyun void *notifier_fn_arg;
283*4882a593Smuzhiyun atomic_t notifier_enabled;
284*4882a593Smuzhiyun struct rcu_head rcu;
285*4882a593Smuzhiyun unsigned flags;
286*4882a593Smuzhiyun struct list_head list;
287*4882a593Smuzhiyun };
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun enum qmss_version {
290*4882a593Smuzhiyun QMSS,
291*4882a593Smuzhiyun QMSS_66AK2G,
292*4882a593Smuzhiyun };
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun struct knav_device {
295*4882a593Smuzhiyun struct device *dev;
296*4882a593Smuzhiyun unsigned base_id;
297*4882a593Smuzhiyun unsigned num_queues;
298*4882a593Smuzhiyun unsigned num_queues_in_use;
299*4882a593Smuzhiyun unsigned inst_shift;
300*4882a593Smuzhiyun struct knav_link_ram_block link_rams[KNAV_NUM_LINKRAM];
301*4882a593Smuzhiyun void *instances;
302*4882a593Smuzhiyun struct list_head regions;
303*4882a593Smuzhiyun struct list_head queue_ranges;
304*4882a593Smuzhiyun struct list_head pools;
305*4882a593Smuzhiyun struct list_head pdsps;
306*4882a593Smuzhiyun struct list_head qmgrs;
307*4882a593Smuzhiyun enum qmss_version version;
308*4882a593Smuzhiyun };
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun struct knav_range_ops {
311*4882a593Smuzhiyun int (*init_range)(struct knav_range_info *range);
312*4882a593Smuzhiyun int (*free_range)(struct knav_range_info *range);
313*4882a593Smuzhiyun int (*init_queue)(struct knav_range_info *range,
314*4882a593Smuzhiyun struct knav_queue_inst *inst);
315*4882a593Smuzhiyun int (*open_queue)(struct knav_range_info *range,
316*4882a593Smuzhiyun struct knav_queue_inst *inst, unsigned flags);
317*4882a593Smuzhiyun int (*close_queue)(struct knav_range_info *range,
318*4882a593Smuzhiyun struct knav_queue_inst *inst);
319*4882a593Smuzhiyun int (*set_notify)(struct knav_range_info *range,
320*4882a593Smuzhiyun struct knav_queue_inst *inst, bool enabled);
321*4882a593Smuzhiyun };
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun struct knav_irq_info {
324*4882a593Smuzhiyun int irq;
325*4882a593Smuzhiyun struct cpumask *cpu_mask;
326*4882a593Smuzhiyun };
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun struct knav_range_info {
329*4882a593Smuzhiyun const char *name;
330*4882a593Smuzhiyun struct knav_device *kdev;
331*4882a593Smuzhiyun unsigned queue_base;
332*4882a593Smuzhiyun unsigned num_queues;
333*4882a593Smuzhiyun void *queue_base_inst;
334*4882a593Smuzhiyun unsigned flags;
335*4882a593Smuzhiyun struct list_head list;
336*4882a593Smuzhiyun struct knav_range_ops *ops;
337*4882a593Smuzhiyun struct knav_acc_info acc_info;
338*4882a593Smuzhiyun struct knav_acc_channel *acc;
339*4882a593Smuzhiyun unsigned num_irqs;
340*4882a593Smuzhiyun struct knav_irq_info irqs[RANGE_MAX_IRQS];
341*4882a593Smuzhiyun };
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun #define RANGE_RESERVED BIT(0)
344*4882a593Smuzhiyun #define RANGE_HAS_IRQ BIT(1)
345*4882a593Smuzhiyun #define RANGE_HAS_ACCUMULATOR BIT(2)
346*4882a593Smuzhiyun #define RANGE_MULTI_QUEUE BIT(3)
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun #define for_each_region(kdev, region) \
349*4882a593Smuzhiyun list_for_each_entry(region, &kdev->regions, list)
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun #define first_region(kdev) \
352*4882a593Smuzhiyun list_first_entry_or_null(&kdev->regions, \
353*4882a593Smuzhiyun struct knav_region, list)
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun #define for_each_queue_range(kdev, range) \
356*4882a593Smuzhiyun list_for_each_entry(range, &kdev->queue_ranges, list)
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun #define first_queue_range(kdev) \
359*4882a593Smuzhiyun list_first_entry_or_null(&kdev->queue_ranges, \
360*4882a593Smuzhiyun struct knav_range_info, list)
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun #define for_each_pool(kdev, pool) \
363*4882a593Smuzhiyun list_for_each_entry(pool, &kdev->pools, list)
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun #define for_each_pdsp(kdev, pdsp) \
366*4882a593Smuzhiyun list_for_each_entry(pdsp, &kdev->pdsps, list)
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun #define for_each_qmgr(kdev, qmgr) \
369*4882a593Smuzhiyun list_for_each_entry(qmgr, &kdev->qmgrs, list)
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun static inline struct knav_pdsp_info *
knav_find_pdsp(struct knav_device * kdev,unsigned pdsp_id)372*4882a593Smuzhiyun knav_find_pdsp(struct knav_device *kdev, unsigned pdsp_id)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun struct knav_pdsp_info *pdsp;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun for_each_pdsp(kdev, pdsp)
377*4882a593Smuzhiyun if (pdsp_id == pdsp->id)
378*4882a593Smuzhiyun return pdsp;
379*4882a593Smuzhiyun return NULL;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun extern int knav_init_acc_range(struct knav_device *kdev,
383*4882a593Smuzhiyun struct device_node *node,
384*4882a593Smuzhiyun struct knav_range_info *range);
385*4882a593Smuzhiyun extern void knav_queue_notify(struct knav_queue_inst *inst);
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun #endif /* __KNAV_QMSS_H__ */
388