aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilippe Bergheaud <felix@linux.vnet.ibm.com>2015-08-28 03:37:36 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-08-30 04:56:34 -0400
commit390fd5929f52bdfb9dfcc03820041ba556780f4a (patch)
treeb74dc3c63d9748ee953671ee3c7cc2bc6dec3300
parent55e07668fbba9466e6a9ef7650718356cda38406 (diff)
cxl: Set up and enable PSL Timebase
This patch configures the PSL Timebase function and enables it, after the CAPP has been initialized by OPAL. Acked-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Philippe Bergheaud <felix@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--drivers/misc/cxl/cxl.h5
-rw-r--r--drivers/misc/cxl/pci.c57
2 files changed, 61 insertions, 1 deletions
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index d6566c60bcb0..1c30ef77073d 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -83,8 +83,10 @@ static const cxl_p1_reg_t CXL_PSL_AFUSEL = {0x00B0};
83/* 0x00C0:7EFF Implementation dependent area */ 83/* 0x00C0:7EFF Implementation dependent area */
84static const cxl_p1_reg_t CXL_PSL_FIR1 = {0x0100}; 84static const cxl_p1_reg_t CXL_PSL_FIR1 = {0x0100};
85static const cxl_p1_reg_t CXL_PSL_FIR2 = {0x0108}; 85static const cxl_p1_reg_t CXL_PSL_FIR2 = {0x0108};
86static const cxl_p1_reg_t CXL_PSL_Timebase = {0x0110};
86static const cxl_p1_reg_t CXL_PSL_VERSION = {0x0118}; 87static const cxl_p1_reg_t CXL_PSL_VERSION = {0x0118};
87static const cxl_p1_reg_t CXL_PSL_RESLCKTO = {0x0128}; 88static const cxl_p1_reg_t CXL_PSL_RESLCKTO = {0x0128};
89static const cxl_p1_reg_t CXL_PSL_TB_CTLSTAT = {0x0140};
88static const cxl_p1_reg_t CXL_PSL_FIR_CNTL = {0x0148}; 90static const cxl_p1_reg_t CXL_PSL_FIR_CNTL = {0x0148};
89static const cxl_p1_reg_t CXL_PSL_DSNDCTL = {0x0150}; 91static const cxl_p1_reg_t CXL_PSL_DSNDCTL = {0x0150};
90static const cxl_p1_reg_t CXL_PSL_SNWRALLOC = {0x0158}; 92static const cxl_p1_reg_t CXL_PSL_SNWRALLOC = {0x0158};
@@ -152,6 +154,9 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0};
152#define CXL_PSL_SPAP_Size_Shift 4 154#define CXL_PSL_SPAP_Size_Shift 4
153#define CXL_PSL_SPAP_V 0x0000000000000001ULL 155#define CXL_PSL_SPAP_V 0x0000000000000001ULL
154 156
157/****** CXL_PSL_Control ****************************************************/
158#define CXL_PSL_Control_tb 0x0000000000000001ULL
159
155/****** CXL_PSL_DLCNTL *****************************************************/ 160/****** CXL_PSL_DLCNTL *****************************************************/
156#define CXL_PSL_DLCNTL_D (0x1ull << (63-28)) 161#define CXL_PSL_DLCNTL_D (0x1ull << (63-28))
157#define CXL_PSL_DLCNTL_C (0x1ull << (63-29)) 162#define CXL_PSL_DLCNTL_C (0x1ull << (63-29))
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 6ca7c3d0ef9b..02c85160bfe9 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -370,6 +370,55 @@ static int init_implementation_adapter_regs(struct cxl *adapter, struct pci_dev
370 return 0; 370 return 0;
371} 371}
372 372
373#define TBSYNC_CNT(n) (((u64)n & 0x7) << (63-6))
374#define _2048_250MHZ_CYCLES 1
375
376static int cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
377{
378 u64 psl_tb;
379 int delta;
380 unsigned int retry = 0;
381 struct device_node *np;
382
383 if (!(np = pnv_pci_get_phb_node(dev)))
384 return -ENODEV;
385
386 /* Do not fail when CAPP timebase sync is not supported by OPAL */
387 of_node_get(np);
388 if (! of_get_property(np, "ibm,capp-timebase-sync", NULL)) {
389 of_node_put(np);
390 pr_err("PSL: Timebase sync: OPAL support missing\n");
391 return 0;
392 }
393 of_node_put(np);
394
395 /*
396 * Setup PSL Timebase Control and Status register
397 * with the recommended Timebase Sync Count value
398 */
399 cxl_p1_write(adapter, CXL_PSL_TB_CTLSTAT,
400 TBSYNC_CNT(2 * _2048_250MHZ_CYCLES));
401
402 /* Enable PSL Timebase */
403 cxl_p1_write(adapter, CXL_PSL_Control, 0x0000000000000000);
404 cxl_p1_write(adapter, CXL_PSL_Control, CXL_PSL_Control_tb);
405
406 /* Wait until CORE TB and PSL TB difference <= 16usecs */
407 do {
408 msleep(1);
409 if (retry++ > 5) {
410 pr_err("PSL: Timebase sync: giving up!\n");
411 return -EIO;
412 }
413 psl_tb = cxl_p1_read(adapter, CXL_PSL_Timebase);
414 delta = mftb() - psl_tb;
415 if (delta < 0)
416 delta = -delta;
417 } while (cputime_to_usecs(delta) > 16);
418
419 return 0;
420}
421
373static int init_implementation_afu_regs(struct cxl_afu *afu) 422static int init_implementation_afu_regs(struct cxl_afu *afu)
374{ 423{
375 /* read/write masks for this slice */ 424 /* read/write masks for this slice */
@@ -1053,9 +1102,12 @@ err1:
1053 return NULL; 1102 return NULL;
1054} 1103}
1055 1104
1105#define CXL_PSL_ErrIVTE_tberror (0x1ull << (63-31))
1106
1056static int sanitise_adapter_regs(struct cxl *adapter) 1107static int sanitise_adapter_regs(struct cxl *adapter)
1057{ 1108{
1058 cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000); 1109 /* Clear PSL tberror bit by writing 1 to it */
1110 cxl_p1_write(adapter, CXL_PSL_ErrIVTE, CXL_PSL_ErrIVTE_tberror);
1059 return cxl_tlb_slb_invalidate(adapter); 1111 return cxl_tlb_slb_invalidate(adapter);
1060} 1112}
1061 1113
@@ -1108,6 +1160,9 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
1108 if ((rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_SNOOP_ON))) 1160 if ((rc = pnv_phb_to_cxl_mode(dev, OPAL_PHB_CAPI_MODE_SNOOP_ON)))
1109 goto err; 1161 goto err;
1110 1162
1163 if ((rc = cxl_setup_psl_timebase(adapter, dev)))
1164 goto err;
1165
1111 if ((rc = cxl_register_psl_err_irq(adapter))) 1166 if ((rc = cxl_register_psl_err_irq(adapter)))
1112 goto err; 1167 goto err;
1113 1168