Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2be663d authored by Christophe Lombard's avatar Christophe Lombard Committed by Michael Ellerman
Browse files

cxl: Fix timebase synchronization status on P9



The PSL Timebase register is updated by the PSL to maintain the
timebase.

On P9, the Timebase value is only provided by the CAPP as received the
last time a timebase request was performed.

The timebase requests are initiated through the adapter configuration
or application registers.

The specific sysfs entry "/sys/class/cxl/cardxx/psl_timebase_synced"
is now dynamically updated according the content of the PSL Timebase
register.

Fixes: f24be42a ("cxl: Add psl9 specific code")
Signed-off-by: default avatarChristophe Lombard <clombard@linux.vnet.ibm.com>
Reviewed-by: default avatarVaibhav Jain <vaibhav@linux.vnet.ibm.com>
Acked-by: default avatarAndrew Donnellan <andrew.donnellan@au1.ibm.com>
Acked-by: default avatarFrederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 014a32b3
Loading
Loading
Loading
Loading
+0 −17
Original line number Original line Diff line number Diff line
@@ -659,9 +659,6 @@ static u64 timebase_read_xsl(struct cxl *adapter)


static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
{
{
	u64 psl_tb;
	int delta;
	unsigned int retry = 0;
	struct device_node *np;
	struct device_node *np;


	adapter->psl_timebase_synced = false;
	adapter->psl_timebase_synced = false;
@@ -689,20 +686,6 @@ static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
	cxl_p1_write(adapter, CXL_PSL_Control, 0x0000000000000000);
	cxl_p1_write(adapter, CXL_PSL_Control, 0x0000000000000000);
	cxl_p1_write(adapter, CXL_PSL_Control, CXL_PSL_Control_tb);
	cxl_p1_write(adapter, CXL_PSL_Control, CXL_PSL_Control_tb);


	/* Wait until CORE TB and PSL TB difference <= 16usecs */
	do {
		msleep(1);
		if (retry++ > 5) {
			dev_info(&dev->dev, "PSL timebase can't synchronize\n");
			return;
		}
		psl_tb = adapter->native->sl_ops->timebase_read(adapter);
		delta = mftb() - psl_tb;
		if (delta < 0)
			delta = -delta;
	} while (tb_to_ns(delta) > 16000);

	adapter->psl_timebase_synced = true;
	return;
	return;
}
}


+12 −0
Original line number Original line Diff line number Diff line
@@ -62,7 +62,19 @@ static ssize_t psl_timebase_synced_show(struct device *device,
					char *buf)
					char *buf)
{
{
	struct cxl *adapter = to_cxl_adapter(device);
	struct cxl *adapter = to_cxl_adapter(device);
	u64 psl_tb, delta;


	/* Recompute the status only in native mode */
	if (cpu_has_feature(CPU_FTR_HVMODE)) {
		psl_tb = adapter->native->sl_ops->timebase_read(adapter);
		delta = abs(mftb() - psl_tb);

		/* CORE TB and PSL TB difference <= 16usecs ? */
		adapter->psl_timebase_synced = (tb_to_ns(delta) < 16000) ? true : false;
		pr_devel("PSL timebase %s - delta: 0x%016llx\n",
			 (tb_to_ns(delta) < 16000) ? "synchronized" :
			 "not synchronized", tb_to_ns(delta));
	}
	return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced);
	return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced);
}
}