Commit 3624a227 authored by Li Ming's avatar Li Ming Committed by Dave Jiang
Browse files

cxl/hdm: Add support for 32 switch decoders



Per CXL r4.0 section 8.2.4.20.1. CXL host bridge and switch ports can
support 32 HDM decoders. Current implementation misses some decoders on
CXL host bridge and switch in the case that the value of Decoder Count
field in CXL HDM decoder Capability Register is greater than or equal to
9.

Update calculation implementation to ensure the decoder count calculation
is correct for CXL host bridge/switch ports.

Signed-off-by: default avatarLi Ming <ming.li@zohomail.com>
Reviewed-by: default avatarGregory Price <gourry@gourry.net>
Reviewed-by: default avatarDave Jiang <dave.jiang@intel.com>
Reviewed-by: default avatarAlison Schofield <alison.schofield@intel.com>
Link: https://patch.msgid.link/20260321061459.1910205-1-ming.li@zohomail.com


Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
parent 9b6e1ed2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ static struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
	}

	parse_hdm_decoder_caps(cxlhdm);
	if (cxlhdm->decoder_count == 0) {
	if (cxlhdm->decoder_count < 0) {
		dev_err(dev, "Spec violation. Caps invalid\n");
		return ERR_PTR(-ENXIO);
	}
+10 −1
Original line number Diff line number Diff line
@@ -77,7 +77,16 @@ static inline int cxl_hdm_decoder_count(u32 cap_hdr)
{
	int val = FIELD_GET(CXL_HDM_DECODER_COUNT_MASK, cap_hdr);

	return val ? val * 2 : 1;
	switch (val) {
	case 0:
		return 1;
	case 1 ... 8:
		return val * 2;
	case 9 ... 12:
		return (val - 4) * 4;
	default:
		return -ENXIO;
	}
}

/* Encode defined in CXL 2.0 8.2.5.12.7 HDM Decoder Control Register */
+1 −1
Original line number Diff line number Diff line
@@ -923,7 +923,7 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd);
 */
struct cxl_hdm {
	struct cxl_component_regs regs;
	unsigned int decoder_count;
	int decoder_count;
	unsigned int target_count;
	unsigned int interleave_mask;
	unsigned long iw_cap_mask;