[PATCH v2 04/15] cxl/region: Calculate endpoint's region position during init

Robert Richter
2025-02-18T13:24:49Z

The calculation of an endpoint's position in a region traverses all
ports up to the root port and determines the corresponding decoders
for that particular address range. For address translation the HPA
range must be recalculated between ports. In order to prepare the
implementation of address translation, move code to
cxl_endpoint_decoder_initialize() and reuse the existing iterator
there.

Signed-off-by: Robert Richter <rrichter@amd.com>
---
drivers/cxl/core/region.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index ad4a6ce37216..6f106bfa115f 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -1903,7 +1903,6 @@ static int cxl_region_sort_targets(struct cxl_region *cxlr)
for (i = 0; i < p->nr_targets; i++) {
struct cxl_endpoint_decoder *cxled = p->targets[i];

- cxled->pos = cxl_calc_interleave_pos(cxled);
/*
* Record that sorting failed, but still continue to calc
* cxled->pos so that follow-on code paths can reliably
@@ -3264,10 +3263,22 @@ static int cxl_endpoint_decoder_initialize(struct cxl_endpoint_decoder *cxled)
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
struct cxl_port *iter = cxled_to_port(cxled);
struct cxl_decoder *root, *cxld = &cxled->cxld;
- struct range *hpa = &cxld->hpa_range;
+ struct range hpa = cxld->hpa_range;
+ struct cxl_interleave_context ctx;
+ int rc;

- while (iter && !is_cxl_root(iter))
- iter = to_cxl_port(iter->dev.parent);
+ ctx = (struct cxl_interleave_context) {
+ .hpa_range = &hpa,
+ };
+
+ while (iter && !is_cxl_root(iter)) {
+ /* Convert interleave settings to next port upstream. */
+ rc = cxl_port_calc_interleave(iter, &ctx);
+ if (rc < 0)
+ return rc;
+
+ iter = parent_port_of(iter);
+ }

if (!iter)
return -ENXIO;
@@ -3281,7 +3292,13 @@ static int cxl_endpoint_decoder_initialize(struct cxl_endpoint_decoder *cxled)
return -ENXIO;
}

+ dev_dbg(cxld->dev.parent,
+ "%s:%s: range:%#llx-%#llx pos:%d\n",
+ dev_name(&cxled->cxld.dev), dev_name(&cxld->dev),
+ hpa.start, hpa.end, ctx.pos);
+
cxled->cxlrd = to_cxl_root_decoder(&root->dev);
+ cxled->pos = ctx.pos;

return 0;
}
--
2.39.5