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

Commit 94322ed8 authored by Vaibhav Jain's avatar Vaibhav Jain Committed by Michael Ellerman
Browse files

cxl: Check if PSL data-cache is available before issue flush request



PSL9D doesn't have a data-cache that needs to be flushed before
resetting the card. However when cxl tries to flush data-cache on such
a card, it times-out as PSL_Control register never indicates flush
operation complete due to missing data-cache. This is usually
indicated in the kernel logs with this message:

"WARNING: cache flush timed out"

To fix this the patch checks PSL_Debug register CDC-Field(BIT:27)
which indicates the absence of a data-cache and sets a flag
'no_data_cache' in 'struct cxl_native' to indicate this. When
cxl_data_cache_flush() is called it checks the flag and if set bails
out early without requesting a data-cache flush operation to the PSL.

Signed-off-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 02b63b42
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -369,6 +369,9 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0};
#define CXL_PSL_TFC_An_AE (1ull << (63-30)) /* Restart PSL with address error */
#define CXL_PSL_TFC_An_R  (1ull << (63-31)) /* Restart PSL transaction */

/****** CXL_PSL_DEBUG *****************************************************/
#define CXL_PSL_DEBUG_CDC  (1ull << (63-27)) /* Coherent Data cache support */

/****** CXL_XSL9_IERAT_ERAT - CAIA 2 **********************************/
#define CXL_XSL9_IERAT_MLPID    (1ull << (63-0))  /* Match LPID */
#define CXL_XSL9_IERAT_MPID     (1ull << (63-1))  /* Match PID */
@@ -669,6 +672,7 @@ struct cxl_native {
	irq_hw_number_t err_hwirq;
	unsigned int err_virq;
	u64 ps_off;
	bool no_data_cache; /* set if no data cache on the card */
	const struct cxl_service_layer_ops *sl_ops;
};

+10 −1
Original line number Diff line number Diff line
@@ -353,8 +353,17 @@ int cxl_data_cache_flush(struct cxl *adapter)
	u64 reg;
	unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);

	pr_devel("Flushing data cache\n");
	/*
	 * Do a datacache flush only if datacache is available.
	 * In case of PSL9D datacache absent hence flush operation.
	 * would timeout.
	 */
	if (adapter->native->no_data_cache) {
		pr_devel("No PSL data cache. Ignoring cache flush req.\n");
		return 0;
	}

	pr_devel("Flushing data cache\n");
	reg = cxl_p1_read(adapter, CXL_PSL_Control);
	reg |= CXL_PSL_Control_Fr;
	cxl_p1_write(adapter, CXL_PSL_Control, reg);
+13 −6
Original line number Diff line number Diff line
@@ -456,6 +456,7 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter,
	u64 chipid;
	u32 phb_index;
	u64 capp_unit_id;
	u64 psl_debug;
	int rc;

	rc = cxl_calc_capp_routing(dev, &chipid, &phb_index, &capp_unit_id);
@@ -510,6 +511,16 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter,
		cxl_p1_write(adapter, CXL_PSL9_DEBUG, 0xC000000000000000ULL);
	}

	/*
	 * Check if PSL has data-cache. We need to flush adapter datacache
	 * when as its about to be removed.
	 */
	psl_debug = cxl_p1_read(adapter, CXL_PSL9_DEBUG);
	if (psl_debug & CXL_PSL_DEBUG_CDC) {
		dev_dbg(&dev->dev, "No data-cache present\n");
		adapter->native->no_data_cache = true;
	}

	return 0;
}

@@ -1448,9 +1459,7 @@ int cxl_pci_reset(struct cxl *adapter)

	/*
	 * The adapter is about to be reset, so ignore errors.
	 * Not supported on P9 DD1
	 */
	if ((cxl_is_power8()) || (!(cxl_is_power9_dd1())))
	cxl_data_cache_flush(adapter);

	/* pcie_warm_reset requests a fundamental pci reset which includes a
@@ -1934,9 +1943,7 @@ static void cxl_pci_remove_adapter(struct cxl *adapter)

	/*
	 * Flush adapter datacache as its about to be removed.
	 * Not supported on P9 DD1.
	 */
	if ((cxl_is_power8()) || (!(cxl_is_power9_dd1())))
	cxl_data_cache_flush(adapter);

	cxl_deconfigure_adapter(adapter);