Message ID | 168679261945.3436160.11673393474107374595.stgit@dwillia2-xfh.jf.intel.com |
---|---|
State | Accepted |
Commit | cecbb5da921231aa0933667fba85bea5b91d6a46 |
Headers | show |
Series | Device memory prep | expand |
On 6/14/23 18:30, Dan Williams wrote: > In preparation for device-memory region creation, arrange for decoders > of CXL_DEVTYPE_DEVMEM memdevs to default to CXL_DECODER_DEVMEM for their > target type. > > Revisit this if a device ever shows up that wants to offer mixed HDM-H > (Host-Only Memory) and HDM-DB support, or an CXL_DEVTYPE_DEVMEM device > that supports HDM-H. > > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > Signed-off-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> > --- > drivers/cxl/core/hdm.c | 35 ++++++++++++++++++++++++++--------- > drivers/cxl/cxl.h | 2 +- > 2 files changed, 27 insertions(+), 10 deletions(-) > > diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c > index 79170de13d89..715c1f103739 100644 > --- a/drivers/cxl/core/hdm.c > +++ b/drivers/cxl/core/hdm.c > @@ -572,7 +572,7 @@ static void cxld_set_type(struct cxl_decoder *cxld, u32 *ctrl) > { > u32p_replace_bits(ctrl, > !!(cxld->target_type == CXL_DECODER_HOSTONLYMEM), > - CXL_HDM_DECODER0_CTRL_TYPE); > + CXL_HDM_DECODER0_CTRL_HOSTONLY); > } > > static int cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt) > @@ -794,8 +794,8 @@ 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) > { > + struct cxl_endpoint_decoder *cxled = NULL; > u64 size, base, skip, dpa_size, lo, hi; > - struct cxl_endpoint_decoder *cxled; > bool committed; > u32 remainder; > int i, rc; > @@ -828,6 +828,8 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, > return -ENXIO; > } > > + if (info) > + cxled = to_cxl_endpoint_decoder(&cxld->dev); > cxld->hpa_range = (struct range) { > .start = base, > .end = base + size - 1, > @@ -838,7 +840,7 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, > cxld->flags |= CXL_DECODER_F_ENABLE; > if (ctrl & CXL_HDM_DECODER0_CTRL_LOCK) > cxld->flags |= CXL_DECODER_F_LOCK; > - if (FIELD_GET(CXL_HDM_DECODER0_CTRL_TYPE, ctrl)) > + if (FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl)) > cxld->target_type = CXL_DECODER_HOSTONLYMEM; > else > cxld->target_type = CXL_DECODER_DEVMEM; > @@ -857,12 +859,28 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, > } > port->commit_end = cxld->id; > } else { > - /* unless / until type-2 drivers arrive, assume type-3 */ > - if (FIELD_GET(CXL_HDM_DECODER0_CTRL_TYPE, ctrl) == 0) { > - ctrl |= CXL_HDM_DECODER0_CTRL_TYPE; > + if (cxled) { > + struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); > + struct cxl_dev_state *cxlds = cxlmd->cxlds; > + > + /* > + * Default by devtype until a device arrives that needs > + * more precision. > + */ > + if (cxlds->type == CXL_DEVTYPE_CLASSMEM) > + cxld->target_type = CXL_DECODER_HOSTONLYMEM; > + else > + cxld->target_type = CXL_DECODER_DEVMEM; > + } else { > + /* To be overridden by region type at commit time */ > + cxld->target_type = CXL_DECODER_HOSTONLYMEM; > + } > + > + if (!FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl) && > + cxld->target_type == CXL_DECODER_HOSTONLYMEM) { > + ctrl |= CXL_HDM_DECODER0_CTRL_HOSTONLY; > writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which)); > } > - cxld->target_type = CXL_DECODER_HOSTONLYMEM; > } > rc = eiw_to_ways(FIELD_GET(CXL_HDM_DECODER0_CTRL_IW_MASK, ctrl), > &cxld->interleave_ways); > @@ -881,7 +899,7 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, > port->id, cxld->id, cxld->hpa_range.start, cxld->hpa_range.end, > cxld->interleave_ways, cxld->interleave_granularity); > > - if (!info) { > + if (!cxled) { > lo = readl(hdm + CXL_HDM_DECODER0_TL_LOW(which)); > hi = readl(hdm + CXL_HDM_DECODER0_TL_HIGH(which)); > target_list.value = (hi << 32) + lo; > @@ -904,7 +922,6 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, > lo = readl(hdm + CXL_HDM_DECODER0_SKIP_LOW(which)); > hi = readl(hdm + CXL_HDM_DECODER0_SKIP_HIGH(which)); > skip = (hi << 32) + lo; > - cxled = to_cxl_endpoint_decoder(&cxld->dev); > rc = devm_cxl_dpa_reserve(cxled, *dpa_base + skip, dpa_size, skip); > if (rc) { > dev_err(&port->dev, > diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h > index ae0965ac8c5a..f309b1387858 100644 > --- a/drivers/cxl/cxl.h > +++ b/drivers/cxl/cxl.h > @@ -56,7 +56,7 @@ > #define CXL_HDM_DECODER0_CTRL_COMMIT BIT(9) > #define CXL_HDM_DECODER0_CTRL_COMMITTED BIT(10) > #define CXL_HDM_DECODER0_CTRL_COMMIT_ERROR BIT(11) > -#define CXL_HDM_DECODER0_CTRL_TYPE BIT(12) > +#define CXL_HDM_DECODER0_CTRL_HOSTONLY BIT(12) > #define CXL_HDM_DECODER0_TL_LOW(i) (0x20 * (i) + 0x24) > #define CXL_HDM_DECODER0_TL_HIGH(i) (0x20 * (i) + 0x28) > #define CXL_HDM_DECODER0_SKIP_LOW(i) CXL_HDM_DECODER0_TL_LOW(i) >
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index 79170de13d89..715c1f103739 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -572,7 +572,7 @@ static void cxld_set_type(struct cxl_decoder *cxld, u32 *ctrl) { u32p_replace_bits(ctrl, !!(cxld->target_type == CXL_DECODER_HOSTONLYMEM), - CXL_HDM_DECODER0_CTRL_TYPE); + CXL_HDM_DECODER0_CTRL_HOSTONLY); } static int cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt) @@ -794,8 +794,8 @@ 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) { + struct cxl_endpoint_decoder *cxled = NULL; u64 size, base, skip, dpa_size, lo, hi; - struct cxl_endpoint_decoder *cxled; bool committed; u32 remainder; int i, rc; @@ -828,6 +828,8 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, return -ENXIO; } + if (info) + cxled = to_cxl_endpoint_decoder(&cxld->dev); cxld->hpa_range = (struct range) { .start = base, .end = base + size - 1, @@ -838,7 +840,7 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, cxld->flags |= CXL_DECODER_F_ENABLE; if (ctrl & CXL_HDM_DECODER0_CTRL_LOCK) cxld->flags |= CXL_DECODER_F_LOCK; - if (FIELD_GET(CXL_HDM_DECODER0_CTRL_TYPE, ctrl)) + if (FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl)) cxld->target_type = CXL_DECODER_HOSTONLYMEM; else cxld->target_type = CXL_DECODER_DEVMEM; @@ -857,12 +859,28 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, } port->commit_end = cxld->id; } else { - /* unless / until type-2 drivers arrive, assume type-3 */ - if (FIELD_GET(CXL_HDM_DECODER0_CTRL_TYPE, ctrl) == 0) { - ctrl |= CXL_HDM_DECODER0_CTRL_TYPE; + if (cxled) { + struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); + struct cxl_dev_state *cxlds = cxlmd->cxlds; + + /* + * Default by devtype until a device arrives that needs + * more precision. + */ + if (cxlds->type == CXL_DEVTYPE_CLASSMEM) + cxld->target_type = CXL_DECODER_HOSTONLYMEM; + else + cxld->target_type = CXL_DECODER_DEVMEM; + } else { + /* To be overridden by region type at commit time */ + cxld->target_type = CXL_DECODER_HOSTONLYMEM; + } + + if (!FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl) && + cxld->target_type == CXL_DECODER_HOSTONLYMEM) { + ctrl |= CXL_HDM_DECODER0_CTRL_HOSTONLY; writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which)); } - cxld->target_type = CXL_DECODER_HOSTONLYMEM; } rc = eiw_to_ways(FIELD_GET(CXL_HDM_DECODER0_CTRL_IW_MASK, ctrl), &cxld->interleave_ways); @@ -881,7 +899,7 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, port->id, cxld->id, cxld->hpa_range.start, cxld->hpa_range.end, cxld->interleave_ways, cxld->interleave_granularity); - if (!info) { + if (!cxled) { lo = readl(hdm + CXL_HDM_DECODER0_TL_LOW(which)); hi = readl(hdm + CXL_HDM_DECODER0_TL_HIGH(which)); target_list.value = (hi << 32) + lo; @@ -904,7 +922,6 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, lo = readl(hdm + CXL_HDM_DECODER0_SKIP_LOW(which)); hi = readl(hdm + CXL_HDM_DECODER0_SKIP_HIGH(which)); skip = (hi << 32) + lo; - cxled = to_cxl_endpoint_decoder(&cxld->dev); rc = devm_cxl_dpa_reserve(cxled, *dpa_base + skip, dpa_size, skip); if (rc) { dev_err(&port->dev, diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index ae0965ac8c5a..f309b1387858 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -56,7 +56,7 @@ #define CXL_HDM_DECODER0_CTRL_COMMIT BIT(9) #define CXL_HDM_DECODER0_CTRL_COMMITTED BIT(10) #define CXL_HDM_DECODER0_CTRL_COMMIT_ERROR BIT(11) -#define CXL_HDM_DECODER0_CTRL_TYPE BIT(12) +#define CXL_HDM_DECODER0_CTRL_HOSTONLY BIT(12) #define CXL_HDM_DECODER0_TL_LOW(i) (0x20 * (i) + 0x24) #define CXL_HDM_DECODER0_TL_HIGH(i) (0x20 * (i) + 0x28) #define CXL_HDM_DECODER0_SKIP_LOW(i) CXL_HDM_DECODER0_TL_LOW(i)