]> Git Repo - linux.git/blob - drivers/platform/x86/intel/sdsi.c
drm/i915: Use REG_BIT() & co. for AUX CH registers
[linux.git] / drivers / platform / x86 / intel / sdsi.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel On Demand (Software Defined Silicon) driver
4  *
5  * Copyright (c) 2022, Intel Corporation.
6  * All Rights Reserved.
7  *
8  * Author: "David E. Box" <[email protected]>
9  */
10
11 #include <linux/auxiliary_bus.h>
12 #include <linux/bits.h>
13 #include <linux/bitfield.h>
14 #include <linux/device.h>
15 #include <linux/iopoll.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/pci.h>
19 #include <linux/slab.h>
20 #include <linux/sysfs.h>
21 #include <linux/types.h>
22 #include <linux/uaccess.h>
23
24 #include "vsec.h"
25
26 #define ACCESS_TYPE_BARID               2
27 #define ACCESS_TYPE_LOCAL               3
28
29 #define SDSI_MIN_SIZE_DWORDS            276
30 #define SDSI_SIZE_MAILBOX               1024
31 #define SDSI_SIZE_REGS                  80
32 #define SDSI_SIZE_CMD                   sizeof(u64)
33
34 /*
35  * Write messages are currently up to the size of the mailbox
36  * while read messages are up to 4 times the size of the
37  * mailbox, sent in packets
38  */
39 #define SDSI_SIZE_WRITE_MSG             SDSI_SIZE_MAILBOX
40 #define SDSI_SIZE_READ_MSG              (SDSI_SIZE_MAILBOX * 4)
41
42 #define SDSI_ENABLED_FEATURES_OFFSET    16
43 #define SDSI_FEATURE_SDSI               BIT(3)
44 #define SDSI_FEATURE_METERING           BIT(26)
45
46 #define SDSI_SOCKET_ID_OFFSET           64
47 #define SDSI_SOCKET_ID                  GENMASK(3, 0)
48
49 #define SDSI_MBOX_CMD_SUCCESS           0x40
50 #define SDSI_MBOX_CMD_TIMEOUT           0x80
51
52 #define MBOX_TIMEOUT_US                 2000
53 #define MBOX_TIMEOUT_ACQUIRE_US         1000
54 #define MBOX_POLLING_PERIOD_US          100
55 #define MBOX_ACQUIRE_NUM_RETRIES        5
56 #define MBOX_ACQUIRE_RETRY_DELAY_MS     500
57 #define MBOX_MAX_PACKETS                4
58
59 #define MBOX_OWNER_NONE                 0x00
60 #define MBOX_OWNER_INBAND               0x01
61
62 #define CTRL_RUN_BUSY                   BIT(0)
63 #define CTRL_READ_WRITE                 BIT(1)
64 #define CTRL_SOM                        BIT(2)
65 #define CTRL_EOM                        BIT(3)
66 #define CTRL_OWNER                      GENMASK(5, 4)
67 #define CTRL_COMPLETE                   BIT(6)
68 #define CTRL_READY                      BIT(7)
69 #define CTRL_STATUS                     GENMASK(15, 8)
70 #define CTRL_PACKET_SIZE                GENMASK(31, 16)
71 #define CTRL_MSG_SIZE                   GENMASK(63, 48)
72
73 #define DISC_TABLE_SIZE                 12
74 #define DT_ACCESS_TYPE                  GENMASK(3, 0)
75 #define DT_SIZE                         GENMASK(27, 12)
76 #define DT_TBIR                         GENMASK(2, 0)
77 #define DT_OFFSET(v)                    ((v) & GENMASK(31, 3))
78
79 #define SDSI_GUID_V1                    0x006DD191
80 #define GUID_V1_CNTRL_SIZE              8
81 #define GUID_V1_REGS_SIZE               72
82 #define SDSI_GUID_V2                    0xF210D9EF
83 #define GUID_V2_CNTRL_SIZE              16
84 #define GUID_V2_REGS_SIZE               80
85
86 enum sdsi_command {
87         SDSI_CMD_PROVISION_AKC          = 0x0004,
88         SDSI_CMD_PROVISION_CAP          = 0x0008,
89         SDSI_CMD_READ_STATE             = 0x0010,
90         SDSI_CMD_READ_METER             = 0x0014,
91 };
92
93 struct sdsi_mbox_info {
94         u64     *payload;
95         void    *buffer;
96         int     size;
97 };
98
99 struct disc_table {
100         u32     access_info;
101         u32     guid;
102         u32     offset;
103 };
104
105 struct sdsi_priv {
106         struct mutex            mb_lock;        /* Mailbox access lock */
107         struct device           *dev;
108         void __iomem            *control_addr;
109         void __iomem            *mbox_addr;
110         void __iomem            *regs_addr;
111         int                     control_size;
112         int                     maibox_size;
113         int                     registers_size;
114         u32                     guid;
115         u32                     features;
116 };
117
118 /* SDSi mailbox operations must be performed using 64bit mov instructions */
119 static __always_inline void
120 sdsi_memcpy64_toio(u64 __iomem *to, const u64 *from, size_t count_bytes)
121 {
122         size_t count = count_bytes / sizeof(*to);
123         int i;
124
125         for (i = 0; i < count; i++)
126                 writeq(from[i], &to[i]);
127 }
128
129 static __always_inline void
130 sdsi_memcpy64_fromio(u64 *to, const u64 __iomem *from, size_t count_bytes)
131 {
132         size_t count = count_bytes / sizeof(*to);
133         int i;
134
135         for (i = 0; i < count; i++)
136                 to[i] = readq(&from[i]);
137 }
138
139 static inline void sdsi_complete_transaction(struct sdsi_priv *priv)
140 {
141         u64 control = FIELD_PREP(CTRL_COMPLETE, 1);
142
143         lockdep_assert_held(&priv->mb_lock);
144         writeq(control, priv->control_addr);
145 }
146
147 static int sdsi_status_to_errno(u32 status)
148 {
149         switch (status) {
150         case SDSI_MBOX_CMD_SUCCESS:
151                 return 0;
152         case SDSI_MBOX_CMD_TIMEOUT:
153                 return -ETIMEDOUT;
154         default:
155                 return -EIO;
156         }
157 }
158
159 static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info,
160                               size_t *data_size)
161 {
162         struct device *dev = priv->dev;
163         u32 total, loop, eom, status, message_size;
164         u64 control;
165         int ret;
166
167         lockdep_assert_held(&priv->mb_lock);
168
169         /* Format and send the read command */
170         control = FIELD_PREP(CTRL_EOM, 1) |
171                   FIELD_PREP(CTRL_SOM, 1) |
172                   FIELD_PREP(CTRL_RUN_BUSY, 1) |
173                   FIELD_PREP(CTRL_PACKET_SIZE, info->size);
174         writeq(control, priv->control_addr);
175
176         /* For reads, data sizes that are larger than the mailbox size are read in packets. */
177         total = 0;
178         loop = 0;
179         do {
180                 void *buf = info->buffer + (SDSI_SIZE_MAILBOX * loop);
181                 u32 packet_size;
182
183                 /* Poll on ready bit */
184                 ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY,
185                                          MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US);
186                 if (ret)
187                         break;
188
189                 eom = FIELD_GET(CTRL_EOM, control);
190                 status = FIELD_GET(CTRL_STATUS, control);
191                 packet_size = FIELD_GET(CTRL_PACKET_SIZE, control);
192                 message_size = FIELD_GET(CTRL_MSG_SIZE, control);
193
194                 ret = sdsi_status_to_errno(status);
195                 if (ret)
196                         break;
197
198                 /* Only the last packet can be less than the mailbox size. */
199                 if (!eom && packet_size != SDSI_SIZE_MAILBOX) {
200                         dev_err(dev, "Invalid packet size\n");
201                         ret = -EPROTO;
202                         break;
203                 }
204
205                 if (packet_size > SDSI_SIZE_MAILBOX) {
206                         dev_err(dev, "Packet size too large\n");
207                         ret = -EPROTO;
208                         break;
209                 }
210
211                 sdsi_memcpy64_fromio(buf, priv->mbox_addr, round_up(packet_size, SDSI_SIZE_CMD));
212
213                 total += packet_size;
214
215                 sdsi_complete_transaction(priv);
216         } while (!eom && ++loop < MBOX_MAX_PACKETS);
217
218         if (ret) {
219                 sdsi_complete_transaction(priv);
220                 return ret;
221         }
222
223         if (!eom) {
224                 dev_err(dev, "Exceeded read attempts\n");
225                 return -EPROTO;
226         }
227
228         /* Message size check is only valid for multi-packet transfers */
229         if (loop && total != message_size)
230                 dev_warn(dev, "Read count %u differs from expected count %u\n",
231                          total, message_size);
232
233         *data_size = total;
234
235         return 0;
236 }
237
238 static int sdsi_mbox_cmd_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
239 {
240         u64 control;
241         u32 status;
242         int ret;
243
244         lockdep_assert_held(&priv->mb_lock);
245
246         /* Write rest of the payload */
247         sdsi_memcpy64_toio(priv->mbox_addr + SDSI_SIZE_CMD, info->payload + 1,
248                            info->size - SDSI_SIZE_CMD);
249
250         /* Format and send the write command */
251         control = FIELD_PREP(CTRL_EOM, 1) |
252                   FIELD_PREP(CTRL_SOM, 1) |
253                   FIELD_PREP(CTRL_RUN_BUSY, 1) |
254                   FIELD_PREP(CTRL_READ_WRITE, 1) |
255                   FIELD_PREP(CTRL_PACKET_SIZE, info->size);
256         writeq(control, priv->control_addr);
257
258         /* Poll on ready bit */
259         ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY,
260                                  MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US);
261
262         if (ret)
263                 goto release_mbox;
264
265         status = FIELD_GET(CTRL_STATUS, control);
266         ret = sdsi_status_to_errno(status);
267
268 release_mbox:
269         sdsi_complete_transaction(priv);
270
271         return ret;
272 }
273
274 static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
275 {
276         u64 control;
277         u32 owner;
278         int ret, retries = 0;
279
280         lockdep_assert_held(&priv->mb_lock);
281
282         /* Check mailbox is available */
283         control = readq(priv->control_addr);
284         owner = FIELD_GET(CTRL_OWNER, control);
285         if (owner != MBOX_OWNER_NONE)
286                 return -EBUSY;
287
288         /*
289          * If there has been no recent transaction and no one owns the mailbox,
290          * we should acquire it in under 1ms. However, if we've accessed it
291          * recently it may take up to 2.1 seconds to acquire it again.
292          */
293         do {
294                 /* Write first qword of payload */
295                 writeq(info->payload[0], priv->mbox_addr);
296
297                 /* Check for ownership */
298                 ret = readq_poll_timeout(priv->control_addr, control,
299                         FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_INBAND,
300                         MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US);
301
302                 if (FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_NONE &&
303                     retries++ < MBOX_ACQUIRE_NUM_RETRIES) {
304                         msleep(MBOX_ACQUIRE_RETRY_DELAY_MS);
305                         continue;
306                 }
307
308                 /* Either we got it or someone else did. */
309                 break;
310         } while (true);
311
312         return ret;
313 }
314
315 static int sdsi_mbox_write(struct sdsi_priv *priv, struct sdsi_mbox_info *info)
316 {
317         int ret;
318
319         lockdep_assert_held(&priv->mb_lock);
320
321         ret = sdsi_mbox_acquire(priv, info);
322         if (ret)
323                 return ret;
324
325         return sdsi_mbox_cmd_write(priv, info);
326 }
327
328 static int sdsi_mbox_read(struct sdsi_priv *priv, struct sdsi_mbox_info *info, size_t *data_size)
329 {
330         int ret;
331
332         lockdep_assert_held(&priv->mb_lock);
333
334         ret = sdsi_mbox_acquire(priv, info);
335         if (ret)
336                 return ret;
337
338         return sdsi_mbox_cmd_read(priv, info, data_size);
339 }
340
341 static ssize_t sdsi_provision(struct sdsi_priv *priv, char *buf, size_t count,
342                               enum sdsi_command command)
343 {
344         struct sdsi_mbox_info info;
345         int ret;
346
347         if (count > (SDSI_SIZE_WRITE_MSG - SDSI_SIZE_CMD))
348                 return -EOVERFLOW;
349
350         /* Qword aligned message + command qword */
351         info.size = round_up(count, SDSI_SIZE_CMD) + SDSI_SIZE_CMD;
352
353         info.payload = kzalloc(info.size, GFP_KERNEL);
354         if (!info.payload)
355                 return -ENOMEM;
356
357         /* Copy message to payload buffer */
358         memcpy(info.payload, buf, count);
359
360         /* Command is last qword of payload buffer */
361         info.payload[(info.size - SDSI_SIZE_CMD) / SDSI_SIZE_CMD] = command;
362
363         ret = mutex_lock_interruptible(&priv->mb_lock);
364         if (ret)
365                 goto free_payload;
366         ret = sdsi_mbox_write(priv, &info);
367         mutex_unlock(&priv->mb_lock);
368
369 free_payload:
370         kfree(info.payload);
371
372         if (ret)
373                 return ret;
374
375         return count;
376 }
377
378 static ssize_t provision_akc_write(struct file *filp, struct kobject *kobj,
379                                    struct bin_attribute *attr, char *buf, loff_t off,
380                                    size_t count)
381 {
382         struct device *dev = kobj_to_dev(kobj);
383         struct sdsi_priv *priv = dev_get_drvdata(dev);
384
385         if (off)
386                 return -ESPIPE;
387
388         return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_AKC);
389 }
390 static BIN_ATTR_WO(provision_akc, SDSI_SIZE_WRITE_MSG);
391
392 static ssize_t provision_cap_write(struct file *filp, struct kobject *kobj,
393                                    struct bin_attribute *attr, char *buf, loff_t off,
394                                    size_t count)
395 {
396         struct device *dev = kobj_to_dev(kobj);
397         struct sdsi_priv *priv = dev_get_drvdata(dev);
398
399         if (off)
400                 return -ESPIPE;
401
402         return sdsi_provision(priv, buf, count, SDSI_CMD_PROVISION_CAP);
403 }
404 static BIN_ATTR_WO(provision_cap, SDSI_SIZE_WRITE_MSG);
405
406 static ssize_t
407 certificate_read(u64 command, struct sdsi_priv *priv, char *buf, loff_t off,
408                  size_t count)
409 {
410         struct sdsi_mbox_info info;
411         size_t size;
412         int ret;
413
414         if (off)
415                 return 0;
416
417         /* Buffer for return data */
418         info.buffer = kmalloc(SDSI_SIZE_READ_MSG, GFP_KERNEL);
419         if (!info.buffer)
420                 return -ENOMEM;
421
422         info.payload = &command;
423         info.size = sizeof(command);
424
425         ret = mutex_lock_interruptible(&priv->mb_lock);
426         if (ret)
427                 goto free_buffer;
428         ret = sdsi_mbox_read(priv, &info, &size);
429         mutex_unlock(&priv->mb_lock);
430         if (ret < 0)
431                 goto free_buffer;
432
433         if (size > count)
434                 size = count;
435
436         memcpy(buf, info.buffer, size);
437
438 free_buffer:
439         kfree(info.buffer);
440
441         if (ret)
442                 return ret;
443
444         return size;
445 }
446
447 static ssize_t
448 state_certificate_read(struct file *filp, struct kobject *kobj,
449                        struct bin_attribute *attr, char *buf, loff_t off,
450                        size_t count)
451 {
452         struct device *dev = kobj_to_dev(kobj);
453         struct sdsi_priv *priv = dev_get_drvdata(dev);
454
455         return certificate_read(SDSI_CMD_READ_STATE, priv, buf, off, count);
456 }
457 static BIN_ATTR_ADMIN_RO(state_certificate, SDSI_SIZE_READ_MSG);
458
459 static ssize_t
460 meter_certificate_read(struct file *filp, struct kobject *kobj,
461                        struct bin_attribute *attr, char *buf, loff_t off,
462                        size_t count)
463 {
464         struct device *dev = kobj_to_dev(kobj);
465         struct sdsi_priv *priv = dev_get_drvdata(dev);
466
467         return certificate_read(SDSI_CMD_READ_METER, priv, buf, off, count);
468 }
469 static BIN_ATTR_ADMIN_RO(meter_certificate, SDSI_SIZE_READ_MSG);
470
471 static ssize_t registers_read(struct file *filp, struct kobject *kobj,
472                               struct bin_attribute *attr, char *buf, loff_t off,
473                               size_t count)
474 {
475         struct device *dev = kobj_to_dev(kobj);
476         struct sdsi_priv *priv = dev_get_drvdata(dev);
477         void __iomem *addr = priv->regs_addr;
478         int size =  priv->registers_size;
479
480         /*
481          * The check below is performed by the sysfs caller based on the static
482          * file size. But this may be greater than the actual size which is based
483          * on the GUID. So check here again based on actual size before reading.
484          */
485         if (off >= size)
486                 return 0;
487
488         if (off + count > size)
489                 count = size - off;
490
491         memcpy_fromio(buf, addr + off, count);
492
493         return count;
494 }
495 static BIN_ATTR_ADMIN_RO(registers, SDSI_SIZE_REGS);
496
497 static struct bin_attribute *sdsi_bin_attrs[] = {
498         &bin_attr_registers,
499         &bin_attr_state_certificate,
500         &bin_attr_meter_certificate,
501         &bin_attr_provision_akc,
502         &bin_attr_provision_cap,
503         NULL
504 };
505
506 static umode_t
507 sdsi_battr_is_visible(struct kobject *kobj, struct bin_attribute *attr, int n)
508 {
509         struct device *dev = kobj_to_dev(kobj);
510         struct sdsi_priv *priv = dev_get_drvdata(dev);
511
512         /* Registers file is always readable if the device is present */
513         if (attr == &bin_attr_registers)
514                 return attr->attr.mode;
515
516         /* All other attributes not visible if BIOS has not enabled On Demand */
517         if (!(priv->features & SDSI_FEATURE_SDSI))
518                 return 0;
519
520         if (attr == &bin_attr_meter_certificate)
521                 return (priv->features & SDSI_FEATURE_METERING) ?
522                                 attr->attr.mode : 0;
523
524         return attr->attr.mode;
525 }
526
527 static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf)
528 {
529         struct sdsi_priv *priv = dev_get_drvdata(dev);
530
531         return sysfs_emit(buf, "0x%x\n", priv->guid);
532 }
533 static DEVICE_ATTR_RO(guid);
534
535 static struct attribute *sdsi_attrs[] = {
536         &dev_attr_guid.attr,
537         NULL
538 };
539
540 static const struct attribute_group sdsi_group = {
541         .attrs = sdsi_attrs,
542         .bin_attrs = sdsi_bin_attrs,
543         .is_bin_visible = sdsi_battr_is_visible,
544 };
545 __ATTRIBUTE_GROUPS(sdsi);
546
547 static int sdsi_get_layout(struct sdsi_priv *priv, struct disc_table *table)
548 {
549         switch (table->guid) {
550         case SDSI_GUID_V1:
551                 priv->control_size = GUID_V1_CNTRL_SIZE;
552                 priv->registers_size = GUID_V1_REGS_SIZE;
553                 break;
554         case SDSI_GUID_V2:
555                 priv->control_size = GUID_V2_CNTRL_SIZE;
556                 priv->registers_size = GUID_V2_REGS_SIZE;
557                 break;
558         default:
559                 dev_err(priv->dev, "Unrecognized GUID 0x%x\n", table->guid);
560                 return -EINVAL;
561         }
562         return 0;
563 }
564
565 static int sdsi_map_mbox_registers(struct sdsi_priv *priv, struct pci_dev *parent,
566                                    struct disc_table *disc_table, struct resource *disc_res)
567 {
568         u32 access_type = FIELD_GET(DT_ACCESS_TYPE, disc_table->access_info);
569         u32 size = FIELD_GET(DT_SIZE, disc_table->access_info);
570         u32 tbir = FIELD_GET(DT_TBIR, disc_table->offset);
571         u32 offset = DT_OFFSET(disc_table->offset);
572         struct resource res = {};
573
574         /* Starting location of SDSi MMIO region based on access type */
575         switch (access_type) {
576         case ACCESS_TYPE_LOCAL:
577                 if (tbir) {
578                         dev_err(priv->dev, "Unsupported BAR index %u for access type %u\n",
579                                 tbir, access_type);
580                         return -EINVAL;
581                 }
582
583                 /*
584                  * For access_type LOCAL, the base address is as follows:
585                  * base address = end of discovery region + base offset + 1
586                  */
587                 res.start = disc_res->end + offset + 1;
588                 break;
589
590         case ACCESS_TYPE_BARID:
591                 res.start = pci_resource_start(parent, tbir) + offset;
592                 break;
593
594         default:
595                 dev_err(priv->dev, "Unrecognized access_type %u\n", access_type);
596                 return -EINVAL;
597         }
598
599         res.end = res.start + size * sizeof(u32) - 1;
600         res.flags = IORESOURCE_MEM;
601
602         priv->control_addr = devm_ioremap_resource(priv->dev, &res);
603         if (IS_ERR(priv->control_addr))
604                 return PTR_ERR(priv->control_addr);
605
606         priv->mbox_addr = priv->control_addr + priv->control_size;
607         priv->regs_addr = priv->mbox_addr + SDSI_SIZE_MAILBOX;
608
609         priv->features = readq(priv->regs_addr + SDSI_ENABLED_FEATURES_OFFSET);
610
611         return 0;
612 }
613
614 static int sdsi_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id)
615 {
616         struct intel_vsec_device *intel_cap_dev = auxdev_to_ivdev(auxdev);
617         struct disc_table disc_table;
618         struct resource *disc_res;
619         void __iomem *disc_addr;
620         struct sdsi_priv *priv;
621         int ret;
622
623         priv = devm_kzalloc(&auxdev->dev, sizeof(*priv), GFP_KERNEL);
624         if (!priv)
625                 return -ENOMEM;
626
627         priv->dev = &auxdev->dev;
628         mutex_init(&priv->mb_lock);
629         auxiliary_set_drvdata(auxdev, priv);
630
631         /* Get the SDSi discovery table */
632         disc_res = &intel_cap_dev->resource[0];
633         disc_addr = devm_ioremap_resource(&auxdev->dev, disc_res);
634         if (IS_ERR(disc_addr))
635                 return PTR_ERR(disc_addr);
636
637         memcpy_fromio(&disc_table, disc_addr, DISC_TABLE_SIZE);
638
639         priv->guid = disc_table.guid;
640
641         /* Get guid based layout info */
642         ret = sdsi_get_layout(priv, &disc_table);
643         if (ret)
644                 return ret;
645
646         /* Map the SDSi mailbox registers */
647         ret = sdsi_map_mbox_registers(priv, intel_cap_dev->pcidev, &disc_table, disc_res);
648         if (ret)
649                 return ret;
650
651         return 0;
652 }
653
654 static const struct auxiliary_device_id sdsi_aux_id_table[] = {
655         { .name = "intel_vsec.sdsi" },
656         {}
657 };
658 MODULE_DEVICE_TABLE(auxiliary, sdsi_aux_id_table);
659
660 static struct auxiliary_driver sdsi_aux_driver = {
661         .driver = {
662                 .dev_groups = sdsi_groups,
663         },
664         .id_table       = sdsi_aux_id_table,
665         .probe          = sdsi_probe,
666         /* No remove. All resources are handled under devm */
667 };
668 module_auxiliary_driver(sdsi_aux_driver);
669
670 MODULE_AUTHOR("David E. Box <[email protected]>");
671 MODULE_DESCRIPTION("Intel On Demand (SDSi) driver");
672 MODULE_LICENSE("GPL");
This page took 0.075168 seconds and 4 git commands to generate.