Merge tag 'pull-work.iov_iter-base' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / firmware / arm_scmi / voltage.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * System Control and Management Interface (SCMI) Voltage Protocol
4  *
5  * Copyright (C) 2020-2022 ARM Ltd.
6  */
7
8 #include <linux/module.h>
9 #include <linux/scmi_protocol.h>
10
11 #include "protocols.h"
12
13 #define VOLTAGE_DOMS_NUM_MASK           GENMASK(15, 0)
14 #define REMAINING_LEVELS_MASK           GENMASK(31, 16)
15 #define RETURNED_LEVELS_MASK            GENMASK(11, 0)
16
17 enum scmi_voltage_protocol_cmd {
18         VOLTAGE_DOMAIN_ATTRIBUTES = 0x3,
19         VOLTAGE_DESCRIBE_LEVELS = 0x4,
20         VOLTAGE_CONFIG_SET = 0x5,
21         VOLTAGE_CONFIG_GET = 0x6,
22         VOLTAGE_LEVEL_SET = 0x7,
23         VOLTAGE_LEVEL_GET = 0x8,
24         VOLTAGE_DOMAIN_NAME_GET = 0x09,
25 };
26
27 #define NUM_VOLTAGE_DOMAINS(x)  ((u16)(FIELD_GET(VOLTAGE_DOMS_NUM_MASK, (x))))
28
29 struct scmi_msg_resp_domain_attributes {
30         __le32 attr;
31 #define SUPPORTS_ASYNC_LEVEL_SET(x)     ((x) & BIT(31))
32 #define SUPPORTS_EXTENDED_NAMES(x)      ((x) & BIT(30))
33         u8 name[SCMI_SHORT_NAME_MAX_SIZE];
34 };
35
36 struct scmi_msg_cmd_describe_levels {
37         __le32 domain_id;
38         __le32 level_index;
39 };
40
41 struct scmi_msg_resp_describe_levels {
42         __le32 flags;
43 #define NUM_REMAINING_LEVELS(f) ((u16)(FIELD_GET(REMAINING_LEVELS_MASK, (f))))
44 #define NUM_RETURNED_LEVELS(f)  ((u16)(FIELD_GET(RETURNED_LEVELS_MASK, (f))))
45 #define SUPPORTS_SEGMENTED_LEVELS(f)    ((f) & BIT(12))
46         __le32 voltage[];
47 };
48
49 struct scmi_msg_cmd_config_set {
50         __le32 domain_id;
51         __le32 config;
52 };
53
54 struct scmi_msg_cmd_level_set {
55         __le32 domain_id;
56         __le32 flags;
57         __le32 voltage_level;
58 };
59
60 struct scmi_resp_voltage_level_set_complete {
61         __le32 domain_id;
62         __le32 voltage_level;
63 };
64
65 struct voltage_info {
66         unsigned int version;
67         unsigned int num_domains;
68         struct scmi_voltage_info *domains;
69 };
70
71 static int scmi_protocol_attributes_get(const struct scmi_protocol_handle *ph,
72                                         struct voltage_info *vinfo)
73 {
74         int ret;
75         struct scmi_xfer *t;
76
77         ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0,
78                                       sizeof(__le32), &t);
79         if (ret)
80                 return ret;
81
82         ret = ph->xops->do_xfer(ph, t);
83         if (!ret)
84                 vinfo->num_domains =
85                         NUM_VOLTAGE_DOMAINS(get_unaligned_le32(t->rx.buf));
86
87         ph->xops->xfer_put(ph, t);
88         return ret;
89 }
90
91 static int scmi_init_voltage_levels(struct device *dev,
92                                     struct scmi_voltage_info *v,
93                                     u32 num_returned, u32 num_remaining,
94                                     bool segmented)
95 {
96         u32 num_levels;
97
98         num_levels = num_returned + num_remaining;
99         /*
100          * segmented levels entries are represented by a single triplet
101          * returned all in one go.
102          */
103         if (!num_levels ||
104             (segmented && (num_remaining || num_returned != 3))) {
105                 dev_err(dev,
106                         "Invalid level descriptor(%d/%d/%d) for voltage dom %d\n",
107                         num_levels, num_returned, num_remaining, v->id);
108                 return -EINVAL;
109         }
110
111         v->levels_uv = devm_kcalloc(dev, num_levels, sizeof(u32), GFP_KERNEL);
112         if (!v->levels_uv)
113                 return -ENOMEM;
114
115         v->num_levels = num_levels;
116         v->segmented = segmented;
117
118         return 0;
119 }
120
121 struct scmi_volt_ipriv {
122         struct device *dev;
123         struct scmi_voltage_info *v;
124 };
125
126 static void iter_volt_levels_prepare_message(void *message,
127                                              unsigned int desc_index,
128                                              const void *priv)
129 {
130         struct scmi_msg_cmd_describe_levels *msg = message;
131         const struct scmi_volt_ipriv *p = priv;
132
133         msg->domain_id = cpu_to_le32(p->v->id);
134         msg->level_index = cpu_to_le32(desc_index);
135 }
136
137 static int iter_volt_levels_update_state(struct scmi_iterator_state *st,
138                                          const void *response, void *priv)
139 {
140         int ret = 0;
141         u32 flags;
142         const struct scmi_msg_resp_describe_levels *r = response;
143         struct scmi_volt_ipriv *p = priv;
144
145         flags = le32_to_cpu(r->flags);
146         st->num_returned = NUM_RETURNED_LEVELS(flags);
147         st->num_remaining = NUM_REMAINING_LEVELS(flags);
148
149         /* Allocate space for num_levels if not already done */
150         if (!p->v->num_levels) {
151                 ret = scmi_init_voltage_levels(p->dev, p->v, st->num_returned,
152                                                st->num_remaining,
153                                               SUPPORTS_SEGMENTED_LEVELS(flags));
154                 if (!ret)
155                         st->max_resources = p->v->num_levels;
156         }
157
158         return ret;
159 }
160
161 static int
162 iter_volt_levels_process_response(const struct scmi_protocol_handle *ph,
163                                   const void *response,
164                                   struct scmi_iterator_state *st, void *priv)
165 {
166         s32 val;
167         const struct scmi_msg_resp_describe_levels *r = response;
168         struct scmi_volt_ipriv *p = priv;
169
170         val = (s32)le32_to_cpu(r->voltage[st->loop_idx]);
171         p->v->levels_uv[st->desc_index + st->loop_idx] = val;
172         if (val < 0)
173                 p->v->negative_volts_allowed = true;
174
175         return 0;
176 }
177
178 static int scmi_voltage_levels_get(const struct scmi_protocol_handle *ph,
179                                    struct scmi_voltage_info *v)
180 {
181         int ret;
182         void *iter;
183         struct scmi_iterator_ops ops = {
184                 .prepare_message = iter_volt_levels_prepare_message,
185                 .update_state = iter_volt_levels_update_state,
186                 .process_response = iter_volt_levels_process_response,
187         };
188         struct scmi_volt_ipriv vpriv = {
189                 .dev = ph->dev,
190                 .v = v,
191         };
192
193         iter = ph->hops->iter_response_init(ph, &ops, v->num_levels,
194                                             VOLTAGE_DESCRIBE_LEVELS,
195                                             sizeof(struct scmi_msg_cmd_describe_levels),
196                                             &vpriv);
197         if (IS_ERR(iter))
198                 return PTR_ERR(iter);
199
200         ret = ph->hops->iter_response_run(iter);
201         if (ret) {
202                 v->num_levels = 0;
203                 devm_kfree(ph->dev, v->levels_uv);
204         }
205
206         return ret;
207 }
208
209 static int scmi_voltage_descriptors_get(const struct scmi_protocol_handle *ph,
210                                         struct voltage_info *vinfo)
211 {
212         int ret, dom;
213         struct scmi_xfer *td;
214         struct scmi_msg_resp_domain_attributes *resp_dom;
215
216         ret = ph->xops->xfer_get_init(ph, VOLTAGE_DOMAIN_ATTRIBUTES,
217                                       sizeof(__le32), sizeof(*resp_dom), &td);
218         if (ret)
219                 return ret;
220         resp_dom = td->rx.buf;
221
222         for (dom = 0; dom < vinfo->num_domains; dom++) {
223                 u32 attributes;
224                 struct scmi_voltage_info *v;
225
226                 /* Retrieve domain attributes at first ... */
227                 put_unaligned_le32(dom, td->tx.buf);
228                 /* Skip domain on comms error */
229                 if (ph->xops->do_xfer(ph, td))
230                         continue;
231
232                 v = vinfo->domains + dom;
233                 v->id = dom;
234                 attributes = le32_to_cpu(resp_dom->attr);
235                 strscpy(v->name, resp_dom->name, SCMI_SHORT_NAME_MAX_SIZE);
236
237                 /*
238                  * If supported overwrite short name with the extended one;
239                  * on error just carry on and use already provided short name.
240                  */
241                 if (PROTOCOL_REV_MAJOR(vinfo->version) >= 0x2) {
242                         if (SUPPORTS_EXTENDED_NAMES(attributes))
243                                 ph->hops->extended_name_get(ph,
244                                                         VOLTAGE_DOMAIN_NAME_GET,
245                                                         v->id, v->name,
246                                                         SCMI_MAX_STR_SIZE);
247                         if (SUPPORTS_ASYNC_LEVEL_SET(attributes))
248                                 v->async_level_set = true;
249                 }
250
251                 /* Skip invalid voltage descriptors */
252                 scmi_voltage_levels_get(ph, v);
253         }
254
255         ph->xops->xfer_put(ph, td);
256
257         return ret;
258 }
259
260 static int __scmi_voltage_get_u32(const struct scmi_protocol_handle *ph,
261                                   u8 cmd_id, u32 domain_id, u32 *value)
262 {
263         int ret;
264         struct scmi_xfer *t;
265         struct voltage_info *vinfo = ph->get_priv(ph);
266
267         if (domain_id >= vinfo->num_domains)
268                 return -EINVAL;
269
270         ret = ph->xops->xfer_get_init(ph, cmd_id, sizeof(__le32), 0, &t);
271         if (ret)
272                 return ret;
273
274         put_unaligned_le32(domain_id, t->tx.buf);
275         ret = ph->xops->do_xfer(ph, t);
276         if (!ret)
277                 *value = get_unaligned_le32(t->rx.buf);
278
279         ph->xops->xfer_put(ph, t);
280         return ret;
281 }
282
283 static int scmi_voltage_config_set(const struct scmi_protocol_handle *ph,
284                                    u32 domain_id, u32 config)
285 {
286         int ret;
287         struct scmi_xfer *t;
288         struct voltage_info *vinfo = ph->get_priv(ph);
289         struct scmi_msg_cmd_config_set *cmd;
290
291         if (domain_id >= vinfo->num_domains)
292                 return -EINVAL;
293
294         ret = ph->xops->xfer_get_init(ph, VOLTAGE_CONFIG_SET,
295                                      sizeof(*cmd), 0, &t);
296         if (ret)
297                 return ret;
298
299         cmd = t->tx.buf;
300         cmd->domain_id = cpu_to_le32(domain_id);
301         cmd->config = cpu_to_le32(config & GENMASK(3, 0));
302
303         ret = ph->xops->do_xfer(ph, t);
304
305         ph->xops->xfer_put(ph, t);
306         return ret;
307 }
308
309 static int scmi_voltage_config_get(const struct scmi_protocol_handle *ph,
310                                    u32 domain_id, u32 *config)
311 {
312         return __scmi_voltage_get_u32(ph, VOLTAGE_CONFIG_GET,
313                                       domain_id, config);
314 }
315
316 static int scmi_voltage_level_set(const struct scmi_protocol_handle *ph,
317                                   u32 domain_id,
318                                   enum scmi_voltage_level_mode mode,
319                                   s32 volt_uV)
320 {
321         int ret;
322         struct scmi_xfer *t;
323         struct voltage_info *vinfo = ph->get_priv(ph);
324         struct scmi_msg_cmd_level_set *cmd;
325         struct scmi_voltage_info *v;
326
327         if (domain_id >= vinfo->num_domains)
328                 return -EINVAL;
329
330         ret = ph->xops->xfer_get_init(ph, VOLTAGE_LEVEL_SET,
331                                       sizeof(*cmd), 0, &t);
332         if (ret)
333                 return ret;
334
335         v = vinfo->domains + domain_id;
336
337         cmd = t->tx.buf;
338         cmd->domain_id = cpu_to_le32(domain_id);
339         cmd->voltage_level = cpu_to_le32(volt_uV);
340
341         if (!v->async_level_set || mode != SCMI_VOLTAGE_LEVEL_SET_AUTO) {
342                 cmd->flags = cpu_to_le32(0x0);
343                 ret = ph->xops->do_xfer(ph, t);
344         } else {
345                 cmd->flags = cpu_to_le32(0x1);
346                 ret = ph->xops->do_xfer_with_response(ph, t);
347                 if (!ret) {
348                         struct scmi_resp_voltage_level_set_complete *resp;
349
350                         resp = t->rx.buf;
351                         if (le32_to_cpu(resp->domain_id) == domain_id)
352                                 dev_dbg(ph->dev,
353                                         "Voltage domain %d set async to %d\n",
354                                         v->id,
355                                         le32_to_cpu(resp->voltage_level));
356                         else
357                                 ret = -EPROTO;
358                 }
359         }
360
361         ph->xops->xfer_put(ph, t);
362         return ret;
363 }
364
365 static int scmi_voltage_level_get(const struct scmi_protocol_handle *ph,
366                                   u32 domain_id, s32 *volt_uV)
367 {
368         return __scmi_voltage_get_u32(ph, VOLTAGE_LEVEL_GET,
369                                       domain_id, (u32 *)volt_uV);
370 }
371
372 static const struct scmi_voltage_info * __must_check
373 scmi_voltage_info_get(const struct scmi_protocol_handle *ph, u32 domain_id)
374 {
375         struct voltage_info *vinfo = ph->get_priv(ph);
376
377         if (domain_id >= vinfo->num_domains ||
378             !vinfo->domains[domain_id].num_levels)
379                 return NULL;
380
381         return vinfo->domains + domain_id;
382 }
383
384 static int scmi_voltage_domains_num_get(const struct scmi_protocol_handle *ph)
385 {
386         struct voltage_info *vinfo = ph->get_priv(ph);
387
388         return vinfo->num_domains;
389 }
390
391 static struct scmi_voltage_proto_ops voltage_proto_ops = {
392         .num_domains_get = scmi_voltage_domains_num_get,
393         .info_get = scmi_voltage_info_get,
394         .config_set = scmi_voltage_config_set,
395         .config_get = scmi_voltage_config_get,
396         .level_set = scmi_voltage_level_set,
397         .level_get = scmi_voltage_level_get,
398 };
399
400 static int scmi_voltage_protocol_init(const struct scmi_protocol_handle *ph)
401 {
402         int ret;
403         u32 version;
404         struct voltage_info *vinfo;
405
406         ret = ph->xops->version_get(ph, &version);
407         if (ret)
408                 return ret;
409
410         dev_dbg(ph->dev, "Voltage Version %d.%d\n",
411                 PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
412
413         vinfo = devm_kzalloc(ph->dev, sizeof(*vinfo), GFP_KERNEL);
414         if (!vinfo)
415                 return -ENOMEM;
416         vinfo->version = version;
417
418         ret = scmi_protocol_attributes_get(ph, vinfo);
419         if (ret)
420                 return ret;
421
422         if (vinfo->num_domains) {
423                 vinfo->domains = devm_kcalloc(ph->dev, vinfo->num_domains,
424                                               sizeof(*vinfo->domains),
425                                               GFP_KERNEL);
426                 if (!vinfo->domains)
427                         return -ENOMEM;
428                 ret = scmi_voltage_descriptors_get(ph, vinfo);
429                 if (ret)
430                         return ret;
431         } else {
432                 dev_warn(ph->dev, "No Voltage domains found.\n");
433         }
434
435         return ph->set_priv(ph, vinfo);
436 }
437
438 static const struct scmi_protocol scmi_voltage = {
439         .id = SCMI_PROTOCOL_VOLTAGE,
440         .owner = THIS_MODULE,
441         .instance_init = &scmi_voltage_protocol_init,
442         .ops = &voltage_proto_ops,
443 };
444
445 DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(voltage, scmi_voltage)