Skip to content

Commit 1acba6e

Browse files
davejiangdjbw
authored andcommitted
cxl/pci: Break out range register decoding from cxl_hdm_decode_init()
There are 2 scenarios that requires additional handling. 1. A device that has active ranges in DVSEC range registers (RR) but no HDM decoder register block. 2. A device that has both RR active and HDM, but the HDM decoders are not programmed. The goal is to create emulated decoder software structs based on the RR. Move the CXL DVSEC range register decoding code block from cxl_hdm_decode_init() to its own function. Refactor code in preparation for the HDM decoder emulation. There is no functionality change to the code. Name the new function to cxl_dvsec_rr_decode(). The only change is to set range->start and range->end to CXL_RESOURCE_NONE and skipping the reading of base registers if the range size is 0, which equates to range not active. Reviewed-by: Jonathan Cameron <[email protected]> Signed-off-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/167640366839.935665.11816388524993234329.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <[email protected]>
1 parent 6d796c5 commit 1acba6e

File tree

1 file changed

+40
-24
lines changed

1 file changed

+40
-24
lines changed

drivers/cxl/core/pci.c

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,10 @@ int cxl_await_media_ready(struct cxl_dev_state *cxlds)
141141
}
142142
EXPORT_SYMBOL_NS_GPL(cxl_await_media_ready, CXL);
143143

144-
static int wait_for_valid(struct cxl_dev_state *cxlds)
144+
static int wait_for_valid(struct pci_dev *pdev, int d)
145145
{
146-
struct pci_dev *pdev = to_pci_dev(cxlds->dev);
147-
int d = cxlds->cxl_dvsec, rc;
148146
u32 val;
147+
int rc;
149148

150149
/*
151150
* Memory_Info_Valid: When set, indicates that the CXL Range 1 Size high
@@ -334,20 +333,11 @@ static bool __cxl_hdm_decode_init(struct cxl_dev_state *cxlds,
334333
return true;
335334
}
336335

337-
/**
338-
* cxl_hdm_decode_init() - Setup HDM decoding for the endpoint
339-
* @cxlds: Device state
340-
* @cxlhdm: Mapped HDM decoder Capability
341-
*
342-
* Try to enable the endpoint's HDM Decoder Capability
343-
*/
344-
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm)
336+
static int cxl_dvsec_rr_decode(struct device *dev, int d,
337+
struct cxl_endpoint_dvsec_info *info)
345338
{
346-
struct pci_dev *pdev = to_pci_dev(cxlds->dev);
347-
struct cxl_endpoint_dvsec_info info = { 0 };
339+
struct pci_dev *pdev = to_pci_dev(dev);
348340
int hdm_count, rc, i, ranges = 0;
349-
struct device *dev = &pdev->dev;
350-
int d = cxlds->cxl_dvsec;
351341
u16 cap, ctrl;
352342

353343
if (!d) {
@@ -378,7 +368,7 @@ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm)
378368
if (!hdm_count || hdm_count > 2)
379369
return -EINVAL;
380370

381-
rc = wait_for_valid(cxlds);
371+
rc = wait_for_valid(pdev, d);
382372
if (rc) {
383373
dev_dbg(dev, "Failure awaiting MEM_INFO_VALID (%d)\n", rc);
384374
return rc;
@@ -389,9 +379,9 @@ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm)
389379
* disabled, and they will remain moot after the HDM Decoder
390380
* capability is enabled.
391381
*/
392-
info.mem_enabled = FIELD_GET(CXL_DVSEC_MEM_ENABLE, ctrl);
393-
if (!info.mem_enabled)
394-
goto hdm_init;
382+
info->mem_enabled = FIELD_GET(CXL_DVSEC_MEM_ENABLE, ctrl);
383+
if (!info->mem_enabled)
384+
return 0;
395385

396386
for (i = 0; i < hdm_count; i++) {
397387
u64 base, size;
@@ -410,6 +400,13 @@ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm)
410400
return rc;
411401

412402
size |= temp & CXL_DVSEC_MEM_SIZE_LOW_MASK;
403+
if (!size) {
404+
info->dvsec_range[i] = (struct range) {
405+
.start = 0,
406+
.end = CXL_RESOURCE_NONE,
407+
};
408+
continue;
409+
}
413410

414411
rc = pci_read_config_dword(
415412
pdev, d + CXL_DVSEC_RANGE_BASE_HIGH(i), &temp);
@@ -425,22 +422,41 @@ int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm)
425422

426423
base |= temp & CXL_DVSEC_MEM_BASE_LOW_MASK;
427424

428-
info.dvsec_range[i] = (struct range) {
425+
info->dvsec_range[i] = (struct range) {
429426
.start = base,
430427
.end = base + size - 1
431428
};
432429

433-
if (size)
434-
ranges++;
430+
ranges++;
435431
}
436432

437-
info.ranges = ranges;
433+
info->ranges = ranges;
434+
435+
return 0;
436+
}
437+
438+
/**
439+
* cxl_hdm_decode_init() - Setup HDM decoding for the endpoint
440+
* @cxlds: Device state
441+
* @cxlhdm: Mapped HDM decoder Capability
442+
*
443+
* Try to enable the endpoint's HDM Decoder Capability
444+
*/
445+
int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm)
446+
{
447+
struct cxl_endpoint_dvsec_info info = { 0 };
448+
struct device *dev = cxlds->dev;
449+
int d = cxlds->cxl_dvsec;
450+
int rc;
451+
452+
rc = cxl_dvsec_rr_decode(dev, d, &info);
453+
if (rc < 0)
454+
return rc;
438455

439456
/*
440457
* If DVSEC ranges are being used instead of HDM decoder registers there
441458
* is no use in trying to manage those.
442459
*/
443-
hdm_init:
444460
if (!__cxl_hdm_decode_init(cxlds, cxlhdm, &info)) {
445461
dev_err(dev,
446462
"Legacy range registers configuration prevents HDM operation.\n");

0 commit comments

Comments
 (0)