forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-02-20 ea08eeccae9297f7aabd2ef7f0c2517ac4549acc
kernel/drivers/firmware/arm_scmi/reset.c
....@@ -2,19 +2,21 @@
22 /*
33 * System Control and Management Interface (SCMI) Reset Protocol
44 *
5
- * Copyright (C) 2019 ARM Ltd.
5
+ * Copyright (C) 2019-2020 ARM Ltd.
66 */
77
8
+#define pr_fmt(fmt) "SCMI Notifications RESET - " fmt
9
+
10
+#include <linux/module.h>
11
+#include <linux/scmi_protocol.h>
12
+
813 #include "common.h"
14
+#include "notify.h"
915
1016 enum scmi_reset_protocol_cmd {
1117 RESET_DOMAIN_ATTRIBUTES = 0x3,
1218 RESET = 0x4,
1319 RESET_NOTIFY = 0x5,
14
-};
15
-
16
-enum scmi_reset_protocol_notify {
17
- RESET_ISSUED = 0x0,
1820 };
1921
2022 #define NUM_RESET_DOMAIN_MASK 0xffff
....@@ -38,6 +40,18 @@
3840 #define ARCH_COLD_RESET 0
3941 };
4042
43
+struct scmi_msg_reset_notify {
44
+ __le32 id;
45
+ __le32 event_control;
46
+#define RESET_TP_NOTIFY_ALL BIT(0)
47
+};
48
+
49
+struct scmi_reset_issued_notify_payld {
50
+ __le32 agent_id;
51
+ __le32 domain_id;
52
+ __le32 reset_state;
53
+};
54
+
4155 struct reset_dom_info {
4256 bool async_reset;
4357 bool reset_notify;
....@@ -51,46 +65,45 @@
5165 struct reset_dom_info *dom_info;
5266 };
5367
54
-static int scmi_reset_attributes_get(const struct scmi_handle *handle,
68
+static int scmi_reset_attributes_get(const struct scmi_protocol_handle *ph,
5569 struct scmi_reset_info *pi)
5670 {
5771 int ret;
5872 struct scmi_xfer *t;
5973 u32 attr;
6074
61
- ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
62
- SCMI_PROTOCOL_RESET, 0, sizeof(attr), &t);
75
+ ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES,
76
+ 0, sizeof(attr), &t);
6377 if (ret)
6478 return ret;
6579
66
- ret = scmi_do_xfer(handle, t);
80
+ ret = ph->xops->do_xfer(ph, t);
6781 if (!ret) {
6882 attr = get_unaligned_le32(t->rx.buf);
6983 pi->num_domains = attr & NUM_RESET_DOMAIN_MASK;
7084 }
7185
72
- scmi_xfer_put(handle, t);
86
+ ph->xops->xfer_put(ph, t);
7387 return ret;
7488 }
7589
7690 static int
77
-scmi_reset_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
78
- struct reset_dom_info *dom_info)
91
+scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph,
92
+ u32 domain, struct reset_dom_info *dom_info)
7993 {
8094 int ret;
8195 struct scmi_xfer *t;
8296 struct scmi_msg_resp_reset_domain_attributes *attr;
8397
84
- ret = scmi_xfer_get_init(handle, RESET_DOMAIN_ATTRIBUTES,
85
- SCMI_PROTOCOL_RESET, sizeof(domain),
86
- sizeof(*attr), &t);
98
+ ret = ph->xops->xfer_get_init(ph, RESET_DOMAIN_ATTRIBUTES,
99
+ sizeof(domain), sizeof(*attr), &t);
87100 if (ret)
88101 return ret;
89102
90103 put_unaligned_le32(domain, t->tx.buf);
91104 attr = t->rx.buf;
92105
93
- ret = scmi_do_xfer(handle, t);
106
+ ret = ph->xops->do_xfer(ph, t);
94107 if (!ret) {
95108 u32 attributes = le32_to_cpu(attr->attributes);
96109
....@@ -102,47 +115,49 @@
102115 strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
103116 }
104117
105
- scmi_xfer_put(handle, t);
118
+ ph->xops->xfer_put(ph, t);
106119 return ret;
107120 }
108121
109
-static int scmi_reset_num_domains_get(const struct scmi_handle *handle)
122
+static int scmi_reset_num_domains_get(const struct scmi_protocol_handle *ph)
110123 {
111
- struct scmi_reset_info *pi = handle->reset_priv;
124
+ struct scmi_reset_info *pi = ph->get_priv(ph);
112125
113126 return pi->num_domains;
114127 }
115128
116
-static char *scmi_reset_name_get(const struct scmi_handle *handle, u32 domain)
129
+static char *scmi_reset_name_get(const struct scmi_protocol_handle *ph,
130
+ u32 domain)
117131 {
118
- struct scmi_reset_info *pi = handle->reset_priv;
132
+ struct scmi_reset_info *pi = ph->get_priv(ph);
133
+
119134 struct reset_dom_info *dom = pi->dom_info + domain;
120135
121136 return dom->name;
122137 }
123138
124
-static int scmi_reset_latency_get(const struct scmi_handle *handle, u32 domain)
139
+static int scmi_reset_latency_get(const struct scmi_protocol_handle *ph,
140
+ u32 domain)
125141 {
126
- struct scmi_reset_info *pi = handle->reset_priv;
142
+ struct scmi_reset_info *pi = ph->get_priv(ph);
127143 struct reset_dom_info *dom = pi->dom_info + domain;
128144
129145 return dom->latency_us;
130146 }
131147
132
-static int scmi_domain_reset(const struct scmi_handle *handle, u32 domain,
148
+static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
133149 u32 flags, u32 state)
134150 {
135151 int ret;
136152 struct scmi_xfer *t;
137153 struct scmi_msg_reset_domain_reset *dom;
138
- struct scmi_reset_info *pi = handle->reset_priv;
154
+ struct scmi_reset_info *pi = ph->get_priv(ph);
139155 struct reset_dom_info *rdom = pi->dom_info + domain;
140156
141157 if (rdom->async_reset)
142158 flags |= ASYNCHRONOUS_RESET;
143159
144
- ret = scmi_xfer_get_init(handle, RESET, SCMI_PROTOCOL_RESET,
145
- sizeof(*dom), 0, &t);
160
+ ret = ph->xops->xfer_get_init(ph, RESET, sizeof(*dom), 0, &t);
146161 if (ret)
147162 return ret;
148163
....@@ -152,34 +167,35 @@
152167 dom->reset_state = cpu_to_le32(state);
153168
154169 if (rdom->async_reset)
155
- ret = scmi_do_xfer_with_response(handle, t);
170
+ ret = ph->xops->do_xfer_with_response(ph, t);
156171 else
157
- ret = scmi_do_xfer(handle, t);
172
+ ret = ph->xops->do_xfer(ph, t);
158173
159
- scmi_xfer_put(handle, t);
174
+ ph->xops->xfer_put(ph, t);
160175 return ret;
161176 }
162177
163
-static int scmi_reset_domain_reset(const struct scmi_handle *handle, u32 domain)
178
+static int scmi_reset_domain_reset(const struct scmi_protocol_handle *ph,
179
+ u32 domain)
164180 {
165
- return scmi_domain_reset(handle, domain, AUTONOMOUS_RESET,
181
+ return scmi_domain_reset(ph, domain, AUTONOMOUS_RESET,
166182 ARCH_COLD_RESET);
167183 }
168184
169185 static int
170
-scmi_reset_domain_assert(const struct scmi_handle *handle, u32 domain)
186
+scmi_reset_domain_assert(const struct scmi_protocol_handle *ph, u32 domain)
171187 {
172
- return scmi_domain_reset(handle, domain, EXPLICIT_RESET_ASSERT,
188
+ return scmi_domain_reset(ph, domain, EXPLICIT_RESET_ASSERT,
173189 ARCH_COLD_RESET);
174190 }
175191
176192 static int
177
-scmi_reset_domain_deassert(const struct scmi_handle *handle, u32 domain)
193
+scmi_reset_domain_deassert(const struct scmi_protocol_handle *ph, u32 domain)
178194 {
179
- return scmi_domain_reset(handle, domain, 0, ARCH_COLD_RESET);
195
+ return scmi_domain_reset(ph, domain, 0, ARCH_COLD_RESET);
180196 }
181197
182
-static struct scmi_reset_ops reset_ops = {
198
+static const struct scmi_reset_proto_ops reset_proto_ops = {
183199 .num_domains_get = scmi_reset_num_domains_get,
184200 .name_get = scmi_reset_name_get,
185201 .latency_get = scmi_reset_latency_get,
....@@ -188,24 +204,111 @@
188204 .deassert = scmi_reset_domain_deassert,
189205 };
190206
191
-static int scmi_reset_protocol_init(struct scmi_handle *handle)
207
+static int scmi_reset_notify(const struct scmi_protocol_handle *ph,
208
+ u32 domain_id, bool enable)
209
+{
210
+ int ret;
211
+ u32 evt_cntl = enable ? RESET_TP_NOTIFY_ALL : 0;
212
+ struct scmi_xfer *t;
213
+ struct scmi_msg_reset_notify *cfg;
214
+
215
+ ret = ph->xops->xfer_get_init(ph, RESET_NOTIFY, sizeof(*cfg), 0, &t);
216
+ if (ret)
217
+ return ret;
218
+
219
+ cfg = t->tx.buf;
220
+ cfg->id = cpu_to_le32(domain_id);
221
+ cfg->event_control = cpu_to_le32(evt_cntl);
222
+
223
+ ret = ph->xops->do_xfer(ph, t);
224
+
225
+ ph->xops->xfer_put(ph, t);
226
+ return ret;
227
+}
228
+
229
+static int scmi_reset_set_notify_enabled(const struct scmi_protocol_handle *ph,
230
+ u8 evt_id, u32 src_id, bool enable)
231
+{
232
+ int ret;
233
+
234
+ ret = scmi_reset_notify(ph, src_id, enable);
235
+ if (ret)
236
+ pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
237
+ evt_id, src_id, ret);
238
+
239
+ return ret;
240
+}
241
+
242
+static void *
243
+scmi_reset_fill_custom_report(const struct scmi_protocol_handle *ph,
244
+ u8 evt_id, ktime_t timestamp,
245
+ const void *payld, size_t payld_sz,
246
+ void *report, u32 *src_id)
247
+{
248
+ const struct scmi_reset_issued_notify_payld *p = payld;
249
+ struct scmi_reset_issued_report *r = report;
250
+
251
+ if (evt_id != SCMI_EVENT_RESET_ISSUED || sizeof(*p) != payld_sz)
252
+ return NULL;
253
+
254
+ r->timestamp = timestamp;
255
+ r->agent_id = le32_to_cpu(p->agent_id);
256
+ r->domain_id = le32_to_cpu(p->domain_id);
257
+ r->reset_state = le32_to_cpu(p->reset_state);
258
+ *src_id = r->domain_id;
259
+
260
+ return r;
261
+}
262
+
263
+static int scmi_reset_get_num_sources(const struct scmi_protocol_handle *ph)
264
+{
265
+ struct scmi_reset_info *pinfo = ph->get_priv(ph);
266
+
267
+ if (!pinfo)
268
+ return -EINVAL;
269
+
270
+ return pinfo->num_domains;
271
+}
272
+
273
+static const struct scmi_event reset_events[] = {
274
+ {
275
+ .id = SCMI_EVENT_RESET_ISSUED,
276
+ .max_payld_sz = sizeof(struct scmi_reset_issued_notify_payld),
277
+ .max_report_sz = sizeof(struct scmi_reset_issued_report),
278
+ },
279
+};
280
+
281
+static const struct scmi_event_ops reset_event_ops = {
282
+ .get_num_sources = scmi_reset_get_num_sources,
283
+ .set_notify_enabled = scmi_reset_set_notify_enabled,
284
+ .fill_custom_report = scmi_reset_fill_custom_report,
285
+};
286
+
287
+static const struct scmi_protocol_events reset_protocol_events = {
288
+ .queue_sz = SCMI_PROTO_QUEUE_SZ,
289
+ .ops = &reset_event_ops,
290
+ .evts = reset_events,
291
+ .num_events = ARRAY_SIZE(reset_events),
292
+};
293
+
294
+static int scmi_reset_protocol_init(const struct scmi_protocol_handle *ph)
192295 {
193296 int domain;
194297 u32 version;
195298 struct scmi_reset_info *pinfo;
196299
197
- scmi_version_get(handle, SCMI_PROTOCOL_RESET, &version);
300
+ ph->xops->version_get(ph, &version);
198301
199
- dev_dbg(handle->dev, "Reset Version %d.%d\n",
302
+ dev_dbg(ph->dev, "Reset Version %d.%d\n",
200303 PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
201304
202
- pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL);
305
+ pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL);
203306 if (!pinfo)
204307 return -ENOMEM;
205308
206
- scmi_reset_attributes_get(handle, pinfo);
309
+ scmi_reset_attributes_get(ph, pinfo);
207310
208
- pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains,
311
+ pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains,
209312 sizeof(*pinfo->dom_info), GFP_KERNEL);
210313 if (!pinfo->dom_info)
211314 return -ENOMEM;
....@@ -213,14 +316,19 @@
213316 for (domain = 0; domain < pinfo->num_domains; domain++) {
214317 struct reset_dom_info *dom = pinfo->dom_info + domain;
215318
216
- scmi_reset_domain_attributes_get(handle, domain, dom);
319
+ scmi_reset_domain_attributes_get(ph, domain, dom);
217320 }
218321
219322 pinfo->version = version;
220
- handle->reset_ops = &reset_ops;
221
- handle->reset_priv = pinfo;
222
-
223
- return 0;
323
+ return ph->set_priv(ph, pinfo);
224324 }
225325
226
-DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(SCMI_PROTOCOL_RESET, reset)
326
+static const struct scmi_protocol scmi_reset = {
327
+ .id = SCMI_PROTOCOL_RESET,
328
+ .owner = THIS_MODULE,
329
+ .init_instance = &scmi_reset_protocol_init,
330
+ .ops = &reset_proto_ops,
331
+ .events = &reset_protocol_events,
332
+};
333
+
334
+DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(reset, scmi_reset)