Skip to content

Commit 29614c5

Browse files
Junhao Hewilldeacon
authored andcommitted
drivers/perf: hisi: Use ACPI driver_data to retrieve SLLC PMU information
Make use of struct acpi_device_id::driver_data for version specific information rather than judge the version register. This will help to simplify the probe process and also a bit easier for extension. Factor out SLLC register definition to struct hisi_sllc_pmu_regs. No functional changes intended. Reviewed-by: Jonathan Cameron <[email protected]> Signed-off-by: Junhao He <[email protected]> Signed-off-by: Yicong Yang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 17aa34e commit 29614c5

File tree

1 file changed

+118
-60
lines changed

1 file changed

+118
-60
lines changed

drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c

Lines changed: 118 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,31 @@
4141
#define SLLC_SRCID_CMD_SHIFT 1
4242
#define SLLC_SRCID_MSK_SHIFT 12
4343
#define SLLC_NR_EVENTS 0x80
44+
#define SLLC_EVENT_CNTn(cnt0, n) ((cnt0) + (n) * 8)
4445

4546
HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_min, config1, 10, 0);
4647
HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_max, config1, 21, 11);
4748
HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 32, 22);
4849
HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 43, 33);
4950
HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 44, 44);
5051

52+
struct hisi_sllc_pmu_regs {
53+
u32 int_mask;
54+
u32 int_clear;
55+
u32 int_status;
56+
u32 perf_ctrl;
57+
u32 srcid_ctrl;
58+
u32 srcid_cmd_shift;
59+
u32 srcid_mask_shift;
60+
u32 tgtid_ctrl;
61+
u32 tgtid_min_shift;
62+
u32 tgtid_max_shift;
63+
u32 event_ctrl;
64+
u32 event_type0;
65+
u32 version;
66+
u32 event_cnt0;
67+
};
68+
5169
static bool tgtid_is_valid(u32 max, u32 min)
5270
{
5371
return max > 0 && max >= min;
@@ -56,96 +74,104 @@ static bool tgtid_is_valid(u32 max, u32 min)
5674
static void hisi_sllc_pmu_enable_tracetag(struct perf_event *event)
5775
{
5876
struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
77+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
5978
u32 tt_en = hisi_get_tracetag_en(event);
6079

6180
if (tt_en) {
6281
u32 val;
6382

64-
val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
83+
val = readl(sllc_pmu->base + regs->perf_ctrl);
6584
val |= SLLC_TRACETAG_EN | SLLC_FILT_EN;
66-
writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
85+
writel(val, sllc_pmu->base + regs->perf_ctrl);
6786
}
6887
}
6988

7089
static void hisi_sllc_pmu_disable_tracetag(struct perf_event *event)
7190
{
7291
struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
92+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
7393
u32 tt_en = hisi_get_tracetag_en(event);
7494

7595
if (tt_en) {
7696
u32 val;
7797

78-
val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
98+
val = readl(sllc_pmu->base + regs->perf_ctrl);
7999
val &= ~(SLLC_TRACETAG_EN | SLLC_FILT_EN);
80-
writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
100+
writel(val, sllc_pmu->base + regs->perf_ctrl);
81101
}
82102
}
83103

84104
static void hisi_sllc_pmu_config_tgtid(struct perf_event *event)
85105
{
86106
struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
107+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
87108
u32 min = hisi_get_tgtid_min(event);
88109
u32 max = hisi_get_tgtid_max(event);
89110

90111
if (tgtid_is_valid(max, min)) {
91-
u32 val = (max << SLLC_TGTID_MAX_SHIFT) | (min << SLLC_TGTID_MIN_SHIFT);
112+
u32 val = (max << regs->tgtid_max_shift) |
113+
(min << regs->tgtid_min_shift);
92114

93-
writel(val, sllc_pmu->base + SLLC_TGTID_CTRL);
115+
writel(val, sllc_pmu->base + regs->tgtid_ctrl);
94116
/* Enable the tgtid */
95-
val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
117+
val = readl(sllc_pmu->base + regs->perf_ctrl);
96118
val |= SLLC_TGTID_EN | SLLC_FILT_EN;
97-
writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
119+
writel(val, sllc_pmu->base + regs->perf_ctrl);
98120
}
99121
}
100122

101123
static void hisi_sllc_pmu_clear_tgtid(struct perf_event *event)
102124
{
103125
struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
126+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
104127
u32 min = hisi_get_tgtid_min(event);
105128
u32 max = hisi_get_tgtid_max(event);
106129

107130
if (tgtid_is_valid(max, min)) {
108131
u32 val;
109132

110-
writel(SLLC_TGTID_NONE, sllc_pmu->base + SLLC_TGTID_CTRL);
133+
writel(SLLC_TGTID_NONE, sllc_pmu->base + regs->tgtid_ctrl);
111134
/* Disable the tgtid */
112-
val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
135+
val = readl(sllc_pmu->base + regs->perf_ctrl);
113136
val &= ~(SLLC_TGTID_EN | SLLC_FILT_EN);
114-
writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
137+
writel(val, sllc_pmu->base + regs->perf_ctrl);
115138
}
116139
}
117140

118141
static void hisi_sllc_pmu_config_srcid(struct perf_event *event)
119142
{
120143
struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
144+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
121145
u32 cmd = hisi_get_srcid_cmd(event);
122146

123147
if (cmd) {
124148
u32 val, msk;
125149

126150
msk = hisi_get_srcid_msk(event);
127-
val = (cmd << SLLC_SRCID_CMD_SHIFT) | (msk << SLLC_SRCID_MSK_SHIFT);
128-
writel(val, sllc_pmu->base + SLLC_SRCID_CTRL);
151+
val = (cmd << regs->srcid_cmd_shift) |
152+
(msk << regs->srcid_mask_shift);
153+
writel(val, sllc_pmu->base + regs->srcid_ctrl);
129154
/* Enable the srcid */
130-
val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
155+
val = readl(sllc_pmu->base + regs->perf_ctrl);
131156
val |= SLLC_SRCID_EN | SLLC_FILT_EN;
132-
writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
157+
writel(val, sllc_pmu->base + regs->perf_ctrl);
133158
}
134159
}
135160

136161
static void hisi_sllc_pmu_clear_srcid(struct perf_event *event)
137162
{
138163
struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
164+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
139165
u32 cmd = hisi_get_srcid_cmd(event);
140166

141167
if (cmd) {
142168
u32 val;
143169

144-
writel(SLLC_SRCID_NONE, sllc_pmu->base + SLLC_SRCID_CTRL);
170+
writel(SLLC_SRCID_NONE, sllc_pmu->base + regs->srcid_ctrl);
145171
/* Disable the srcid */
146-
val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
172+
val = readl(sllc_pmu->base + regs->perf_ctrl);
147173
val &= ~(SLLC_SRCID_EN | SLLC_FILT_EN);
148-
writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
174+
writel(val, sllc_pmu->base + regs->perf_ctrl);
149175
}
150176
}
151177

@@ -167,29 +193,27 @@ static void hisi_sllc_pmu_clear_filter(struct perf_event *event)
167193
}
168194
}
169195

