Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cxl: Add support for POWER9 DD2

The PSL initialization sequence has been updated to DD2.
This patch adapts to the changes, retaining compatibility with DD1.
The patch includes some changes to DD1 fix-ups as well.

Tests performed on some of the old/new hardware.

The function is_page_fault(), for POWER9, lists the Translation Checkout
Responses where the page fault will be handled by copro_handle_mm_fault().
This list is too restrictive and not necessary.

This patches removes this restriction and all page faults, whatever the
reason, will be handled. In this case, the interruption is always
acknowledged.

The following features will be added soon:
- phb reset when switching to capi mode.
- cxllib update to support new functions.

Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>

Acked-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
Reviewed-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

authored by

Christophe Lombard and committed by
Michael Ellerman
56328743 4ca360f3

+28 -36
+2
drivers/misc/cxl/cxl.h
··· 100 100 static const cxl_p1_reg_t CXL_XSL_DSNCTL = {0x0168}; 101 101 /* PSL registers - CAIA 2 */ 102 102 static const cxl_p1_reg_t CXL_PSL9_CONTROL = {0x0020}; 103 + static const cxl_p1_reg_t CXL_XSL9_INV = {0x0110}; 104 + static const cxl_p1_reg_t CXL_XSL9_DEF = {0x0140}; 103 105 static const cxl_p1_reg_t CXL_XSL9_DSNCTL = {0x0168}; 104 106 static const cxl_p1_reg_t CXL_PSL9_FIR1 = {0x0300}; 105 107 static const cxl_p1_reg_t CXL_PSL9_FIR2 = {0x0308};
+2 -13
drivers/misc/cxl/fault.c
··· 220 220 221 221 static bool cxl_is_page_fault(struct cxl_context *ctx, u64 dsisr) 222 222 { 223 - u64 crs; /* Translation Checkout Response Status */ 224 - 225 223 if ((cxl_is_power8()) && (dsisr & CXL_PSL_DSISR_An_DM)) 226 224 return true; 227 225 228 - if (cxl_is_power9()) { 229 - crs = (dsisr & CXL_PSL9_DSISR_An_CO_MASK); 230 - if ((crs == CXL_PSL9_DSISR_An_PF_SLR) || 231 - (crs == CXL_PSL9_DSISR_An_PF_RGC) || 232 - (crs == CXL_PSL9_DSISR_An_PF_RGP) || 233 - (crs == CXL_PSL9_DSISR_An_PF_HRH) || 234 - (crs == CXL_PSL9_DSISR_An_PF_STEG) || 235 - (crs == CXL_PSL9_DSISR_An_URTCH)) { 236 - return true; 237 - } 238 - } 226 + if (cxl_is_power9()) 227 + return true; 239 228 240 229 return false; 241 230 }
+24 -23
drivers/misc/cxl/pci.c
··· 401 401 *capp_unit_id = get_capp_unit_id(np, *phb_index); 402 402 of_node_put(np); 403 403 if (!*capp_unit_id) { 404 - pr_err("cxl: invalid capp unit id\n"); 404 + pr_err("cxl: invalid capp unit id (phb_index: %d)\n", 405 + *phb_index); 405 406 return -ENODEV; 406 407 } 407 408 ··· 476 475 psl_fircntl |= 0x1ULL; /* ce_thresh */ 477 476 cxl_p1_write(adapter, CXL_PSL9_FIR_CNTL, psl_fircntl); 478 477 479 - /* vccredits=0x1 pcklat=0x4 */ 480 - cxl_p1_write(adapter, CXL_PSL9_DSNDCTL, 0x0000000000001810ULL); 481 - 482 - /* 483 - * For debugging with trace arrays. 484 - * Configure RX trace 0 segmented mode. 485 - * Configure CT trace 0 segmented mode. 486 - * Configure LA0 trace 0 segmented mode. 487 - * Configure LA1 trace 0 segmented mode. 478 + /* Setup the PSL to transmit packets on the PCIe before the 479 + * CAPP is enabled 488 480 */ 489 - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000000ULL); 490 - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000003ULL); 491 - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000005ULL); 492 - cxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000006ULL); 481 + cxl_p1_write(adapter, CXL_PSL9_DSNDCTL, 0x0001001000002A10ULL); 493 482 494 483 /* 495 484 * A response to an ASB_Notify request is returned by the 496 485 * system as an MMIO write to the address defined in 497 - * the PSL_TNR_ADDR register 486 + * the PSL_TNR_ADDR register. 487 + * keep the Reset Value: 0x00020000E0000000 498 488 */ 499 - /* PSL_TNR_ADDR */ 500 489 501 - /* NORST */ 502 - cxl_p1_write(adapter, CXL_PSL9_DEBUG, 0x8000000000000000ULL); 490 + /* Enable XSL rty limit */ 491 + cxl_p1_write(adapter, CXL_XSL9_DEF, 0x51F8000000000005ULL); 503 492 504 - /* allocate the apc machines */ 505 - cxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000003FFFF0000ULL); 493 + /* Change XSL_INV dummy read threshold */ 494 + cxl_p1_write(adapter, CXL_XSL9_INV, 0x0000040007FFC200ULL); 506 495 507 - /* Disable vc dd1 fix */ 508 - if (cxl_is_power9_dd1()) 509 - cxl_p1_write(adapter, CXL_PSL9_GP_CT, 0x0400000000000001ULL); 496 + if (phb_index == 3) { 497 + /* disable machines 31-47 and 20-27 for DMA */ 498 + cxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000FF3FFFF0000ULL); 499 + } 500 + 501 + /* Snoop machines */ 502 + cxl_p1_write(adapter, CXL_PSL9_APCDEDALLOC, 0x800F000200000000ULL); 503 + 504 + if (cxl_is_power9_dd1()) { 505 + /* Disabling deadlock counter CAR */ 506 + cxl_p1_write(adapter, CXL_PSL9_GP_CT, 0x0020000000000001ULL); 507 + } else 508 + cxl_p1_write(adapter, CXL_PSL9_DEBUG, 0x4000000000000000ULL); 510 509 511 510 return 0; 512 511 }