@@ -19,6 +19,25 @@ struct cxl_cxims_data {
* Find a targets entry (n) in the host bridge interleave list.
* CXL Specfication 3.0 Table 9-22
*/
+static int cxl_xor_calc_n(u64 hpa, struct cxl_cxims_data *cximsd, int iw,
+ int ig)
+{
+ int eiw, i = 0, n = 0;
+
+ /* IW: 2,4,6,8,12,16 begin building 'n' using xormaps */
+ if (iw != 3) {
+ for (i = 0; i < cximsd->nr_maps; i++)
+ n |= (hweight64(hpa & cximsd->xormaps[i]) & 1) << i;
+ }
+ /* IW: 3,6,12 add a modulo calculation to 'n' */
+ if (!is_power_of_2(iw)) {
+ eiw = ilog2(iw / 3) + 8;
+ hpa &= GENMASK_ULL(51, eiw + ig);
+ n |= do_div(hpa, 3) << i;
+ }
+ return n;
+}
+
static struct cxl_dport *cxl_hb_xor(struct cxl_root_decoder *cxlrd, int pos)
{
struct cxl_cxims_data *cximsd = cxlrd->platform_data;
@@ -26,7 +45,7 @@ static struct cxl_dport *cxl_hb_xor(struct cxl_root_decoder *cxlrd, int pos)
struct cxl_decoder *cxld = &cxlsd->cxld;
int ig = cxld->interleave_granularity;
int iw = cxld->interleave_ways;
- int eiw, i = 0, n = 0;
+ int n = 0;
u64 hpa;
if (dev_WARN_ONCE(&cxld->dev,
@@ -34,26 +53,12 @@ static struct cxl_dport *cxl_hb_xor(struct cxl_root_decoder *cxlrd, int pos)
"misconfigured root decoder\n"))
return NULL;
- if (iw == 1)
- /* Entry is always 0 for no interleave */
- return cxlrd->cxlsd.target[0];
-
hpa = cxlrd->res->start + pos * ig;
- if (iw == 3)
- goto no_map;
+ /* Entry (n) is 0 for no interleave (iw == 1) */
+ if (iw != 1)
+ n = cxl_xor_calc_n(hpa, cximsd, iw, ig);
- /* IW: 2,4,6,8,12,16 begin building 'n' using xormaps */
- for (i = 0; i < cximsd->nr_maps; i++)
- n |= (hweight64(hpa & cximsd->xormaps[i]) & 1) << i;
-
-no_map:
- /* IW: 3,6,12 add a modulo calculation to 'n' */
- if (!is_power_of_2(iw)) {
- eiw = ilog2(iw / 3) + 8;
- hpa &= GENMASK_ULL(51, eiw + ig);
- n |= do_div(hpa, 3) << i;
- }
return cxlrd->cxlsd.target[n];
}