]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cxl/hdm: Add support for 32 switch decoders
authorLi Ming <ming.li@zohomail.com>
Sat, 21 Mar 2026 06:14:59 +0000 (14:14 +0800)
committerDave Jiang <dave.jiang@intel.com>
Fri, 10 Apr 2026 15:32:14 +0000 (08:32 -0700)
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>
drivers/cxl/core/hdm.c
drivers/cxl/cxl.h
drivers/cxl/cxlmem.h

index c222e98ae7364cb54bc6d40237e121003d9776ee..3930e130d6b6a6a6aef432ca4052b17d14f01000 100644 (file)
@@ -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);
        }
index d09c84bcc0150c491dc3d02b9d6247682f911426..4e7923811f94bcbb709bc8731468da4ac7268453 100644 (file)
@@ -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 */
index e21d744d639bd26c6e87f756a8f051dfea86d4eb..399b150b404cef807f9c383de1c00a0df0980c81 100644 (file)
@@ -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;