Skip to content

Commit 8ce520f

Browse files
Robert Richterdjbw
authored andcommitted
cxl/hdm: Use stored Component Register mappings to map HDM decoder capability
Now, that the Component Register mappings are stored, use them to enable and map the HDM decoder capabilities. The Component Registers do not need to be probed again for this, remove probing code. The HDM capability applies to Endpoints, USPs and VH Host Bridges. The Endpoint's component register mappings are located in the cxlds and else in the port's structure. Duplicate the cxlds->reg_map in port->reg_map for endpoint ports. Signed-off-by: Terry Bowman <terry.bowman@amd.com> Signed-off-by: Robert Richter <rrichter@amd.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> [rework to drop cxl_port_get_comp_map()] Link: https://lore.kernel.org/r/20231018171713.1883517-8-rrichter@amd.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 2dd1827 commit 8ce520f

File tree

3 files changed

+43
-39
lines changed

3 files changed

+43
-39
lines changed

drivers/cxl/core/hdm.c

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -81,26 +81,6 @@ static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm)
8181
cxlhdm->interleave_mask |= GENMASK(14, 12);
8282
}
8383

84-
static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb,
85-
struct cxl_component_regs *regs)
86-
{
87-
struct cxl_register_map map = {
88-
.host = &port->dev,
89-
.resource = port->component_reg_phys,
90-
.base = crb,
91-
.max_size = CXL_COMPONENT_REG_BLOCK_SIZE,
92-
};
93-
94-
cxl_probe_component_regs(&port->dev, crb, &map.component_map);
95-
if (!map.component_map.hdm_decoder.valid) {
96-
dev_dbg(&port->dev, "HDM decoder registers not implemented\n");
97-
/* unique error code to indicate no HDM decoder capability */
98-
return -ENODEV;
99-
}
100-
101-
return cxl_map_component_regs(&map, regs, BIT(CXL_CM_CAP_CAP_ID_HDM));
102-
}
103-
10484
static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
10585
{
10686
struct cxl_hdm *cxlhdm;
@@ -153,9 +133,9 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
153133
struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
154134
struct cxl_endpoint_dvsec_info *info)
155135
{
136+
struct cxl_register_map *reg_map = &port->reg_map;
156137
struct device *dev = &port->dev;
157138
struct cxl_hdm *cxlhdm;
158-
void __iomem *crb;
159139
int rc;
160140

161141
cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL);
@@ -164,19 +144,29 @@ struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
164144
cxlhdm->port = port;
165145
dev_set_drvdata(dev, cxlhdm);
166146

167-
crb = ioremap(port->component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE);
168-
if (!crb && info && info->mem_enabled) {
147+
/* Memory devices can configure device HDM using DVSEC range regs. */
148+
if (reg_map->resource == CXL_RESOURCE_NONE) {
149+
if (!info && !info->mem_enabled) {
150+
dev_err(dev, "No component registers mapped\n");
151+
return ERR_PTR(-ENXIO);
152+
}
153+
169154
cxlhdm->decoder_count = info->ranges;
170155
return cxlhdm;
171-
} else if (!crb) {
172-
dev_err(dev, "No component registers mapped\n");
173-
return ERR_PTR(-ENXIO);
174156
}
175157

176-
rc = map_hdm_decoder_regs(port, crb, &cxlhdm->regs);
177-
iounmap(crb);
178-
if (rc)
158+
if (!reg_map->component_map.hdm_decoder.valid) {
159+
dev_dbg(&port->dev, "HDM decoder registers not implemented\n");
160+
/* unique error code to indicate no HDM decoder capability */
161+
return ERR_PTR(-ENODEV);
162+
}
163+
164+
rc = cxl_map_component_regs(reg_map, &cxlhdm->regs,
165+
BIT(CXL_CM_CAP_CAP_ID_HDM));
166+
if (rc) {
167+
dev_err(dev, "Failed to map HDM capability.\n");
179168
return ERR_PTR(rc);
169+
}
180170

181171
parse_hdm_decoder_caps(cxlhdm);
182172
if (cxlhdm->decoder_count == 0) {

drivers/cxl/core/port.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -751,16 +751,31 @@ static struct cxl_port *__devm_cxl_add_port(struct device *host,
751751
return port;
752752

753753
dev = &port->dev;
754-
if (is_cxl_memdev(uport_dev))
754+
if (is_cxl_memdev(uport_dev)) {
755+
struct cxl_memdev *cxlmd = to_cxl_memdev(uport_dev);
756+
struct cxl_dev_state *cxlds = cxlmd->cxlds;
757+
755758
rc = dev_set_name(dev, "endpoint%d", port->id);
756-
else if (parent_dport)
759+
if (rc)
760+
goto err;
761+
762+
/*
763+
* The endpoint driver already enumerated the component and RAS
764+
* registers. Reuse that enumeration while prepping them to be
765+
* mapped by the cxl_port driver.
766+
*/
767+
port->reg_map = cxlds->reg_map;
768+
port->reg_map.host = &port->dev;
769+
} else if (parent_dport) {
757770
rc = dev_set_name(dev, "port%d", port->id);
758-
else
759-
rc = dev_set_name(dev, "root%d", port->id);
760-
if (rc)
761-
goto err;
771+
if (rc)
772+
goto err;
762773

763-
rc = cxl_port_setup_regs(port, component_reg_phys);
774+
rc = cxl_port_setup_regs(port, component_reg_phys);
775+
if (rc)
776+
goto err;
777+
} else
778+
rc = dev_set_name(dev, "root%d", port->id);
764779
if (rc)
765780
goto err;
766781

drivers/cxl/mem.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ static int devm_cxl_add_endpoint(struct device *host, struct cxl_memdev *cxlmd,
4949
struct cxl_dport *parent_dport)
5050
{
5151
struct cxl_port *parent_port = parent_dport->port;
52-
struct cxl_dev_state *cxlds = cxlmd->cxlds;
5352
struct cxl_port *endpoint, *iter, *down;
5453
int rc;
5554

@@ -65,8 +64,8 @@ static int devm_cxl_add_endpoint(struct device *host, struct cxl_memdev *cxlmd,
6564
ep->next = down;
6665
}
6766

68-
endpoint = devm_cxl_add_port(host, &cxlmd->dev,
69-
cxlds->component_reg_phys,
67+
/* Note: endpoint port component registers are derived from @cxlds */
68+
endpoint = devm_cxl_add_port(host, &cxlmd->dev, CXL_RESOURCE_NONE,
7069
parent_dport);
7170
if (IS_ERR(endpoint))
7271
return PTR_ERR(endpoint);

0 commit comments

Comments
 (0)