170-
static u32 hisi_sllc_pmu_get_counter_offset(int idx)
171-
{
172-
return (SLLC_EVENT_CNT0_L + idx * 8);
173-
}
174-
175196
static u64 hisi_sllc_pmu_read_counter(struct hisi_pmu *sllc_pmu,
176197
struct hw_perf_event *hwc)
177198
{
178-
return readq(sllc_pmu->base +
179-
hisi_sllc_pmu_get_counter_offset(hwc->idx));
199+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
200+
201+
return readq(sllc_pmu->base + SLLC_EVENT_CNTn(regs->event_cnt0, hwc->idx));
180202
}
181203

182204
static void hisi_sllc_pmu_write_counter(struct hisi_pmu *sllc_pmu,
183205
struct hw_perf_event *hwc, u64 val)
184206
{
185-
writeq(val, sllc_pmu->base +
186-
hisi_sllc_pmu_get_counter_offset(hwc->idx));
207+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
208+
209+
writeq(val, sllc_pmu->base + SLLC_EVENT_CNTn(regs->event_cnt0, hwc->idx));
187210
}
188211

189212
static void hisi_sllc_pmu_write_evtype(struct hisi_pmu *sllc_pmu, int idx,
190213
u32 type)
191214
{
192-
u32 reg, reg_idx, shift, val;
215+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
216+
u32 reg, val;
193217

194218
/*
195219
* Select the appropriate event select register(SLLC_EVENT_TYPE0/1).
@@ -198,96 +222,98 @@ static void hisi_sllc_pmu_write_evtype(struct hisi_pmu *sllc_pmu, int idx,
198222
* SLLC_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
199223
* SLLC_EVENT_TYPE1 is chosen.
200224
*/
201-
reg = SLLC_EVENT_TYPE0 + (idx / 4) * 4;
202-
reg_idx = idx % 4;
203-
shift = 8 * reg_idx;
225+
reg = regs->event_type0 + (idx / 4) * 4;
204226

205227
/* Write event code to SLLC_EVENT_TYPEx Register */
206228
val = readl(sllc_pmu->base + reg);
207-
val &= ~(SLLC_EVTYPE_MASK << shift);
208-
val |= (type << shift);
229+
val &= ~(SLLC_EVTYPE_MASK << HISI_PMU_EVTYPE_SHIFT(idx));
230+
val |= (type << HISI_PMU_EVTYPE_SHIFT(idx));
209231
writel(val, sllc_pmu->base + reg);
210232
}
211233

