1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __STARFIVE_E24_H__
#define __STARFIVE_E24_H__
#include <linux/types.h>
#include <linux/completion.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
#include <linux/irqreturn.h>
#include <linux/platform_device.h>
#define E24_IOCTL_MAGIC 'e'
#define E24_IOCTL_SEND _IO(E24_IOCTL_MAGIC, 1)
#define E24_IOCTL_RECV _IO(E24_IOCTL_MAGIC, 2)
#define E24_IOCTL_GET_CHANNEL _IO(E24_IOCTL_MAGIC, 3)
#define E24_IOCTL_FREE_CHANNEL _IO(E24_IOCTL_MAGIC, 4)
#define E24_IOCTL_ALLOC _IO(E24_IOCTL_MAGIC, 5)
#define E24_IOCTL_FREE _IO(E24_IOCTL_MAGIC, 6)
#define E24_DSP_CMD_INLINE_DATA_SIZE 16
#define E24_NO_TRANSLATION ((u32)~0ul)
#define E24_CMD_STRIDE 256
#define E24_MEM_MAP
enum e24_irq_mode {
MAIL_IRQ_NONE,
MAIL_IRQ_LEVEL,
MAIL_IRQ_MAX
};
enum {
E24_FLAG_READ = 0x1,
E24_FLAG_WRITE = 0x2,
E24_FLAG_READ_WRITE = 0x3,
};
enum {
E24_QUEUE_FLAG_VALID = 0x4,
E24_QUEUE_FLAG_PRIO = 0xff00,
E24_QUEUE_FLAG_PRIO_SHIFT = 8,
E24_QUEUE_VALID_FLAGS =
E24_QUEUE_FLAG_VALID |
E24_QUEUE_FLAG_PRIO,
};
enum {
E24_CMD_FLAG_REQUEST_VALID = 0x00000001,
E24_CMD_FLAG_RESPONSE_VALID = 0x00000002,
E24_CMD_FLAG_REQUEST_NSID = 0x00000004,
E24_CMD_FLAG_RESPONSE_DELIVERY_FAIL = 0x00000008,
};
struct e24_address_map_entry {
phys_addr_t src_addr;
u32 dst_addr;
u32 size;
};
struct e24_address_map {
unsigned int n;
struct e24_address_map_entry *entry;
};
struct e24_alien_mapping {
unsigned long vaddr;
unsigned long size;
phys_addr_t paddr;
void *allocation;
enum {
ALIEN_GUP,
ALIEN_PFN_MAP,
ALIEN_COPY,
} type;
};
struct e24_mapping {
enum {
E24_MAPPING_NONE,
E24_MAPPING_NATIVE,
E24_MAPPING_ALIEN,
E24_MAPPING_KERNEL = 0x4,
} type;
union {
struct {
struct e24_allocation *m_allocation;
unsigned long vaddr;
} native;
struct e24_alien_mapping alien_mapping;
};
};
struct e24_ioctl_alloc {
u32 size;
u32 align;
u64 addr;
};
struct e24_comm {
struct mutex lock;
void __iomem *comm;
struct completion completion;
u32 priority;
};
struct e24_device {
struct device *dev;
const char *firmware_name;
const struct firmware *firmware;
struct miscdevice miscdev;
const struct e24_hw_ops *hw_ops;
void *hw_arg;
int irq_mode;
u32 n_queues;
struct completion completion;
struct e24_address_map address_map;
struct e24_comm *queue;
void __iomem *comm;
phys_addr_t comm_phys;
phys_addr_t shared_mem;
phys_addr_t shared_size;
u32 mbox_data;
int nodeid;
spinlock_t busy_list_lock;
struct mbox_chan *tx_channel;
struct mbox_chan *rx_channel;
void *rx_buffer;
void *message;
struct e24_allocation_pool *pool;
struct e24_allocation *busy_list;
};
struct e24_hw_arg {
struct e24_device *e24;
phys_addr_t regs_phys;
struct clk *clk_rtc;
struct clk *clk_core;
struct clk *clk_dbg;
struct reset_control *rst_core;
struct regmap *reg_syscon;
enum e24_irq_mode irq_mode;
};
static inline int e24_compare_address(phys_addr_t addr,
const struct e24_address_map_entry *entry)
{
if (addr < entry->src_addr)
return -1;
if (addr - entry->src_addr < entry->size)
return 0;
return 1;
}
irqreturn_t e24_irq_handler(int irq, struct e24_device *e24_hw);
#endif
|