Skip to content

Commit

Permalink
cxl/hdm: Add emulation when HDM decoders are not committed
Browse files Browse the repository at this point in the history
For the case where DVSEC range register(s) are active and HDM decoders are
not committed, use RR to provide emulation. A first pass is done to note
whether any decoders are committed. If there are no committed endpoint
decoders, then DVSEC ranges will be used for emulation.

Reviewed-by: Jonathan Cameron <[email protected]>
Signed-off-by: Dave Jiang <[email protected]>
Link: https://lore.kernel.org/r/167640369536.935665.611974113442400127.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Dan Williams <[email protected]>
  • Loading branch information
davejiang authored and djbw committed Feb 14, 2023
1 parent 4474ce5 commit d7a2153
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions drivers/cxl/core/hdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,32 @@ static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port,
return 0;
}

static bool should_emulate_decoders(struct cxl_port *port)
{
struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
void __iomem *hdm = cxlhdm->regs.hdm_decoder;
u32 ctrl;
int i;

if (!is_cxl_endpoint(cxlhdm->port))
return false;

if (!hdm)
return true;

/*
* If any decoders are committed already, there should not be any
* emulated DVSEC decoders.
*/
for (i = 0; i < cxlhdm->decoder_count; i++) {
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
return false;
}

return true;
}

static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
int *target_map, void __iomem *hdm, int which,
u64 *dpa_base, struct cxl_endpoint_dvsec_info *info)
Expand All @@ -745,6 +771,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
unsigned char target_id[8];
} target_list;

if (should_emulate_decoders(port))
return cxl_setup_hdm_decoder_from_dvsec(port, cxld, which, info);

if (is_endpoint_decoder(&cxld->dev))
cxled = to_cxl_endpoint_decoder(&cxld->dev);

Expand Down

0 comments on commit d7a2153

Please sign in to comment.