212234
static void hisi_sllc_pmu_start_counters(struct hisi_pmu *sllc_pmu)
213235
{
236+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
214237
u32 val;
215238

216-
val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
239+
val = readl(sllc_pmu->base + regs->perf_ctrl);
217240
val |= SLLC_PERF_CTRL_EN;
218-
writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
241+
writel(val, sllc_pmu->base + regs->perf_ctrl);
219242
}
220243

221244
static void hisi_sllc_pmu_stop_counters(struct hisi_pmu *sllc_pmu)
222245
{
246+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
223247
u32 val;
224248

225-
val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
249+
val = readl(sllc_pmu->base + regs->perf_ctrl);
226250
val &= ~(SLLC_PERF_CTRL_EN);
227-
writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
251+
writel(val, sllc_pmu->base + regs->perf_ctrl);
228252
}
229253

230254
static void hisi_sllc_pmu_enable_counter(struct hisi_pmu *sllc_pmu,
231255
struct hw_perf_event *hwc)
232256
{
257+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
233258
u32 val;
234259

235-
val = readl(sllc_pmu->base + SLLC_EVENT_CTRL);
236-
val |= 1 << hwc->idx;
237-
writel(val, sllc_pmu->base + SLLC_EVENT_CTRL);
260+
val = readl(sllc_pmu->base + regs->event_ctrl);
261+
val |= BIT_ULL(hwc->idx);
262+
writel(val, sllc_pmu->base + regs->event_ctrl);
238263
}
239264

240265
static void hisi_sllc_pmu_disable_counter(struct hisi_pmu *sllc_pmu,
241266
struct hw_perf_event *hwc)
242267
{
268+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
243269
u32 val;
244270

245-
val = readl(sllc_pmu->base + SLLC_EVENT_CTRL);
246-
val &= ~(1 << hwc->idx);
247-
writel(val, sllc_pmu->base + SLLC_EVENT_CTRL);
271+
val = readl(sllc_pmu->base + regs->event_ctrl);
272+
val &= ~BIT_ULL(hwc->idx);
273+
writel(val, sllc_pmu->base + regs->event_ctrl);
248274
}
249275

250276
static void hisi_sllc_pmu_enable_counter_int(struct hisi_pmu *sllc_pmu,
251277
struct hw_perf_event *hwc)
252278
{
279+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
253280
u32 val;
254281

255-
val = readl(sllc_pmu->base + SLLC_INT_MASK);
256-
/* Write 0 to enable interrupt */
257-
val &= ~(1 << hwc->idx);
258-
writel(val, sllc_pmu->base + SLLC_INT_MASK);
282+
val = readl(sllc_pmu->base + regs->int_mask);
283+
val &= ~BIT_ULL(hwc->idx);
284+
writel(val, sllc_pmu->base + regs->int_mask);
259285
}
260286

261287
static void hisi_sllc_pmu_disable_counter_int(struct hisi_pmu *sllc_pmu,
262288
struct hw_perf_event *hwc)
263289
{
290+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
264291
u32 val;
265292

266-
val = readl(sllc_pmu->base + SLLC_INT_MASK);
267-
/* Write 1 to mask interrupt */
268-
val |= 1 << hwc->idx;
269-
writel(val, sllc_pmu->base + SLLC_INT_MASK);
293+
val = readl(sllc_pmu->base + regs->int_mask);
294+
val |= BIT_ULL(hwc->idx);
295+
writel(val, sllc_pmu->base + regs->int_mask);
270296
}
271297

