11802d0beSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
241f93af9SSandeep Nair /*
341f93af9SSandeep Nair * Keystone Navigator QMSS driver internal header
441f93af9SSandeep Nair *
541f93af9SSandeep Nair * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
641f93af9SSandeep Nair * Author: Sandeep Nair <sandeep_n@ti.com>
741f93af9SSandeep Nair * Cyril Chemparathy <cyril@ti.com>
841f93af9SSandeep Nair * Santosh Shilimkar <santosh.shilimkar@ti.com>
941f93af9SSandeep Nair */
1041f93af9SSandeep Nair
1141f93af9SSandeep Nair #ifndef __KNAV_QMSS_H__
1241f93af9SSandeep Nair #define __KNAV_QMSS_H__
1341f93af9SSandeep Nair
14bc3acbb8SVasyl Gomonovych #include <linux/percpu.h>
15bc3acbb8SVasyl Gomonovych
1641f93af9SSandeep Nair #define THRESH_GTE BIT(7)
1741f93af9SSandeep Nair #define THRESH_LT 0
1841f93af9SSandeep Nair
1941f93af9SSandeep Nair #define PDSP_CTRL_PC_MASK 0xffff0000
2041f93af9SSandeep Nair #define PDSP_CTRL_SOFT_RESET BIT(0)
2141f93af9SSandeep Nair #define PDSP_CTRL_ENABLE BIT(1)
2241f93af9SSandeep Nair #define PDSP_CTRL_RUNNING BIT(15)
2341f93af9SSandeep Nair
2441f93af9SSandeep Nair #define ACC_MAX_CHANNEL 48
2541f93af9SSandeep Nair #define ACC_DEFAULT_PERIOD 25 /* usecs */
2641f93af9SSandeep Nair
2741f93af9SSandeep Nair #define ACC_CHANNEL_INT_BASE 2
2841f93af9SSandeep Nair
2941f93af9SSandeep Nair #define ACC_LIST_ENTRY_TYPE 1
3041f93af9SSandeep Nair #define ACC_LIST_ENTRY_WORDS (1 << ACC_LIST_ENTRY_TYPE)
3141f93af9SSandeep Nair #define ACC_LIST_ENTRY_QUEUE_IDX 0
3241f93af9SSandeep Nair #define ACC_LIST_ENTRY_DESC_IDX (ACC_LIST_ENTRY_WORDS - 1)
3341f93af9SSandeep Nair
3441f93af9SSandeep Nair #define ACC_CMD_DISABLE_CHANNEL 0x80
3541f93af9SSandeep Nair #define ACC_CMD_ENABLE_CHANNEL 0x81
3641f93af9SSandeep Nair #define ACC_CFG_MULTI_QUEUE BIT(21)
3741f93af9SSandeep Nair
3841f93af9SSandeep Nair #define ACC_INTD_OFFSET_EOI (0x0010)
3941f93af9SSandeep Nair #define ACC_INTD_OFFSET_COUNT(ch) (0x0300 + 4 * (ch))
4041f93af9SSandeep Nair #define ACC_INTD_OFFSET_STATUS(ch) (0x0200 + 4 * ((ch) / 32))
4141f93af9SSandeep Nair
4241f93af9SSandeep Nair #define RANGE_MAX_IRQS 64
4341f93af9SSandeep Nair
4441f93af9SSandeep Nair #define ACC_DESCS_MAX SZ_1K
4541f93af9SSandeep Nair #define ACC_DESCS_MASK (ACC_DESCS_MAX - 1)
4641f93af9SSandeep Nair #define DESC_SIZE_MASK 0xful
4741f93af9SSandeep Nair #define DESC_PTR_MASK (~DESC_SIZE_MASK)
4841f93af9SSandeep Nair
4941f93af9SSandeep Nair #define KNAV_NAME_SIZE 32
5041f93af9SSandeep Nair
5141f93af9SSandeep Nair enum knav_acc_result {
5241f93af9SSandeep Nair ACC_RET_IDLE,
5341f93af9SSandeep Nair ACC_RET_SUCCESS,
5441f93af9SSandeep Nair ACC_RET_INVALID_COMMAND,
5541f93af9SSandeep Nair ACC_RET_INVALID_CHANNEL,
5641f93af9SSandeep Nair ACC_RET_INACTIVE_CHANNEL,
5741f93af9SSandeep Nair ACC_RET_ACTIVE_CHANNEL,
5841f93af9SSandeep Nair ACC_RET_INVALID_QUEUE,
5941f93af9SSandeep Nair ACC_RET_INVALID_RET,
6041f93af9SSandeep Nair };
6141f93af9SSandeep Nair
6241f93af9SSandeep Nair struct knav_reg_config {
6341f93af9SSandeep Nair u32 revision;
6441f93af9SSandeep Nair u32 __pad1;
6541f93af9SSandeep Nair u32 divert;
6641f93af9SSandeep Nair u32 link_ram_base0;
6741f93af9SSandeep Nair u32 link_ram_size0;
6841f93af9SSandeep Nair u32 link_ram_base1;
6941f93af9SSandeep Nair u32 __pad2[2];
70*9f162d9dSGustavo A. R. Silva u32 starvation[];
7141f93af9SSandeep Nair };
7241f93af9SSandeep Nair
7341f93af9SSandeep Nair struct knav_reg_region {
7441f93af9SSandeep Nair u32 base;
7541f93af9SSandeep Nair u32 start_index;
7641f93af9SSandeep Nair u32 size_count;
7741f93af9SSandeep Nair u32 __pad;
7841f93af9SSandeep Nair };
7941f93af9SSandeep Nair
8041f93af9SSandeep Nair struct knav_reg_pdsp_regs {
8141f93af9SSandeep Nair u32 control;
8241f93af9SSandeep Nair u32 status;
8341f93af9SSandeep Nair u32 cycle_count;
8441f93af9SSandeep Nair u32 stall_count;
8541f93af9SSandeep Nair };
8641f93af9SSandeep Nair
8741f93af9SSandeep Nair struct knav_reg_acc_command {
8841f93af9SSandeep Nair u32 command;
8941f93af9SSandeep Nair u32 queue_mask;
90cc0336ecSArnd Bergmann u32 list_dma;
9141f93af9SSandeep Nair u32 queue_num;
9241f93af9SSandeep Nair u32 timer_config;
9341f93af9SSandeep Nair };
9441f93af9SSandeep Nair
9541f93af9SSandeep Nair struct knav_link_ram_block {
96cc0336ecSArnd Bergmann dma_addr_t dma;
9741f93af9SSandeep Nair void *virt;
9841f93af9SSandeep Nair size_t size;
9941f93af9SSandeep Nair };
10041f93af9SSandeep Nair
10141f93af9SSandeep Nair struct knav_acc_info {
10241f93af9SSandeep Nair u32 pdsp_id;
10341f93af9SSandeep Nair u32 start_channel;
10441f93af9SSandeep Nair u32 list_entries;
10541f93af9SSandeep Nair u32 pacing_mode;
10641f93af9SSandeep Nair u32 timer_count;
10741f93af9SSandeep Nair int mem_size;
10841f93af9SSandeep Nair int list_size;
10941f93af9SSandeep Nair struct knav_pdsp_info *pdsp;
11041f93af9SSandeep Nair };
11141f93af9SSandeep Nair
11241f93af9SSandeep Nair struct knav_acc_channel {
11341f93af9SSandeep Nair u32 channel;
11441f93af9SSandeep Nair u32 list_index;
11541f93af9SSandeep Nair u32 open_mask;
11641f93af9SSandeep Nair u32 *list_cpu[2];
11741f93af9SSandeep Nair dma_addr_t list_dma[2];
11841f93af9SSandeep Nair char name[KNAV_NAME_SIZE];
11941f93af9SSandeep Nair atomic_t retrigger_count;
12041f93af9SSandeep Nair };
12141f93af9SSandeep Nair
12241f93af9SSandeep Nair struct knav_pdsp_info {
12341f93af9SSandeep Nair const char *name;
12441f93af9SSandeep Nair struct knav_reg_pdsp_regs __iomem *regs;
12541f93af9SSandeep Nair union {
12641f93af9SSandeep Nair void __iomem *command;
12741f93af9SSandeep Nair struct knav_reg_acc_command __iomem *acc_command;
12841f93af9SSandeep Nair u32 __iomem *qos_command;
12941f93af9SSandeep Nair };
13041f93af9SSandeep Nair void __iomem *intd;
13141f93af9SSandeep Nair u32 __iomem *iram;
13241f93af9SSandeep Nair u32 id;
13341f93af9SSandeep Nair struct list_head list;
13404501690SMurali Karicheri bool loaded;
13504501690SMurali Karicheri bool started;
13641f93af9SSandeep Nair };
13741f93af9SSandeep Nair
13841f93af9SSandeep Nair struct knav_qmgr_info {
13941f93af9SSandeep Nair unsigned start_queue;
14041f93af9SSandeep Nair unsigned num_queues;
14141f93af9SSandeep Nair struct knav_reg_config __iomem *reg_config;
14241f93af9SSandeep Nair struct knav_reg_region __iomem *reg_region;
14341f93af9SSandeep Nair struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
14441f93af9SSandeep Nair void __iomem *reg_status;
14541f93af9SSandeep Nair struct list_head list;
14641f93af9SSandeep Nair };
14741f93af9SSandeep Nair
14841f93af9SSandeep Nair #define KNAV_NUM_LINKRAM 2
14941f93af9SSandeep Nair
15041f93af9SSandeep Nair /**
15141f93af9SSandeep Nair * struct knav_queue_stats: queue statistics
15241f93af9SSandeep Nair * pushes: number of push operations
15341f93af9SSandeep Nair * pops: number of pop operations
15441f93af9SSandeep Nair * push_errors: number of push errors
15541f93af9SSandeep Nair * pop_errors: number of pop errors
15641f93af9SSandeep Nair * notifies: notifier counts
15741f93af9SSandeep Nair */
15841f93af9SSandeep Nair struct knav_queue_stats {
159bc3acbb8SVasyl Gomonovych unsigned int pushes;
160bc3acbb8SVasyl Gomonovych unsigned int pops;
161bc3acbb8SVasyl Gomonovych unsigned int push_errors;
162bc3acbb8SVasyl Gomonovych unsigned int pop_errors;
163bc3acbb8SVasyl Gomonovych unsigned int notifies;
16441f93af9SSandeep Nair };
16541f93af9SSandeep Nair
16641f93af9SSandeep Nair /**
16741f93af9SSandeep Nair * struct knav_reg_queue: queue registers
16841f93af9SSandeep Nair * @entry_count: valid entries in the queue
16941f93af9SSandeep Nair * @byte_count: total byte count in thhe queue
17041f93af9SSandeep Nair * @packet_size: packet size for the queue
17141f93af9SSandeep Nair * @ptr_size_thresh: packet pointer size threshold
17241f93af9SSandeep Nair */
17341f93af9SSandeep Nair struct knav_reg_queue {
17441f93af9SSandeep Nair u32 entry_count;
17541f93af9SSandeep Nair u32 byte_count;
17641f93af9SSandeep Nair u32 packet_size;
17741f93af9SSandeep Nair u32 ptr_size_thresh;
17841f93af9SSandeep Nair };
17941f93af9SSandeep Nair
18041f93af9SSandeep Nair /**
18141f93af9SSandeep Nair * struct knav_region: qmss region info
18241f93af9SSandeep Nair * @dma_start, dma_end: start and end dma address
18341f93af9SSandeep Nair * @virt_start, virt_end: start and end virtual address
18441f93af9SSandeep Nair * @desc_size: descriptor size
18541f93af9SSandeep Nair * @used_desc: consumed descriptors
18641f93af9SSandeep Nair * @id: region number
18741f93af9SSandeep Nair * @num_desc: total descriptors
18841f93af9SSandeep Nair * @link_index: index of the first descriptor
18941f93af9SSandeep Nair * @name: region name
19041f93af9SSandeep Nair * @list: instance in the device's region list
19141f93af9SSandeep Nair * @pools: list of descriptor pools in the region
19241f93af9SSandeep Nair */
19341f93af9SSandeep Nair struct knav_region {
19441f93af9SSandeep Nair dma_addr_t dma_start, dma_end;
19541f93af9SSandeep Nair void *virt_start, *virt_end;
19641f93af9SSandeep Nair unsigned desc_size;
19741f93af9SSandeep Nair unsigned used_desc;
19841f93af9SSandeep Nair unsigned id;
19941f93af9SSandeep Nair unsigned num_desc;
20041f93af9SSandeep Nair unsigned link_index;
20141f93af9SSandeep Nair const char *name;
20241f93af9SSandeep Nair struct list_head list;
20341f93af9SSandeep Nair struct list_head pools;
20441f93af9SSandeep Nair };
20541f93af9SSandeep Nair
20641f93af9SSandeep Nair /**
20741f93af9SSandeep Nair * struct knav_pool: qmss pools
20841f93af9SSandeep Nair * @dev: device pointer
20941f93af9SSandeep Nair * @region: qmss region info
21041f93af9SSandeep Nair * @queue: queue registers
21141f93af9SSandeep Nair * @kdev: qmss device pointer
21241f93af9SSandeep Nair * @region_offset: offset from the base
21341f93af9SSandeep Nair * @num_desc: total descriptors
21441f93af9SSandeep Nair * @desc_size: descriptor size
21541f93af9SSandeep Nair * @region_id: region number
21641f93af9SSandeep Nair * @name: pool name
21741f93af9SSandeep Nair * @list: list head
21841f93af9SSandeep Nair * @region_inst: instance in the region's pool list
21941f93af9SSandeep Nair */
22041f93af9SSandeep Nair struct knav_pool {
22141f93af9SSandeep Nair struct device *dev;
22241f93af9SSandeep Nair struct knav_region *region;
22341f93af9SSandeep Nair struct knav_queue *queue;
22441f93af9SSandeep Nair struct knav_device *kdev;
22541f93af9SSandeep Nair int region_offset;
22641f93af9SSandeep Nair int num_desc;
22741f93af9SSandeep Nair int desc_size;
22841f93af9SSandeep Nair int region_id;
22941f93af9SSandeep Nair const char *name;
23041f93af9SSandeep Nair struct list_head list;
23141f93af9SSandeep Nair struct list_head region_inst;
23241f93af9SSandeep Nair };
23341f93af9SSandeep Nair
23441f93af9SSandeep Nair /**
2357bcfe20dSColin King * struct knav_queue_inst: qmss queue instance properties
23641f93af9SSandeep Nair * @descs: descriptor pointer
23741f93af9SSandeep Nair * @desc_head, desc_tail, desc_count: descriptor counters
23841f93af9SSandeep Nair * @acc: accumulator channel pointer
23941f93af9SSandeep Nair * @kdev: qmss device pointer
24041f93af9SSandeep Nair * @range: range info
24141f93af9SSandeep Nair * @qmgr: queue manager info
2427bcfe20dSColin King * @id: queue instance id
24341f93af9SSandeep Nair * @irq_num: irq line number
24441f93af9SSandeep Nair * @notify_needed: notifier needed based on queue type
24541f93af9SSandeep Nair * @num_notifiers: total notifiers
24641f93af9SSandeep Nair * @handles: list head
24741f93af9SSandeep Nair * @name: queue instance name
24841f93af9SSandeep Nair * @irq_name: irq line name
24941f93af9SSandeep Nair */
25041f93af9SSandeep Nair struct knav_queue_inst {
25141f93af9SSandeep Nair u32 *descs;
25241f93af9SSandeep Nair atomic_t desc_head, desc_tail, desc_count;
25341f93af9SSandeep Nair struct knav_acc_channel *acc;
25441f93af9SSandeep Nair struct knav_device *kdev;
25541f93af9SSandeep Nair struct knav_range_info *range;
25641f93af9SSandeep Nair struct knav_qmgr_info *qmgr;
25741f93af9SSandeep Nair u32 id;
25841f93af9SSandeep Nair int irq_num;
25941f93af9SSandeep Nair int notify_needed;
26041f93af9SSandeep Nair atomic_t num_notifiers;
26141f93af9SSandeep Nair struct list_head handles;
26241f93af9SSandeep Nair const char *name;
26341f93af9SSandeep Nair const char *irq_name;
26441f93af9SSandeep Nair };
26541f93af9SSandeep Nair
26641f93af9SSandeep Nair /**
26741f93af9SSandeep Nair * struct knav_queue: qmss queue properties
26841f93af9SSandeep Nair * @reg_push, reg_pop, reg_peek: push, pop queue registers
2697bcfe20dSColin King * @inst: qmss queue instance properties
27041f93af9SSandeep Nair * @notifier_fn: notifier function
27141f93af9SSandeep Nair * @notifier_fn_arg: notifier function argument
27241f93af9SSandeep Nair * @notifier_enabled: notier enabled for a give queue
27341f93af9SSandeep Nair * @rcu: rcu head
27441f93af9SSandeep Nair * @flags: queue flags
27541f93af9SSandeep Nair * @list: list head
27641f93af9SSandeep Nair */
27741f93af9SSandeep Nair struct knav_queue {
27841f93af9SSandeep Nair struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
27941f93af9SSandeep Nair struct knav_queue_inst *inst;
280bc3acbb8SVasyl Gomonovych struct knav_queue_stats __percpu *stats;
28141f93af9SSandeep Nair knav_queue_notify_fn notifier_fn;
28241f93af9SSandeep Nair void *notifier_fn_arg;
28341f93af9SSandeep Nair atomic_t notifier_enabled;
28441f93af9SSandeep Nair struct rcu_head rcu;
28541f93af9SSandeep Nair unsigned flags;
28641f93af9SSandeep Nair struct list_head list;
28741f93af9SSandeep Nair };
28841f93af9SSandeep Nair
289350601b4SMurali Karicheri enum qmss_version {
290350601b4SMurali Karicheri QMSS,
291350601b4SMurali Karicheri QMSS_66AK2G,
292350601b4SMurali Karicheri };
293350601b4SMurali Karicheri
29441f93af9SSandeep Nair struct knav_device {
29541f93af9SSandeep Nair struct device *dev;
29641f93af9SSandeep Nair unsigned base_id;
29741f93af9SSandeep Nair unsigned num_queues;
29841f93af9SSandeep Nair unsigned num_queues_in_use;
29941f93af9SSandeep Nair unsigned inst_shift;
30041f93af9SSandeep Nair struct knav_link_ram_block link_rams[KNAV_NUM_LINKRAM];
30141f93af9SSandeep Nair void *instances;
30241f93af9SSandeep Nair struct list_head regions;
30341f93af9SSandeep Nair struct list_head queue_ranges;
30441f93af9SSandeep Nair struct list_head pools;
30541f93af9SSandeep Nair struct list_head pdsps;
30641f93af9SSandeep Nair struct list_head qmgrs;
307350601b4SMurali Karicheri enum qmss_version version;
30841f93af9SSandeep Nair };
30941f93af9SSandeep Nair
31041f93af9SSandeep Nair struct knav_range_ops {
31141f93af9SSandeep Nair int (*init_range)(struct knav_range_info *range);
31241f93af9SSandeep Nair int (*free_range)(struct knav_range_info *range);
31341f93af9SSandeep Nair int (*init_queue)(struct knav_range_info *range,
31441f93af9SSandeep Nair struct knav_queue_inst *inst);
31541f93af9SSandeep Nair int (*open_queue)(struct knav_range_info *range,
31641f93af9SSandeep Nair struct knav_queue_inst *inst, unsigned flags);
31741f93af9SSandeep Nair int (*close_queue)(struct knav_range_info *range,
31841f93af9SSandeep Nair struct knav_queue_inst *inst);
31941f93af9SSandeep Nair int (*set_notify)(struct knav_range_info *range,
32041f93af9SSandeep Nair struct knav_queue_inst *inst, bool enabled);
32141f93af9SSandeep Nair };
32241f93af9SSandeep Nair
32341f93af9SSandeep Nair struct knav_irq_info {
32441f93af9SSandeep Nair int irq;
325832ad0e3SMarc Zyngier struct cpumask *cpu_mask;
32641f93af9SSandeep Nair };
32741f93af9SSandeep Nair
32841f93af9SSandeep Nair struct knav_range_info {
32941f93af9SSandeep Nair const char *name;
33041f93af9SSandeep Nair struct knav_device *kdev;
33141f93af9SSandeep Nair unsigned queue_base;
33241f93af9SSandeep Nair unsigned num_queues;
33341f93af9SSandeep Nair void *queue_base_inst;
33441f93af9SSandeep Nair unsigned flags;
33541f93af9SSandeep Nair struct list_head list;
33641f93af9SSandeep Nair struct knav_range_ops *ops;
33741f93af9SSandeep Nair struct knav_acc_info acc_info;
33841f93af9SSandeep Nair struct knav_acc_channel *acc;
33941f93af9SSandeep Nair unsigned num_irqs;
34041f93af9SSandeep Nair struct knav_irq_info irqs[RANGE_MAX_IRQS];
34141f93af9SSandeep Nair };
34241f93af9SSandeep Nair
34341f93af9SSandeep Nair #define RANGE_RESERVED BIT(0)
34441f93af9SSandeep Nair #define RANGE_HAS_IRQ BIT(1)
34541f93af9SSandeep Nair #define RANGE_HAS_ACCUMULATOR BIT(2)
34641f93af9SSandeep Nair #define RANGE_MULTI_QUEUE BIT(3)
34741f93af9SSandeep Nair
34841f93af9SSandeep Nair #define for_each_region(kdev, region) \
34941f93af9SSandeep Nair list_for_each_entry(region, &kdev->regions, list)
35041f93af9SSandeep Nair
35141f93af9SSandeep Nair #define first_region(kdev) \
35242813295SAxel Lin list_first_entry_or_null(&kdev->regions, \
35341f93af9SSandeep Nair struct knav_region, list)
35441f93af9SSandeep Nair
35541f93af9SSandeep Nair #define for_each_queue_range(kdev, range) \
35641f93af9SSandeep Nair list_for_each_entry(range, &kdev->queue_ranges, list)
35741f93af9SSandeep Nair
35841f93af9SSandeep Nair #define first_queue_range(kdev) \
35942813295SAxel Lin list_first_entry_or_null(&kdev->queue_ranges, \
36041f93af9SSandeep Nair struct knav_range_info, list)
36141f93af9SSandeep Nair
36241f93af9SSandeep Nair #define for_each_pool(kdev, pool) \
36341f93af9SSandeep Nair list_for_each_entry(pool, &kdev->pools, list)
36441f93af9SSandeep Nair
36541f93af9SSandeep Nair #define for_each_pdsp(kdev, pdsp) \
36641f93af9SSandeep Nair list_for_each_entry(pdsp, &kdev->pdsps, list)
36741f93af9SSandeep Nair
36841f93af9SSandeep Nair #define for_each_qmgr(kdev, qmgr) \
36941f93af9SSandeep Nair list_for_each_entry(qmgr, &kdev->qmgrs, list)
37041f93af9SSandeep Nair
37141f93af9SSandeep Nair static inline struct knav_pdsp_info *
knav_find_pdsp(struct knav_device * kdev,unsigned pdsp_id)37241f93af9SSandeep Nair knav_find_pdsp(struct knav_device *kdev, unsigned pdsp_id)
37341f93af9SSandeep Nair {
37441f93af9SSandeep Nair struct knav_pdsp_info *pdsp;
37541f93af9SSandeep Nair
37641f93af9SSandeep Nair for_each_pdsp(kdev, pdsp)
37741f93af9SSandeep Nair if (pdsp_id == pdsp->id)
37841f93af9SSandeep Nair return pdsp;
37941f93af9SSandeep Nair return NULL;
38041f93af9SSandeep Nair }
38141f93af9SSandeep Nair
38241f93af9SSandeep Nair extern int knav_init_acc_range(struct knav_device *kdev,
38341f93af9SSandeep Nair struct device_node *node,
38441f93af9SSandeep Nair struct knav_range_info *range);
38541f93af9SSandeep Nair extern void knav_queue_notify(struct knav_queue_inst *inst);
38641f93af9SSandeep Nair
38741f93af9SSandeep Nair #endif /* __KNAV_QMSS_H__ */
388