summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Ming <ming.li@zohomail.com>2026-03-21 09:14:59 +0300
committerDave Jiang <dave.jiang@intel.com>2026-04-10 18:32:14 +0300
commit3624a22783b74ffebaa7d9f286e203604baa06c7 (patch)
tree47dd3c8a65b93196fe2db48168f8bcf01d356246
parent9b6e1ed28a7f239cc9184101cedc6fec4c3b3dc9 (diff)
downloadlinux-3624a22783b74ffebaa7d9f286e203604baa06c7.tar.xz
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: Li Ming <ming.li@zohomail.com> Reviewed-by: Gregory Price <gourry@gourry.net> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Link: https://patch.msgid.link/20260321061459.1910205-1-ming.li@zohomail.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
-rw-r--r--drivers/cxl/core/hdm.c2
-rw-r--r--drivers/cxl/cxl.h11
-rw-r--r--drivers/cxl/cxlmem.h2
3 files changed, 12 insertions, 3 deletions
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index c222e98ae736..3930e130d6b6 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -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);
}
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index d09c84bcc015..4e7923811f94 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -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 */
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index e21d744d639b..399b150b404c 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -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;