272298
static u32 hisi_sllc_pmu_get_int_status(struct hisi_pmu *sllc_pmu)
273299
{
274-
return readl(sllc_pmu->base + SLLC_INT_STATUS);
300+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
301+
302+
return readl(sllc_pmu->base + regs->int_status);
275303
}
276304

277305
static void hisi_sllc_pmu_clear_int_status(struct hisi_pmu *sllc_pmu, int idx)
278306
{
279-
writel(1 << idx, sllc_pmu->base + SLLC_INT_CLEAR);
280-
}
307+
struct hisi_sllc_pmu_regs *regs = sllc_pmu->dev_info->private;
281308

282-
static const struct acpi_device_id hisi_sllc_pmu_acpi_match[] = {
283-
{ "HISI0263", },
284-
{}
285-
};
286-
MODULE_DEVICE_TABLE(acpi, hisi_sllc_pmu_acpi_match);
309+
writel(BIT_ULL(idx), sllc_pmu->base + regs->int_clear);
310+
}
287311

288312
static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
289313
struct hisi_pmu *sllc_pmu)
290314
{
315+
struct hisi_sllc_pmu_regs *regs;
316+
291317
hisi_uncore_pmu_init_topology(sllc_pmu, &pdev->dev);
292318

293319
/*
@@ -304,13 +330,18 @@ static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
304330
return -EINVAL;
305331
}
306332

333+
sllc_pmu->dev_info = device_get_match_data(&pdev->dev);
334+
if (!sllc_pmu->dev_info)
335+
return -ENODEV;
336+
307337
sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
308338
if (IS_ERR(sllc_pmu->base)) {
309339
dev_err(&pdev->dev, "ioremap failed for sllc_pmu resource.\n");
310340
return PTR_ERR(sllc_pmu->base);
311341
}
312342

313-
sllc_pmu->identifier = readl(sllc_pmu->base + SLLC_VERSION);
343+
regs = sllc_pmu->dev_info->private;
344+
sllc_pmu->identifier = readl(sllc_pmu->base + regs->version);
314345

315346
return 0;
316347
}
@@ -352,6 +383,27 @@ static const struct attribute_group *hisi_sllc_pmu_v2_attr_groups[] = {
352383
NULL
353384
};
354385

386+
static struct hisi_sllc_pmu_regs hisi_sllc_v2_pmu_regs = {
387+
.int_mask = SLLC_INT_MASK,
388+
.int_clear = SLLC_INT_CLEAR,
389+
.int_status = SLLC_INT_STATUS,
390+
.perf_ctrl = SLLC_PERF_CTRL,
391+
.srcid_ctrl = SLLC_SRCID_CTRL,
392+
.srcid_cmd_shift = SLLC_SRCID_CMD_SHIFT,
393+
.srcid_mask_shift = SLLC_SRCID_MSK_SHIFT,
394+
.tgtid_ctrl = SLLC_TGTID_CTRL,
395+
.tgtid_min_shift = SLLC_TGTID_MIN_SHIFT,
396+
.tgtid_max_shift = SLLC_TGTID_MAX_SHIFT,
397+
.event_ctrl = SLLC_EVENT_CTRL,
398+
.event_type0 = SLLC_EVENT_TYPE0,
399+
.version = SLLC_VERSION,
400+
.event_cnt0 = SLLC_EVENT_CNT0_L,
401+
};
402+
403+
static const struct hisi_pmu_dev_info hisi_sllc_v2 = {
404+
.private = &hisi_sllc_v2_pmu_regs,
405+
};
406+
355407
static const struct hisi_uncore_ops hisi_uncore_sllc_ops = {
356408
.write_evtype = hisi_sllc_pmu_write_evtype,
357409
.get_event_idx = hisi_uncore_pmu_get_event_idx,
@@ -443,6 +495,12 @@ static void hisi_sllc_pmu_remove(struct platform_device *pdev)
443495
&sllc_pmu->node);
444496
}
445497

498+
static const struct acpi_device_id hisi_sllc_pmu_acpi_match[] = {
499+
{ "HISI0263", (kernel_ulong_t)&hisi_sllc_v2 },
500+
{}
501+
};
502+
MODULE_DEVICE_TABLE(acpi, hisi_sllc_pmu_acpi_match);
503+
446504
static struct platform_driver hisi_sllc_pmu_driver = {
447505
.driver = {
448506
.name = "hisi_sllc_pmu",

0 commit comments

Comments
 (0)