diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index a6381bcdf0373dc92a6f352dce0a11cc376d9938..e77622ec29bf68272aa625e2ca60f54fa630f86d 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -683,6 +683,39 @@ static u16 percent_to_mbw_max(u32 pc, u8 wd) return value; } +static u16 percent_to_ca_max(u32 pc, u8 wd) +{ + struct rdt_resource *l3 = resctrl_arch_get_resource(RDT_RESOURCE_L3); + u32 valid_max; + + if (read_cpuid_implementor() != ARM_CPU_IMP_HISI) + return percent_to_mbw_max(pc, wd); + + valid_max = l3->cache.cbm_len; + + if (pc >= MAX_MBA_BW) + return valid_max << (16 - wd); + + return ((pc * valid_max + 50) / 100) << (16 - wd); +} + +static u16 ca_max_to_percent(u16 ca_max, u8 wd) +{ + struct rdt_resource *l3 = resctrl_arch_get_resource(RDT_RESOURCE_L3); + u32 valid_max; + + if (read_cpuid_implementor() != ARM_CPU_IMP_HISI) + return mbw_max_to_percent(ca_max, wd); + + valid_max = l3->cache.cbm_len; + + ca_max = ca_max >> (16 - wd); + if (ca_max >= valid_max) + return MAX_MBA_BW; + + return (ca_max * 100 + valid_max / 2) / valid_max; +} + /* Test whether we can export MPAM_CLASS_CACHE:{2,3}? */ static void mpam_resctrl_pick_caches(void) { @@ -1001,7 +1034,10 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) r->alloc_capable = true; r->membw.min_bw = 1; - r->membw.bw_gran = max(100 / (1 << cprops->cmax_wd), 1); + if (read_cpuid_implementor() != ARM_CPU_IMP_HISI) + r->membw.bw_gran = max(100 / (1 << cprops->cmax_wd), 1); + else + r->membw.bw_gran = max(100 / resctrl_arch_get_resource(RDT_RESOURCE_L3)->cache.cbm_len, 1); break; case RDT_RESOURCE_L3_MIN: @@ -1018,7 +1054,10 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) r->alloc_capable = true; r->membw.min_bw = 0; - r->membw.bw_gran = max(100 / (1 << cprops->cmax_wd), 1); + if (read_cpuid_implementor() != ARM_CPU_IMP_HISI) + r->membw.bw_gran = max(100 / (1 << cprops->cmax_wd), 1); + else + r->membw.bw_gran = max(100 / resctrl_arch_get_resource(RDT_RESOURCE_L3)->cache.cbm_len, 1); break; case RDT_RESOURCE_MB_MIN: @@ -1249,9 +1288,9 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, /* TODO: Scaling is not yet supported */ return cfg->cpbm; case mpam_feat_ccap_part: - return mbw_max_to_percent(cfg->cmax, cprops->cmax_wd); + return ca_max_to_percent(cfg->cmax, cprops->cmax_wd); case mpam_feat_cmin: - return mbw_max_to_percent(cfg->cmin, cprops->cmax_wd); + return ca_max_to_percent(cfg->cmin, cprops->cmax_wd); case mpam_feat_intpri_part: return cfg->intpri; case mpam_feat_mbw_part: @@ -1301,12 +1340,12 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_domain *d, break; case RDT_RESOURCE_L2_MAX: case RDT_RESOURCE_L3_MAX: - cfg.cmax = percent_to_mbw_max(cfg_val, cprops->cmax_wd); + cfg.cmax = percent_to_ca_max(cfg_val, cprops->cmax_wd); mpam_set_feature(mpam_feat_ccap_part, &cfg); break; case RDT_RESOURCE_L2_MIN: case RDT_RESOURCE_L3_MIN: - cfg.cmin = percent_to_mbw_max(cfg_val, cprops->cmax_wd); + cfg.cmin = percent_to_ca_max(cfg_val, cprops->cmax_wd); mpam_set_feature(mpam_feat_cmin, &cfg); break; case RDT_RESOURCE_L2_PRI: