1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2021 Alibaba Group Holding Limited.
4  */
5 
6 #ifndef _THEAD_AON_H
7 #define _THEAD_AON_H
8 
9 #include <linux/device.h>
10 #include <linux/types.h>
11 
12 #define AON_RPC_MSG_MAGIC (0xef)
13 #define TH1520_AON_RPC_VERSION 2
14 #define TH1520_AON_RPC_MSG_NUM 7
15 
16 struct th1520_aon_chan;
17 
18 enum th1520_aon_rpc_svc {
19 	TH1520_AON_RPC_SVC_UNKNOWN = 0,
20 	TH1520_AON_RPC_SVC_PM = 1,
21 	TH1520_AON_RPC_SVC_MISC = 2,
22 	TH1520_AON_RPC_SVC_AVFS = 3,
23 	TH1520_AON_RPC_SVC_SYS = 4,
24 	TH1520_AON_RPC_SVC_WDG = 5,
25 	TH1520_AON_RPC_SVC_LPM = 6,
26 	TH1520_AON_RPC_SVC_MAX = 0x3F,
27 };
28 
29 enum th1520_aon_misc_func {
30 	TH1520_AON_MISC_FUNC_UNKNOWN = 0,
31 	TH1520_AON_MISC_FUNC_SET_CONTROL = 1,
32 	TH1520_AON_MISC_FUNC_GET_CONTROL = 2,
33 	TH1520_AON_MISC_FUNC_REGDUMP_CFG = 3,
34 };
35 
36 enum th1520_aon_wdg_func {
37 	TH1520_AON_WDG_FUNC_UNKNOWN = 0,
38 	TH1520_AON_WDG_FUNC_START = 1,
39 	TH1520_AON_WDG_FUNC_STOP = 2,
40 	TH1520_AON_WDG_FUNC_PING = 3,
41 	TH1520_AON_WDG_FUNC_TIMEOUTSET = 4,
42 	TH1520_AON_WDG_FUNC_RESTART = 5,
43 	TH1520_AON_WDG_FUNC_GET_STATE = 6,
44 	TH1520_AON_WDG_FUNC_POWER_OFF = 7,
45 	TH1520_AON_WDG_FUNC_AON_WDT_ON = 8,
46 	TH1520_AON_WDG_FUNC_AON_WDT_OFF = 9,
47 };
48 
49 enum th1520_aon_sys_func {
50 	TH1520_AON_SYS_FUNC_UNKNOWN = 0,
51 	TH1520_AON_SYS_FUNC_AON_RESERVE_MEM = 1,
52 };
53 
54 enum th1520_aon_lpm_func {
55 	TH1520_AON_LPM_FUNC_UNKNOWN = 0,
56 	TH1520_AON_LPM_FUNC_REQUIRE_STR = 1,
57 	TH1520_AON_LPM_FUNC_RESUME_STR = 2,
58 	TH1520_AON_LPM_FUNC_REQUIRE_STD = 3,
59 	TH1520_AON_LPM_FUNC_CPUHP = 4,
60 	TH1520_AON_LPM_FUNC_REGDUMP_CFG = 5,
61 };
62 
63 enum th1520_aon_pm_func {
64 	TH1520_AON_PM_FUNC_UNKNOWN = 0,
65 	TH1520_AON_PM_FUNC_SET_RESOURCE_REGULATOR = 1,
66 	TH1520_AON_PM_FUNC_GET_RESOURCE_REGULATOR = 2,
67 	TH1520_AON_PM_FUNC_SET_RESOURCE_POWER_MODE = 3,
68 	TH1520_AON_PM_FUNC_PWR_SET = 4,
69 	TH1520_AON_PM_FUNC_PWR_GET = 5,
70 	TH1520_AON_PM_FUNC_CHECK_FAULT = 6,
71 	TH1520_AON_PM_FUNC_GET_TEMPERATURE = 7,
72 };
73 
74 struct th1520_aon_rpc_msg_hdr {
75 	u8 ver; /* version of msg hdr */
76 	u8 size; /*  msg size ,uinit in bytes,the size includes rpc msg header self */
77 	u8 svc; /* rpc main service id */
78 	u8 func; /* rpc sub func id of specific service, sent by caller */
79 } __packed __aligned(1);
80 
81 struct th1520_aon_rpc_ack_common {
82 	struct th1520_aon_rpc_msg_hdr hdr;
83 	u8 err_code;
84 } __packed __aligned(1);
85 
86 #define RPC_SVC_MSG_TYPE_DATA 0
87 #define RPC_SVC_MSG_TYPE_ACK 1
88 #define RPC_SVC_MSG_NEED_ACK 0
89 #define RPC_SVC_MSG_NO_NEED_ACK 1
90 
91 #define RPC_GET_VER(MESG) ((MESG)->ver)
92 #define RPC_SET_VER(MESG, VER) ((MESG)->ver = (VER))
93 #define RPC_GET_SVC_ID(MESG) ((MESG)->svc & 0x3F)
94 #define RPC_SET_SVC_ID(MESG, ID) ((MESG)->svc |= 0x3F & (ID))
95 #define RPC_GET_SVC_FLAG_MSG_TYPE(MESG) (((MESG)->svc & 0x80) >> 7)
96 #define RPC_SET_SVC_FLAG_MSG_TYPE(MESG, TYPE) ((MESG)->svc |= (TYPE) << 7)
97 #define RPC_GET_SVC_FLAG_ACK_TYPE(MESG) (((MESG)->svc & 0x40) >> 6)
98 #define RPC_SET_SVC_FLAG_ACK_TYPE(MESG, ACK) ((MESG)->svc |= (ACK) << 6)
99 
100 #define RPC_SET_BE64(MESG, OFFSET, SET_DATA)                                \
101 	do {                                                                \
102 		u8 *data = (u8 *)(MESG);                                    \
103 		u64 _offset = (OFFSET);                                     \
104 		u64 _set_data = (SET_DATA);                                 \
105 		data[_offset + 7] = _set_data & 0xFF;                       \
106 		data[_offset + 6] = (_set_data & 0xFF00) >> 8;              \
107 		data[_offset + 5] = (_set_data & 0xFF0000) >> 16;           \
108 		data[_offset + 4] = (_set_data & 0xFF000000) >> 24;         \
109 		data[_offset + 3] = (_set_data & 0xFF00000000) >> 32;       \
110 		data[_offset + 2] = (_set_data & 0xFF0000000000) >> 40;     \
111 		data[_offset + 1] = (_set_data & 0xFF000000000000) >> 48;   \
112 		data[_offset + 0] = (_set_data & 0xFF00000000000000) >> 56; \
113 	} while (0)
114 
115 #define RPC_SET_BE32(MESG, OFFSET, SET_DATA)			    \
116 	do {							    \
117 		u8 *data = (u8 *)(MESG);			    \
118 		u64 _offset = (OFFSET);				    \
119 		u64 _set_data = (SET_DATA);			    \
120 		data[_offset + 3] = (_set_data) & 0xFF;		    \
121 		data[_offset + 2] = (_set_data & 0xFF00) >> 8;	    \
122 		data[_offset + 1] = (_set_data & 0xFF0000) >> 16;   \
123 		data[_offset + 0] = (_set_data & 0xFF000000) >> 24; \
124 	} while (0)
125 
126 #define RPC_SET_BE16(MESG, OFFSET, SET_DATA)		       \
127 	do {						       \
128 		u8 *data = (u8 *)(MESG);		       \
129 		u64 _offset = (OFFSET);			       \
130 		u64 _set_data = (SET_DATA);		       \
131 		data[_offset + 1] = (_set_data) & 0xFF;	       \
132 		data[_offset + 0] = (_set_data & 0xFF00) >> 8; \
133 	} while (0)
134 
135 #define RPC_SET_U8(MESG, OFFSET, SET_DATA)	  \
136 	do {					  \
137 		u8 *data = (u8 *)(MESG);	  \
138 		data[OFFSET] = (SET_DATA) & 0xFF; \
139 	} while (0)
140 
141 #define RPC_GET_BE64(MESG, OFFSET, PTR)                                      \
142 	do {                                                                 \
143 		u8 *data = (u8 *)(MESG);                                     \
144 		u64 _offset = (OFFSET);                                      \
145 		*(u32 *)(PTR) =                                              \
146 			(data[_offset + 7] | data[_offset + 6] << 8 |        \
147 			 data[_offset + 5] << 16 | data[_offset + 4] << 24 | \
148 			 data[_offset + 3] << 32 | data[_offset + 2] << 40 | \
149 			 data[_offset + 1] << 48 | data[_offset + 0] << 56); \
150 	} while (0)
151 
152 #define RPC_GET_BE32(MESG, OFFSET, PTR)                                      \
153 	do {                                                                 \
154 		u8 *data = (u8 *)(MESG);                                     \
155 		u64 _offset = (OFFSET);                                      \
156 		*(u32 *)(PTR) =                                              \
157 			(data[_offset + 3] | data[_offset + 2] << 8 |        \
158 			 data[_offset + 1] << 16 | data[_offset + 0] << 24); \
159 	} while (0)
160 
161 #define RPC_GET_BE16(MESG, OFFSET, PTR)                                       \
162 	do {                                                                  \
163 		u8 *data = (u8 *)(MESG);                                      \
164 		u64 _offset = (OFFSET);                                       \
165 		*(u16 *)(PTR) = (data[_offset + 1] | data[_offset + 0] << 8); \
166 	} while (0)
167 
168 #define RPC_GET_U8(MESG, OFFSET, PTR)          \
169 	do {                                   \
170 		u8 *data = (u8 *)(MESG);       \
171 		*(u8 *)(PTR) = (data[OFFSET]); \
172 	} while (0)
173 
174 /*
175  * Defines for SC PM Power Mode
176  */
177 #define TH1520_AON_PM_PW_MODE_OFF 0 /* Power off */
178 #define TH1520_AON_PM_PW_MODE_STBY 1 /* Power in standby */
179 #define TH1520_AON_PM_PW_MODE_LP 2 /* Power in low-power */
180 #define TH1520_AON_PM_PW_MODE_ON 3 /* Power on */
181 
182 /*
183  * Defines for AON power islands
184  */
185 #define TH1520_AON_AUDIO_PD 0
186 #define TH1520_AON_VDEC_PD 1
187 #define TH1520_AON_NPU_PD 2
188 #define TH1520_AON_VENC_PD 3
189 #define TH1520_AON_GPU_PD 4
190 #define TH1520_AON_DSP0_PD 5
191 #define TH1520_AON_DSP1_PD 6
192 
193 struct th1520_aon_chan *th1520_aon_init(struct device *dev);
194 void th1520_aon_deinit(struct th1520_aon_chan *aon_chan);
195 
196 int th1520_aon_call_rpc(struct th1520_aon_chan *aon_chan, void *msg);
197 int th1520_aon_power_update(struct th1520_aon_chan *aon_chan, u16 rsrc,
198 			    bool power_on);
199 
200 #endif /* _THEAD_AON_H */
201