]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/6.8.6/drivers-perf-hisi-enable-hisilicon-erratum-162700402.patch
Linux 6.8.6
[thirdparty/kernel/stable-queue.git] / releases / 6.8.6 / drivers-perf-hisi-enable-hisilicon-erratum-162700402.patch
1 From c4efc8ce27a8db0b812c94d063c482251fd3d605 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Tue, 27 Feb 2024 20:52:31 +0800
4 Subject: drivers/perf: hisi: Enable HiSilicon Erratum 162700402 quirk for
5 HIP09
6
7 From: Junhao He <hejunhao3@huawei.com>
8
9 [ Upstream commit e10b6976f6b9afdf3564f88c851e42d139bb19c0 ]
10
11 HiSilicon UC PMU v2 suffers the erratum 162700402 that the PMU counter
12 cannot be set due to the lack of clock under power saving mode. This will
13 lead to error or inaccurate counts. The clock can be enabled by the PMU
14 global enabling control.
15
16 This patch tries to fix this by set the UC PMU enable before set event
17 period to turn on the clock, and then restore the UC PMU configuration.
18 The counter register can hold its value without a clock.
19
20 Signed-off-by: Junhao He <hejunhao3@huawei.com>
21 Reviewed-by: Yicong Yang <yangyicong@hisilicon.com>
22 Link: https://lore.kernel.org/r/20240227125231.53127-1-hejunhao3@huawei.com
23 Signed-off-by: Will Deacon <will@kernel.org>
24 Signed-off-by: Sasha Levin <sashal@kernel.org>
25 ---
26 drivers/perf/hisilicon/hisi_uncore_uc_pmu.c | 42 ++++++++++++++++++++-
27 1 file changed, 41 insertions(+), 1 deletion(-)
28
29 diff --git a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
30 index 636fb79647c8c..481dcc9e8fbf8 100644
31 --- a/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
32 +++ b/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c
33 @@ -287,12 +287,52 @@ static u64 hisi_uc_pmu_read_counter(struct hisi_pmu *uc_pmu,
34 return readq(uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
35 }
36
37 -static void hisi_uc_pmu_write_counter(struct hisi_pmu *uc_pmu,
38 +static bool hisi_uc_pmu_get_glb_en_state(struct hisi_pmu *uc_pmu)
39 +{
40 + u32 val;
41 +
42 + val = readl(uc_pmu->base + HISI_UC_EVENT_CTRL_REG);
43 + return !!FIELD_GET(HISI_UC_EVENT_GLB_EN, val);
44 +}
45 +
46 +static void hisi_uc_pmu_write_counter_normal(struct hisi_pmu *uc_pmu,
47 struct hw_perf_event *hwc, u64 val)
48 {
49 writeq(val, uc_pmu->base + HISI_UC_CNTR_REGn(hwc->idx));
50 }
51
52 +static void hisi_uc_pmu_write_counter_quirk_v2(struct hisi_pmu *uc_pmu,
53 + struct hw_perf_event *hwc, u64 val)
54 +{
55 + hisi_uc_pmu_start_counters(uc_pmu);
56 + hisi_uc_pmu_write_counter_normal(uc_pmu, hwc, val);
57 + hisi_uc_pmu_stop_counters(uc_pmu);
58 +}
59 +
60 +static void hisi_uc_pmu_write_counter(struct hisi_pmu *uc_pmu,
61 + struct hw_perf_event *hwc, u64 val)
62 +{
63 + bool enable = hisi_uc_pmu_get_glb_en_state(uc_pmu);
64 + bool erratum = uc_pmu->identifier == HISI_PMU_V2;
65 +
66 + /*
67 + * HiSilicon UC PMU v2 suffers the erratum 162700402 that the
68 + * PMU counter cannot be set due to the lack of clock under power
69 + * saving mode. This will lead to error or inaccurate counts.
70 + * The clock can be enabled by the PMU global enabling control.
71 + * The irq handler and pmu_start() will call the function to set
72 + * period. If the function under irq context, the PMU has been
73 + * enabled therefore we set counter directly. Other situations
74 + * the PMU is disabled, we need to enable it to turn on the
75 + * counter clock to set period, and then restore PMU enable
76 + * status, the counter can hold its value without a clock.
77 + */
78 + if (enable || !erratum)
79 + hisi_uc_pmu_write_counter_normal(uc_pmu, hwc, val);
80 + else
81 + hisi_uc_pmu_write_counter_quirk_v2(uc_pmu, hwc, val);
82 +}
83 +
84 static void hisi_uc_pmu_enable_counter_int(struct hisi_pmu *uc_pmu,
85 struct hw_perf_event *hwc)
86 {
87 --
88 2.43.0
89