aboutsummaryrefslogtreecommitdiff
path: root/include/linux/soc/qcom/apr.h
blob: dbc9efe185d1e2bb5385787a8fc485d0395876a9 (plain)
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
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2011-2017, The Linux Foundation
 * Copyright (c) 2018, Linaro Limited
 */

#ifndef __QCOM_APR_H_
#define __QCOM_APR_H_

#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <dt-bindings/soc/qcom,apr.h>

#define APR_HDR_LEN(hdr_len) ((hdr_len)/4)

/*
 * HEADER field
 * version:0:3
 * header_size : 4:7
 * message_type : 8:9
 * reserved: 10:15
 */
#define APR_HDR_FIELD(msg_type, hdr_len, ver)\
	(((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF))

#define APR_HDR_SIZE sizeof(struct apr_hdr)
#define APR_SEQ_CMD_HDR_FIELD APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
					    APR_HDR_LEN(APR_HDR_SIZE), \
					    APR_PKT_VER)
/* Version */
#define APR_PKT_VER		0x0

/* Command and Response Types */
#define APR_MSG_TYPE_EVENT	0x0
#define APR_MSG_TYPE_CMD_RSP	0x1
#define APR_MSG_TYPE_SEQ_CMD	0x2
#define APR_MSG_TYPE_NSEQ_CMD	0x3
#define APR_MSG_TYPE_MAX	0x04

/* APR Basic Response Message */
#define APR_BASIC_RSP_RESULT 0x000110E8
#define APR_RSP_ACCEPTED     0x000100BE

struct aprv2_ibasic_rsp_result_t {
	uint32_t opcode;
	uint32_t status;
};

/* hdr field Ver [0:3], Size [4:7], Message type [8:10] */
#define APR_HDR_FIELD_VER(h)		(h & 0x000F)
#define APR_HDR_FIELD_SIZE(h)		((h & 0x00F0) >> 4)
#define APR_HDR_FIELD_SIZE_BYTES(h)	(((h & 0x00F0) >> 4) * 4)
#define APR_HDR_FIELD_MT(h)		((h & 0x0300) >> 8)

struct apr_hdr {
	uint16_t hdr_field;
	uint16_t pkt_size;
	uint8_t src_svc;
	uint8_t src_domain;
	uint16_t src_port;
	uint8_t dest_svc;
	uint8_t dest_domain;
	uint16_t dest_port;
	uint32_t token;
	uint32_t opcode;
};

struct apr_client_message {
	uint16_t payload_size;
	uint16_t hdr_len;
	uint16_t msg_type;
	uint16_t src;
	uint16_t dest_svc;
	uint16_t src_port;
	uint16_t dest_port;
	uint32_t token;
	uint32_t opcode;
	void *payload;
};

/* Bits 0 to 15 -- Minor version,  Bits 16 to 31 -- Major version */
#define APR_SVC_MAJOR_VERSION(v)	((v >> 16) & 0xFF)
#define APR_SVC_MINOR_VERSION(v)	(v & 0xFF)

struct apr_device {
	struct device	dev;
	uint16_t	svc_id;
	uint16_t	domain_id;
	uint32_t	version;
	spinlock_t	lock;
	struct list_head node;
};

#define to_apr_device(d) container_of(d, struct apr_device, dev)

struct apr_driver {
	int	(*probe)(struct apr_device *sl);
	int	(*remove)(struct apr_device *sl);
	int	(*callback)(struct apr_device *a,
			    struct apr_client_message *d);
	struct device_driver		driver;
	const struct apr_device_id	*id_table;
};

#define to_apr_driver(d) container_of(d, struct apr_driver, driver)

/*
 * use a macro to avoid include chaining to get THIS_MODULE
 */
#define apr_driver_register(drv) __apr_driver_register(drv, THIS_MODULE)

int __apr_driver_register(struct apr_driver *drv, struct module *owner);
void apr_driver_unregister(struct apr_driver *drv);

/**
 * module_apr_driver() - Helper macro for registering a aprbus driver
 * @__aprbus_driver: aprbus_driver struct
 *
 * Helper macro for aprbus drivers which do not do anything special in
 * module init/exit. This eliminates a lot of boilerplate. Each module
 * may only use this macro once, and calling it replaces module_init()
 * and module_exit()
 */
#define module_apr_driver(__apr_driver) \
	module_driver(__apr_driver, apr_driver_register, \
			apr_driver_unregister)

int apr_send_pkt(struct apr_device *adev, void *buf);

#endif /* __QCOM_APR_H_ */