1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | |
3 | #ifndef __QCOM_APR_H_ |
4 | #define __QCOM_APR_H_ |
5 | |
6 | #include <linux/spinlock.h> |
7 | #include <linux/device.h> |
8 | #include <linux/mod_devicetable.h> |
9 | #include <dt-bindings/soc/qcom,apr.h> |
10 | #include <dt-bindings/soc/qcom,gpr.h> |
11 | |
12 | extern const struct bus_type aprbus; |
13 | |
14 | #define APR_HDR_LEN(hdr_len) ((hdr_len)/4) |
15 | |
16 | /* |
17 | * HEADER field |
18 | * version:0:3 |
19 | * header_size : 4:7 |
20 | * message_type : 8:9 |
21 | * reserved: 10:15 |
22 | */ |
23 | #define APR_HDR_FIELD(msg_type, hdr_len, ver)\ |
24 | (((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF)) |
25 | |
26 | #define APR_HDR_SIZE sizeof(struct apr_hdr) |
27 | #define APR_SEQ_CMD_HDR_FIELD APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \ |
28 | APR_HDR_LEN(APR_HDR_SIZE), \ |
29 | APR_PKT_VER) |
30 | /* Version */ |
31 | #define APR_PKT_VER 0x0 |
32 | |
33 | /* Command and Response Types */ |
34 | #define APR_MSG_TYPE_EVENT 0x0 |
35 | #define APR_MSG_TYPE_CMD_RSP 0x1 |
36 | #define APR_MSG_TYPE_SEQ_CMD 0x2 |
37 | #define APR_MSG_TYPE_NSEQ_CMD 0x3 |
38 | #define APR_MSG_TYPE_MAX 0x04 |
39 | |
40 | /* APR Basic Response Message */ |
41 | #define APR_BASIC_RSP_RESULT 0x000110E8 |
42 | #define APR_RSP_ACCEPTED 0x000100BE |
43 | |
44 | struct aprv2_ibasic_rsp_result_t { |
45 | uint32_t opcode; |
46 | uint32_t status; |
47 | }; |
48 | |
49 | /* hdr field Ver [0:3], Size [4:7], Message type [8:10] */ |
50 | #define APR_HDR_FIELD_VER(h) (h & 0x000F) |
51 | #define APR_HDR_FIELD_SIZE(h) ((h & 0x00F0) >> 4) |
52 | #define APR_HDR_FIELD_SIZE_BYTES(h) (((h & 0x00F0) >> 4) * 4) |
53 | #define APR_HDR_FIELD_MT(h) ((h & 0x0300) >> 8) |
54 | |
55 | struct apr_hdr { |
56 | uint16_t hdr_field; |
57 | uint16_t pkt_size; |
58 | uint8_t src_svc; |
59 | uint8_t src_domain; |
60 | uint16_t src_port; |
61 | uint8_t dest_svc; |
62 | uint8_t dest_domain; |
63 | uint16_t dest_port; |
64 | uint32_t token; |
65 | uint32_t opcode; |
66 | } __packed; |
67 | |
68 | struct apr_pkt { |
69 | struct apr_hdr hdr; |
70 | uint8_t payload[]; |
71 | }; |
72 | |
73 | struct apr_resp_pkt { |
74 | struct apr_hdr hdr; |
75 | void *payload; |
76 | int payload_size; |
77 | }; |
78 | |
79 | struct gpr_hdr { |
80 | uint32_t version:4; |
81 | uint32_t hdr_size:4; |
82 | uint32_t pkt_size:24; |
83 | uint32_t dest_domain:8; |
84 | uint32_t src_domain:8; |
85 | uint32_t reserved:16; |
86 | uint32_t src_port; |
87 | uint32_t dest_port; |
88 | uint32_t token; |
89 | uint32_t opcode; |
90 | } __packed; |
91 | |
92 | struct gpr_pkt { |
93 | struct gpr_hdr hdr; |
94 | uint32_t payload[]; |
95 | }; |
96 | |
97 | struct gpr_resp_pkt { |
98 | struct gpr_hdr hdr; |
99 | void *payload; |
100 | int payload_size; |
101 | }; |
102 | |
103 | #define GPR_HDR_SIZE sizeof(struct gpr_hdr) |
104 | #define GPR_PKT_VER 0x0 |
105 | #define ((sizeof(struct gpr_pkt) + 3) >> 2) |
106 | #define (GPR_PKT_HEADER_WORD_SIZE << 2) |
107 | |
108 | #define GPR_BASIC_RSP_RESULT 0x02001005 |
109 | |
110 | struct gpr_ibasic_rsp_result_t { |
111 | uint32_t opcode; |
112 | uint32_t status; |
113 | }; |
114 | |
115 | #define GPR_BASIC_EVT_ACCEPTED 0x02001006 |
116 | |
117 | struct gpr_ibasic_rsp_accepted_t { |
118 | uint32_t opcode; |
119 | }; |
120 | |
121 | /* Bits 0 to 15 -- Minor version, Bits 16 to 31 -- Major version */ |
122 | #define APR_SVC_MAJOR_VERSION(v) ((v >> 16) & 0xFF) |
123 | #define APR_SVC_MINOR_VERSION(v) (v & 0xFF) |
124 | |
125 | typedef int (*gpr_port_cb) (struct gpr_resp_pkt *d, void *priv, int op); |
126 | struct packet_router; |
127 | struct pkt_router_svc { |
128 | struct device *dev; |
129 | gpr_port_cb callback; |
130 | struct packet_router *pr; |
131 | spinlock_t lock; |
132 | int id; |
133 | void *priv; |
134 | }; |
135 | |
136 | typedef struct pkt_router_svc gpr_port_t; |
137 | |
138 | struct apr_device { |
139 | struct device dev; |
140 | uint16_t svc_id; |
141 | uint16_t domain_id; |
142 | uint32_t version; |
143 | char name[APR_NAME_SIZE]; |
144 | const char *service_path; |
145 | struct pkt_router_svc svc; |
146 | struct list_head node; |
147 | }; |
148 | |
149 | typedef struct apr_device gpr_device_t; |
150 | |
151 | #define to_apr_device(d) container_of(d, struct apr_device, dev) |
152 | #define svc_to_apr_device(d) container_of(d, struct apr_device, svc) |
153 | |
154 | struct apr_driver { |
155 | int (*probe)(struct apr_device *sl); |
156 | void (*remove)(struct apr_device *sl); |
157 | int (*callback)(struct apr_device *a, |
158 | struct apr_resp_pkt *d); |
159 | int (*gpr_callback)(struct gpr_resp_pkt *d, void *data, int op); |
160 | struct device_driver driver; |
161 | const struct apr_device_id *id_table; |
162 | }; |
163 | |
164 | typedef struct apr_driver gpr_driver_t; |
165 | #define to_apr_driver(d) container_of(d, struct apr_driver, driver) |
166 | |
167 | /* |
168 | * use a macro to avoid include chaining to get THIS_MODULE |
169 | */ |
170 | #define apr_driver_register(drv) __apr_driver_register(drv, THIS_MODULE) |
171 | |
172 | int __apr_driver_register(struct apr_driver *drv, struct module *owner); |
173 | void apr_driver_unregister(struct apr_driver *drv); |
174 | |
175 | /** |
176 | * module_apr_driver() - Helper macro for registering a aprbus driver |
177 | * @__apr_driver: apr_driver struct |
178 | * |
179 | * Helper macro for aprbus drivers which do not do anything special in |
180 | * module init/exit. This eliminates a lot of boilerplate. Each module |
181 | * may only use this macro once, and calling it replaces module_init() |
182 | * and module_exit() |
183 | */ |
184 | #define module_apr_driver(__apr_driver) \ |
185 | module_driver(__apr_driver, apr_driver_register, \ |
186 | apr_driver_unregister) |
187 | #define module_gpr_driver(__gpr_driver) module_apr_driver(__gpr_driver) |
188 | |
189 | int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt); |
190 | |
191 | gpr_port_t *gpr_alloc_port(gpr_device_t *gdev, struct device *dev, |
192 | gpr_port_cb cb, void *priv); |
193 | void gpr_free_port(gpr_port_t *port); |
194 | int gpr_send_port_pkt(gpr_port_t *port, struct gpr_pkt *pkt); |
195 | int gpr_send_pkt(gpr_device_t *gdev, struct gpr_pkt *pkt); |
196 | |
197 | #endif /* __QCOM_APR_H_ */ |
198 | |