[PATCH OLK-6.6] arm64/mpam: Add quirk for hisi cpbm_wd field

hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICX9YF -------------------------------- The bit mask width indicated in the MPAMF_CPOR_IDR_CPBM_WD IDR register of MPAM is inconsistent with the actual hardware capability. This incorrectly limits the L3 capacity in real use. Therefore, software has to hard-code a workaround to align with the actual CPBM bit width. Fixes: 051d021d1c1a ("arm_mpam: Probe the hardware features resctrl supports") Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_devices.c | 57 +++++++++++++++++++++++++-- drivers/platform/mpam/mpam_internal.h | 2 + drivers/platform/mpam/mpam_resctrl.c | 8 +++- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 516ffc4b4a3d..250032f58659 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -562,6 +562,28 @@ static struct mpam_msc_ris *mpam_get_or_create_ris(struct mpam_msc *msc, return found; } +u16 mpam_cpbm_wd_hisi_workaround(u16 cpbm_wd, enum mpam_device_features feat, + u8 cache_level) +{ + static const struct midr_range cpus[] = { + MIDR_ALL_VERSIONS(MIDR_HISI_HIP12), + { /* sentinel */ } + }; + + if (cache_level != 3) + return cpbm_wd; + + if (is_midr_in_range_list(read_cpuid_id(), cpus)) { + if (feat == mpam_feat_cpor_part) + return 19; + else if (feat == mpam_feat_ccap_part || + feat == mpam_feat_cmin) + return 21; + } + + return cpbm_wd; +} + static void mpam_ris_hw_probe(struct mpam_msc_ris *ris) { int err; @@ -591,7 +613,9 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris) if (FIELD_GET(MPAMF_IDR_HAS_CPOR_PART, ris->idr)) { u32 cpor_features = mpam_read_partsel_reg(msc, CPOR_IDR); - props->cpbm_wd = FIELD_GET(MPAMF_CPOR_IDR_CPBM_WD, cpor_features); + props->cpbm_wd = mpam_cpbm_wd_hisi_workaround( + FIELD_GET(MPAMF_CPOR_IDR_CPBM_WD, cpor_features), + mpam_feat_cpor_part, class->level); if (props->cpbm_wd) mpam_set_feature(mpam_feat_cpor_part, props); } @@ -1212,6 +1236,28 @@ static void mpam_reset_msc_bitmap(struct mpam_msc *msc, u16 reg, u16 wd) __mpam_write_reg(msc, reg, bm); } +static u32 mpam_cpbm_hisi_workaround(u32 cpbm, u8 cache_level) +{ + static const struct midr_range cpus[] = { + MIDR_ALL_VERSIONS(MIDR_HISI_HIP12), + { /* sentinel */ } + }; + + if (cache_level != 3 || + !is_midr_in_range_list(read_cpuid_id(), cpus)) + return cpbm; + + if (cpbm & BIT(18)) + cpbm |= (BIT(19) | BIT(20)); + + if (cpbm & BIT(17)) + cpbm |= BIT(18); + else + cpbm &= ~BIT(18); + + return cpbm; +} + static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid, struct mpam_config *cfg) { @@ -1232,10 +1278,15 @@ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid, if (mpam_has_feature(mpam_feat_cpor_part, rprops)) { if (mpam_has_feature(mpam_feat_cpor_part, cfg)) - mpam_write_partsel_reg(msc, CPBM, cfg->cpbm); + mpam_write_partsel_reg(msc, CPBM, + mpam_cpbm_hisi_workaround(cfg->cpbm, + ris->comp->class->level)); else mpam_reset_msc_bitmap(msc, MPAMCFG_CPBM, - rprops->cpbm_wd); + mpam_cpbm_wd_hisi_workaround( + rprops->cpbm_wd, + mpam_feat_cpor_part, + ris->comp->class->level)); } if (mpam_has_feature(mpam_feat_ccap_part, rprops)) { diff --git a/drivers/platform/mpam/mpam_internal.h b/drivers/platform/mpam/mpam_internal.h index ff1890b3a78e..204005331334 100644 --- a/drivers/platform/mpam/mpam_internal.h +++ b/drivers/platform/mpam/mpam_internal.h @@ -328,6 +328,8 @@ int mpam_resctrl_offline_cpu(unsigned int cpu); int mpam_resctrl_setup(void); void mpam_resctrl_exit(void); +u16 mpam_cpbm_wd_hisi_workaround(u16 cpbm_wd, enum mpam_device_features feat, u8 cache_level); + /* * MPAM MSCs have the following register layout. See: * Arm Architecture Reference Manual Supplement - Memory System Resource diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 6540b84e0f14..34fcb03c1eeb 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -691,7 +691,9 @@ static u16 percent_to_ca_max(u32 pc, u8 wd) if (read_cpuid_implementor() != ARM_CPU_IMP_HISI) return percent_to_mbw_max(pc, wd); - valid_max = l3->cache.cbm_len; + valid_max = mpam_cpbm_wd_hisi_workaround(l3->cache.cbm_len, + mpam_feat_ccap_part, + l3->cache_level); if (pc >= MAX_MBA_BW) return valid_max << (16 - wd); @@ -707,7 +709,9 @@ static u16 ca_max_to_percent(u16 ca_max, u8 wd) if (read_cpuid_implementor() != ARM_CPU_IMP_HISI) return mbw_max_to_percent(ca_max, wd); - valid_max = l3->cache.cbm_len; + valid_max = mpam_cpbm_wd_hisi_workaround(l3->cache.cbm_len, + mpam_feat_ccap_part, + l3->cache_level); ca_max = ca_max >> (16 - wd); if (ca_max >= valid_max) -- 2.25.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/18123 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/I3N... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/18123 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/I3N...
participants (2)
-
patchwork bot
-
Zeng Heng