Message ID | 167330064247.975161.16867413974628215063.stgit@djiang5-mobl3.local |
---|---|
State | Superseded |
Headers | show |
Series | cxl: Introduce HDM decoder emulation from DVSEC range registers | expand |
On Mon, 09 Jan 2023 14:44:03 -0700 Dave Jiang <dave.jiang@intel.com> wrote: > 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. > > Signed-off-by: Dave Jiang <dave.jiang@intel.com> Hi Dave One trivial suggestion inline. With that tidied up Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > --- > drivers/cxl/core/hdm.c | 39 ++++++++++++++++++++++++++++++++------- > drivers/cxl/cxl.h | 1 + > 2 files changed, 33 insertions(+), 7 deletions(-) > > diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c > index ed5e9ef3aa9b..40844ff2fe52 100644 > --- a/drivers/cxl/core/hdm.c > +++ b/drivers/cxl/core/hdm.c > @@ -729,6 +729,33 @@ static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port, > return 0; > } > > +static bool should_emulate_decoders(struct cxl_hdm *cxlhdm) > +{ > + void __iomem *hdm = cxlhdm->regs.hdm_decoder; > + bool committed; > + 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)); > + committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED); FIELD_GET() is nicer than !! I think. Also, local variable isn't useful so I'd get rid of it. if (FIELD_GET(ctrl, CXL_HDM_DECODER0_CTRL_COMMITTED)) return false; > + if (committed) > + return false; > + } > + > + return true; > +} > + >
On 1/13/23 7:07 AM, Jonathan Cameron wrote: > On Mon, 09 Jan 2023 14:44:03 -0700 > Dave Jiang <dave.jiang@intel.com> wrote: > >> 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. >> >> Signed-off-by: Dave Jiang <dave.jiang@intel.com> > Hi Dave > > One trivial suggestion inline. With that tidied up > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > >> --- >> drivers/cxl/core/hdm.c | 39 ++++++++++++++++++++++++++++++++------- >> drivers/cxl/cxl.h | 1 + >> 2 files changed, 33 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c >> index ed5e9ef3aa9b..40844ff2fe52 100644 >> --- a/drivers/cxl/core/hdm.c >> +++ b/drivers/cxl/core/hdm.c >> @@ -729,6 +729,33 @@ static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port, >> return 0; >> } >> >> +static bool should_emulate_decoders(struct cxl_hdm *cxlhdm) >> +{ >> + void __iomem *hdm = cxlhdm->regs.hdm_decoder; >> + bool committed; >> + 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)); >> + committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED); > > FIELD_GET() is nicer than !! I think. > > Also, local variable isn't useful so I'd get rid of it. > > if (FIELD_GET(ctrl, CXL_HDM_DECODER0_CTRL_COMMITTED)) > return false; Compiler does not seem to like single bit mask. How about if (ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED) return false; > > >> + if (committed) >> + return false; >> + } >> + >> + return true; >> +} >> + > >> >
On Tue, 17 Jan 2023 16:19:39 -0700 Dave Jiang <dave.jiang@intel.com> wrote: > On 1/13/23 7:07 AM, Jonathan Cameron wrote: > > On Mon, 09 Jan 2023 14:44:03 -0700 > > Dave Jiang <dave.jiang@intel.com> wrote: > > > >> 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. > >> > >> Signed-off-by: Dave Jiang <dave.jiang@intel.com> > > Hi Dave > > > > One trivial suggestion inline. With that tidied up > > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > > >> --- > >> drivers/cxl/core/hdm.c | 39 ++++++++++++++++++++++++++++++++------- > >> drivers/cxl/cxl.h | 1 + > >> 2 files changed, 33 insertions(+), 7 deletions(-) > >> > >> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c > >> index ed5e9ef3aa9b..40844ff2fe52 100644 > >> --- a/drivers/cxl/core/hdm.c > >> +++ b/drivers/cxl/core/hdm.c > >> @@ -729,6 +729,33 @@ static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port, > >> return 0; > >> } > >> > >> +static bool should_emulate_decoders(struct cxl_hdm *cxlhdm) > >> +{ > >> + void __iomem *hdm = cxlhdm->regs.hdm_decoder; > >> + bool committed; > >> + 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)); > >> + committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED); > > > > FIELD_GET() is nicer than !! I think. > > > > Also, local variable isn't useful so I'd get rid of it. > > > > if (FIELD_GET(ctrl, CXL_HDM_DECODER0_CTRL_COMMITTED)) > > return false; > > Compiler does not seem to like single bit mask. How about That's strange - number of bits shouldn't matter. hough I got parameters backwards above which doesn't help. FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl) > if (ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED) > return false; > > > > > >> + if (committed) > >> + return false; > >> + } > >> + > >> + return true; > >> +} > >> + > > > >> > >
On 1/18/23 3:12 AM, Jonathan Cameron wrote: > On Tue, 17 Jan 2023 16:19:39 -0700 > Dave Jiang <dave.jiang@intel.com> wrote: > >> On 1/13/23 7:07 AM, Jonathan Cameron wrote: >>> On Mon, 09 Jan 2023 14:44:03 -0700 >>> Dave Jiang <dave.jiang@intel.com> wrote: >>> >>>> 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. >>>> >>>> Signed-off-by: Dave Jiang <dave.jiang@intel.com> >>> Hi Dave >>> >>> One trivial suggestion inline. With that tidied up >>> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> >>> >>>> --- >>>> drivers/cxl/core/hdm.c | 39 ++++++++++++++++++++++++++++++++------- >>>> drivers/cxl/cxl.h | 1 + >>>> 2 files changed, 33 insertions(+), 7 deletions(-) >>>> >>>> diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c >>>> index ed5e9ef3aa9b..40844ff2fe52 100644 >>>> --- a/drivers/cxl/core/hdm.c >>>> +++ b/drivers/cxl/core/hdm.c >>>> @@ -729,6 +729,33 @@ static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port, >>>> return 0; >>>> } >>>> >>>> +static bool should_emulate_decoders(struct cxl_hdm *cxlhdm) >>>> +{ >>>> + void __iomem *hdm = cxlhdm->regs.hdm_decoder; >>>> + bool committed; >>>> + 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)); >>>> + committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED); >>> >>> FIELD_GET() is nicer than !! I think. >>> >>> Also, local variable isn't useful so I'd get rid of it. >>> >>> if (FIELD_GET(ctrl, CXL_HDM_DECODER0_CTRL_COMMITTED)) >>> return false; >> >> Compiler does not seem to like single bit mask. How about > > That's strange - number of bits shouldn't matter. > hough I got parameters backwards above which doesn't help. > FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl) ah yeah that was it. oops. > >> if (ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED) >> return false; >>> >>> >>>> + if (committed) >>>> + return false; >>>> + } >>>> + >>>> + return true; >>>> +} >>>> + >>> >>>> >>> >
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index ed5e9ef3aa9b..40844ff2fe52 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -729,6 +729,33 @@ static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port, return 0; } +static bool should_emulate_decoders(struct cxl_hdm *cxlhdm) +{ + void __iomem *hdm = cxlhdm->regs.hdm_decoder; + bool committed; + 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)); + committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED); + if (committed) + 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) @@ -744,16 +771,12 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, unsigned char target_id[8]; } target_list; + if (info->emulate_decoders) + return cxl_setup_hdm_decoder_from_dvsec(port, cxld, which, info); + if (is_endpoint_decoder(&cxld->dev)) cxled = to_cxl_endpoint_decoder(&cxld->dev); - if (!hdm) { - if (!cxled) - return -EINVAL; - - return cxl_setup_hdm_decoder_from_dvsec(port, cxld, which, info); - } - ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which)); base = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which)); size = ioread64_hi_lo(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(which)); @@ -889,6 +912,8 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm, cxl_settle_decoders(cxlhdm); + info->emulate_decoders = should_emulate_decoders(cxlhdm); + for (i = 0; i < cxlhdm->decoder_count; i++) { int target_map[CXL_DECODER_MAX_INTERLEAVE] = { 0 }; int rc, target_count = cxlhdm->target_count; diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 0ec047cced90..f1aa57a95150 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -640,6 +640,7 @@ struct cxl_endpoint_dvsec_info { bool mem_enabled; int ranges; struct range dvsec_range[2]; + bool emulate_decoders; }; struct cxl_hdm;
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. Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- drivers/cxl/core/hdm.c | 39 ++++++++++++++++++++++++++++++++------- drivers/cxl/cxl.h | 1 + 2 files changed, 33 insertions(+), 7 deletions(-)