summaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-13 19:08:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-13 19:08:36 -0400
commit192f0f8e9db7efe4ac98d47f5fa4334e43c1204d (patch)
tree9d1f274bf91e30bafc1296ca0520f7ef49c5d15a /drivers/misc
parentec9249752465b87b5b26d03f476eebaf872ebd12 (diff)
parentf5a9e488d62360c91c5770bd55a0b40e419a71ce (diff)
Merge tag 'powerpc-5.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Michael Ellerman: "Notable changes: - Removal of the NPU DMA code, used by the out-of-tree Nvidia driver, as well as some other functions only used by drivers that haven't (yet?) made it upstream. - A fix for a bug in our handling of hardware watchpoints (eg. perf record -e mem: ...) which could lead to register corruption and kernel crashes. - Enable HAVE_ARCH_HUGE_VMAP, which allows us to use large pages for vmalloc when using the Radix MMU. - A large but incremental rewrite of our exception handling code to use gas macros rather than multiple levels of nested CPP macros. And the usual small fixes, cleanups and improvements. Thanks to: Alastair D'Silva, Alexey Kardashevskiy, Andreas Schwab, Aneesh Kumar K.V, Anju T Sudhakar, Anton Blanchard, Arnd Bergmann, Athira Rajeev, Cédric Le Goater, Christian Lamparter, Christophe Leroy, Christophe Lombard, Christoph Hellwig, Daniel Axtens, Denis Efremov, Enrico Weigelt, Frederic Barrat, Gautham R. Shenoy, Geert Uytterhoeven, Geliang Tang, Gen Zhang, Greg Kroah-Hartman, Greg Kurz, Gustavo Romero, Krzysztof Kozlowski, Madhavan Srinivasan, Masahiro Yamada, Mathieu Malaterre, Michael Neuling, Nathan Lynch, Naveen N. Rao, Nicholas Piggin, Nishad Kamdar, Oliver O'Halloran, Qian Cai, Ravi Bangoria, Sachin Sant, Sam Bobroff, Satheesh Rajendran, Segher Boessenkool, Shaokun Zhang, Shawn Anastasio, Stewart Smith, Suraj Jitindar Singh, Thiago Jung Bauermann, YueHaibing" * tag 'powerpc-5.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (163 commits) powerpc/powernv/idle: Fix restore of SPRN_LDBAR for POWER9 stop state. powerpc/eeh: Handle hugepages in ioremap space ocxl: Update for AFU descriptor template version 1.1 powerpc/boot: pass CONFIG options in a simpler and more robust way powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h powerpc/irq: Don't WARN continuously in arch_local_irq_restore() powerpc/module64: Use symbolic instructions names. powerpc/module32: Use symbolic instructions names. powerpc: Move PPC_HA() PPC_HI() and PPC_LO() to ppc-opcode.h powerpc/module64: Fix comment in R_PPC64_ENTRY handling powerpc/boot: Add lzo support for uImage powerpc/boot: Add lzma support for uImage powerpc/boot: don't force gzipped uImage powerpc/8xx: Add microcode patch to move SMC parameter RAM. powerpc/8xx: Use IO accessors in microcode programming. powerpc/8xx: replace #ifdefs by IS_ENABLED() in microcode.c powerpc/8xx: refactor programming of microcode CPM params. powerpc/8xx: refactor printing of microcode patch name. powerpc/8xx: Refactor microcode write powerpc/8xx: refactor writing of CPM microcode arrays ...
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/ocxl/config.c181
-rw-r--r--drivers/misc/ocxl/pci.c2
2 files changed, 162 insertions, 21 deletions
diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
index 5e65acb8e134..c8e19bfb5ef9 100644
--- a/drivers/misc/ocxl/config.c
+++ b/drivers/misc/ocxl/config.c
@@ -20,11 +20,14 @@
20#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ 0x28 20#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ 0x28
21#define OCXL_DVSEC_TEMPL_MMIO_PP 0x30 21#define OCXL_DVSEC_TEMPL_MMIO_PP 0x30
22#define OCXL_DVSEC_TEMPL_MMIO_PP_SZ 0x38 22#define OCXL_DVSEC_TEMPL_MMIO_PP_SZ 0x38
23#define OCXL_DVSEC_TEMPL_MEM_SZ 0x3C 23#define OCXL_DVSEC_TEMPL_ALL_MEM_SZ 0x3C
24#define OCXL_DVSEC_TEMPL_WWID 0x40 24#define OCXL_DVSEC_TEMPL_LPC_MEM_START 0x40
25#define OCXL_DVSEC_TEMPL_WWID 0x48
26#define OCXL_DVSEC_TEMPL_LPC_MEM_SZ 0x58
25 27
26#define OCXL_MAX_AFU_PER_FUNCTION 64 28#define OCXL_MAX_AFU_PER_FUNCTION 64
27#define OCXL_TEMPL_LEN 0x58 29#define OCXL_TEMPL_LEN_1_0 0x58
30#define OCXL_TEMPL_LEN_1_1 0x60
28#define OCXL_TEMPL_NAME_LEN 24 31#define OCXL_TEMPL_NAME_LEN 24
29#define OCXL_CFG_TIMEOUT 3 32#define OCXL_CFG_TIMEOUT 3
30 33
@@ -269,34 +272,72 @@ static int read_afu_info(struct pci_dev *dev, struct ocxl_fn_config *fn,
269 return 0; 272 return 0;
270} 273}
271 274
275/**
276 * Read the template version from the AFU
277 * dev: the device for the AFU
278 * fn: the AFU offsets
279 * len: outputs the template length
280 * version: outputs the major<<8,minor version
281 *
282 * Returns 0 on success, negative on failure
283 */
284static int read_template_version(struct pci_dev *dev, struct ocxl_fn_config *fn,
285 u16 *len, u16 *version)
286{
287 u32 val32;
288 u8 major, minor;
289 int rc;
290
291 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_VERSION, &val32);
292 if (rc)
293 return rc;
294
295 *len = EXTRACT_BITS(val32, 16, 31);
296 major = EXTRACT_BITS(val32, 8, 15);
297 minor = EXTRACT_BITS(val32, 0, 7);
298 *version = (major << 8) + minor;
299 return 0;
300}
301
272int ocxl_config_check_afu_index(struct pci_dev *dev, 302int ocxl_config_check_afu_index(struct pci_dev *dev,
273 struct ocxl_fn_config *fn, int afu_idx) 303 struct ocxl_fn_config *fn, int afu_idx)
274{ 304{
275 u32 val; 305 int rc;
276 int rc, templ_major, templ_minor, len; 306 u16 templ_version;
307 u16 len, expected_len;
277 308
278 pci_write_config_byte(dev, 309 pci_write_config_byte(dev,
279 fn->dvsec_afu_info_pos + OCXL_DVSEC_AFU_INFO_AFU_IDX, 310 fn->dvsec_afu_info_pos + OCXL_DVSEC_AFU_INFO_AFU_IDX,
280 afu_idx); 311 afu_idx);
281 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_VERSION, &val); 312
313 rc = read_template_version(dev, fn, &len, &templ_version);
282 if (rc) 314 if (rc)
283 return rc; 315 return rc;
284 316
285 /* AFU index map can have holes */ 317 /* AFU index map can have holes, in which case we read all 0's */
286 if (!val) 318 if (!templ_version && !len)
287 return 0; 319 return 0;
288 320
289 templ_major = EXTRACT_BITS(val, 8, 15);
290 templ_minor = EXTRACT_BITS(val, 0, 7);
291 dev_dbg(&dev->dev, "AFU descriptor template version %d.%d\n", 321 dev_dbg(&dev->dev, "AFU descriptor template version %d.%d\n",
292 templ_major, templ_minor); 322 templ_version >> 8, templ_version & 0xFF);
293 323
294 len = EXTRACT_BITS(val, 16, 31); 324 switch (templ_version) {
295 if (len != OCXL_TEMPL_LEN) { 325 case 0x0005: // v0.5 was used prior to the spec approval
296 dev_warn(&dev->dev, 326 case 0x0100:
297 "Unexpected template length in AFU information (%#x)\n", 327 expected_len = OCXL_TEMPL_LEN_1_0;
298 len); 328 break;
329 case 0x0101:
330 expected_len = OCXL_TEMPL_LEN_1_1;
331 break;
332 default:
333 dev_warn(&dev->dev, "Unknown AFU template version %#x\n",
334 templ_version);
335 expected_len = len;
299 } 336 }
337 if (len != expected_len)
338 dev_warn(&dev->dev,
339 "Unexpected template length %#x in AFU information, expected %#x for version %#x\n",
340 len, expected_len, templ_version);
300 return 1; 341 return 1;
301} 342}
302 343
@@ -434,6 +475,102 @@ static int validate_afu(struct pci_dev *dev, struct ocxl_afu_config *afu)
434 return 0; 475 return 0;
435} 476}
436 477
478/**
479 * Populate AFU metadata regarding LPC memory
480 * dev: the device for the AFU
481 * fn: the AFU offsets
482 * afu: the AFU struct to populate the LPC metadata into
483 *
484 * Returns 0 on success, negative on failure
485 */
486static int read_afu_lpc_memory_info(struct pci_dev *dev,
487 struct ocxl_fn_config *fn,
488 struct ocxl_afu_config *afu)
489{
490 int rc;
491 u32 val32;
492 u16 templ_version;
493 u16 templ_len;
494 u64 total_mem_size = 0;
495 u64 lpc_mem_size = 0;
496
497 afu->lpc_mem_offset = 0;
498 afu->lpc_mem_size = 0;
499 afu->special_purpose_mem_offset = 0;
500 afu->special_purpose_mem_size = 0;
501 /*
502 * For AFUs following template v1.0, the LPC memory covers the
503 * total memory. Its size is a power of 2.
504 *
505 * For AFUs with template >= v1.01, the total memory size is
506 * still a power of 2, but it is split in 2 parts:
507 * - the LPC memory, whose size can now be anything
508 * - the remainder memory is a special purpose memory, whose
509 * definition is AFU-dependent. It is not accessible through
510 * the usual commands for LPC memory
511 */
512 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_ALL_MEM_SZ, &val32);
513 if (rc)
514 return rc;
515
516 val32 = EXTRACT_BITS(val32, 0, 7);
517 if (!val32)
518 return 0; /* No LPC memory */
519
520 /*
521 * The configuration space spec allows for a memory size of up
522 * to 2^255 bytes.
523 *
524 * Current generation hardware uses 56-bit physical addresses,
525 * but we won't be able to get near close to that, as we won't
526 * have a hole big enough in the memory map. Let it pass in
527 * the driver for now. We'll get an error from the firmware
528 * when trying to configure something too big.
529 */
530 total_mem_size = 1ull << val32;
531
532 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_LPC_MEM_START, &val32);
533 if (rc)
534 return rc;
535
536 afu->lpc_mem_offset = val32;
537
538 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_LPC_MEM_START + 4, &val32);
539 if (rc)
540 return rc;
541
542 afu->lpc_mem_offset |= (u64) val32 << 32;
543
544 rc = read_template_version(dev, fn, &templ_len, &templ_version);
545 if (rc)
546 return rc;
547
548 if (templ_version >= 0x0101) {
549 rc = read_afu_info(dev, fn,
550 OCXL_DVSEC_TEMPL_LPC_MEM_SZ, &val32);
551 if (rc)
552 return rc;
553 lpc_mem_size = val32;
554
555 rc = read_afu_info(dev, fn,
556 OCXL_DVSEC_TEMPL_LPC_MEM_SZ + 4, &val32);
557 if (rc)
558 return rc;
559 lpc_mem_size |= (u64) val32 << 32;
560 } else {
561 lpc_mem_size = total_mem_size;
562 }
563 afu->lpc_mem_size = lpc_mem_size;
564
565 if (lpc_mem_size < total_mem_size) {
566 afu->special_purpose_mem_offset =
567 afu->lpc_mem_offset + lpc_mem_size;
568 afu->special_purpose_mem_size =
569 total_mem_size - lpc_mem_size;
570 }
571 return 0;
572}
573
437int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn, 574int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn,
438 struct ocxl_afu_config *afu, u8 afu_idx) 575 struct ocxl_afu_config *afu, u8 afu_idx)
439{ 576{
@@ -467,10 +604,9 @@ int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn,
467 if (rc) 604 if (rc)
468 return rc; 605 return rc;
469 606
470 rc = read_afu_info(dev, fn, OCXL_DVSEC_TEMPL_MEM_SZ, &val32); 607 rc = read_afu_lpc_memory_info(dev, fn, afu);
471 if (rc) 608 if (rc)
472 return rc; 609 return rc;
473 afu->log_mem_size = EXTRACT_BITS(val32, 0, 7);
474 610
475 rc = read_afu_control(dev, afu); 611 rc = read_afu_control(dev, afu);
476 if (rc) 612 if (rc)
@@ -487,7 +623,12 @@ int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn,
487 dev_dbg(&dev->dev, " pp mmio bar = %hhu\n", afu->pp_mmio_bar); 623 dev_dbg(&dev->dev, " pp mmio bar = %hhu\n", afu->pp_mmio_bar);
488 dev_dbg(&dev->dev, " pp mmio offset = %#llx\n", afu->pp_mmio_offset); 624 dev_dbg(&dev->dev, " pp mmio offset = %#llx\n", afu->pp_mmio_offset);
489 dev_dbg(&dev->dev, " pp mmio stride = %#x\n", afu->pp_mmio_stride); 625 dev_dbg(&dev->dev, " pp mmio stride = %#x\n", afu->pp_mmio_stride);
490 dev_dbg(&dev->dev, " mem size (log) = %hhu\n", afu->log_mem_size); 626 dev_dbg(&dev->dev, " lpc_mem offset = %#llx\n", afu->lpc_mem_offset);
627 dev_dbg(&dev->dev, " lpc_mem size = %#llx\n", afu->lpc_mem_size);
628 dev_dbg(&dev->dev, " special purpose mem offset = %#llx\n",
629 afu->special_purpose_mem_offset);
630 dev_dbg(&dev->dev, " special purpose mem size = %#llx\n",
631 afu->special_purpose_mem_size);
491 dev_dbg(&dev->dev, " pasid supported (log) = %u\n", 632 dev_dbg(&dev->dev, " pasid supported (log) = %u\n",
492 afu->pasid_supported_log); 633 afu->pasid_supported_log);
493 dev_dbg(&dev->dev, " actag supported = %u\n", 634 dev_dbg(&dev->dev, " actag supported = %u\n",
diff --git a/drivers/misc/ocxl/pci.c b/drivers/misc/ocxl/pci.c
index f2a3ef4b9bdd..cb920aa88d3a 100644
--- a/drivers/misc/ocxl/pci.c
+++ b/drivers/misc/ocxl/pci.c
@@ -41,7 +41,7 @@ static int ocxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
41 return 0; 41 return 0;
42} 42}
43 43
44void ocxl_remove(struct pci_dev *dev) 44static void ocxl_remove(struct pci_dev *dev)
45{ 45{
46 struct ocxl_fn *fn; 46 struct ocxl_fn *fn;
47 struct ocxl_afu *afu; 47 struct ocxl_afu *afu;