Skip to content

Commit bef52b5

Browse files
committed
drm/xe: Create a xe_gt_freq component for raw management and sysfs
Goals of this new xe_gt_freq component: 1. Detach sysfs controls and raw freq management from GuC SLPC. 2. Create a directory that could later be aligned with devfreq. 3. Encapsulate all the freq control in a single directory. Although we only have one freq domain per GT, already start with a numbered freq0 directory so it could be expanded in the future if multiple domains or PLL are needed. Note: Although in the goal #1, the raw freq management control is mentioned, this patch only starts by the sysfs control. The RP freq configuration and init freq selection are still under the guc_pc, but should be moved to this component in a follow-up patch. v2: - Add /tile# to the doc and remove unnecessary kobject_put (Riana) - s/ssize_t/int on some ret variables (Vinay) Cc: Sujaritha Sundaresan <sujaritha.sundaresan@intel.com> Cc: Vinay Belgaumkar <vinay.belgaumkar@intel.com> Cc: Riana Tauro <riana.tauro@intel.com> Reviewed-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 2ab3cc4 commit bef52b5

File tree

7 files changed

+347
-104
lines changed

7 files changed

+347
-104
lines changed

drivers/gpu/drm/xe/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ xe-y += xe_bb.o \
7373
xe_gt_ccs_mode.o \
7474
xe_gt_clock.o \
7575
xe_gt_debugfs.o \
76+
xe_gt_freq.o \
7677
xe_gt_idle.o \
7778
xe_gt_mcr.o \
7879
xe_gt_pagefault.o \

drivers/gpu/drm/xe/xe_gt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "xe_gsc.h"
2525
#include "xe_gt_ccs_mode.h"
2626
#include "xe_gt_clock.h"
27+
#include "xe_gt_freq.h"
2728
#include "xe_gt_idle.h"
2829
#include "xe_gt_mcr.h"
2930
#include "xe_gt_pagefault.h"
@@ -511,6 +512,8 @@ int xe_gt_init(struct xe_gt *gt)
511512
if (err)
512513
return err;
513514

515+
xe_gt_freq_init(gt);
516+
514517
xe_force_wake_init_engines(gt, gt_to_fw(gt));
515518

516519
err = all_fw_domain_init(gt);

drivers/gpu/drm/xe/xe_gt_freq.c

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// SPDX-License-Identifier: MIT
2+
/*
3+
* Copyright © 2023 Intel Corporation
4+
*/
5+
6+
#include "xe_gt_freq.h"
7+
8+
#include <linux/kobject.h>
9+
#include <linux/sysfs.h>
10+
11+
#include <drm/drm_managed.h>
12+
#include <drm/drm_print.h>
13+
14+
#include "xe_device_types.h"
15+
#include "xe_gt_sysfs.h"
16+
#include "xe_guc_pc.h"
17+
18+
/**
19+
* DOC: Xe GT Frequency Management
20+
*
21+
* This component is responsible for the raw GT frequency management, including
22+
* the sysfs API.
23+
*
24+
* Underneath, Xe enables GuC SLPC automated frequency management. GuC is then
25+
* allowed to request PCODE any frequency between the Minimum and the Maximum
26+
* selected by this component. Furthermore, it is important to highlight that
27+
* PCODE is the ultimate decision maker of the actual running frequency, based
28+
* on thermal and other running conditions.
29+
*
30+
* Xe's Freq provides a sysfs API for frequency management:
31+
*
32+
* device/tile#/gt#/freq0/<item>_freq *read-only* files:
33+
* - act_freq: The actual resolved frequency decided by PCODE.
34+
* - cur_freq: The current one requested by GuC PC to the PCODE.
35+
* - rpn_freq: The Render Performance (RP) N level, which is the minimal one.
36+
* - rpe_freq: The Render Performance (RP) E level, which is the efficient one.
37+
* - rp0_freq: The Render Performance (RP) 0 level, which is the maximum one.
38+
*
39+
* device/tile#/gt#/freq0/<item>_freq *read-write* files:
40+
* - min_freq: Min frequency request.
41+
* - max_freq: Max frequency request.
42+
* If max <= min, then freq_min becomes a fixed frequency request.
43+
*/
44+
45+
static struct xe_guc_pc *
46+
dev_to_pc(struct device *dev)
47+
{
48+
return &kobj_to_gt(dev->kobj.parent)->uc.guc.pc;
49+
}
50+
51+
static ssize_t act_freq_show(struct device *dev,
52+
struct device_attribute *attr, char *buf)
53+
{
54+
struct xe_guc_pc *pc = dev_to_pc(dev);
55+
56+
return sysfs_emit(buf, "%d\n", xe_guc_pc_get_act_freq(pc));
57+
}
58+
static DEVICE_ATTR_RO(act_freq);
59+
60+
static ssize_t cur_freq_show(struct device *dev,
61+
struct device_attribute *attr, char *buf)
62+
{
63+
struct xe_guc_pc *pc = dev_to_pc(dev);
64+
u32 freq;
65+
ssize_t ret;
66+
67+
ret = xe_guc_pc_get_cur_freq(pc, &freq);
68+
if (ret)
69+
return ret;
70+
71+
return sysfs_emit(buf, "%d\n", freq);
72+
}
73+
static DEVICE_ATTR_RO(cur_freq);
74+
75+
static ssize_t rp0_freq_show(struct device *dev,
76+
struct device_attribute *attr, char *buf)
77+
{
78+
struct xe_guc_pc *pc = dev_to_pc(dev);
79+
80+
return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rp0_freq(pc));
81+
}
82+
static DEVICE_ATTR_RO(rp0_freq);
83+
84+
static ssize_t rpe_freq_show(struct device *dev,
85+
struct device_attribute *attr, char *buf)
86+
{
87+
struct xe_guc_pc *pc = dev_to_pc(dev);
88+
89+
return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rpe_freq(pc));
90+
}
91+
static DEVICE_ATTR_RO(rpe_freq);
92+
93+
static ssize_t rpn_freq_show(struct device *dev,
94+
struct device_attribute *attr, char *buf)
95+
{
96+
struct xe_guc_pc *pc = dev_to_pc(dev);
97+
98+
return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rpn_freq(pc));
99+
}
100+
static DEVICE_ATTR_RO(rpn_freq);
101+
102+
static ssize_t min_freq_show(struct device *dev,
103+
struct device_attribute *attr, char *buf)
104+
{
105+
struct xe_guc_pc *pc = dev_to_pc(dev);
106+
u32 freq;
107+
ssize_t ret;
108+
109+
ret = xe_guc_pc_get_min_freq(pc, &freq);
110+
if (ret)
111+
return ret;
112+
113+
return sysfs_emit(buf, "%d\n", freq);
114+
}
115+
116+
static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
117+
const char *buff, size_t count)
118+
{
119+
struct xe_guc_pc *pc = dev_to_pc(dev);
120+
u32 freq;
121+
ssize_t ret;
122+
123+
ret = kstrtou32(buff, 0, &freq);
124+
if (ret)
125+
return ret;
126+
127+
ret = xe_guc_pc_set_min_freq(pc, freq);
128+
if (ret)
129+
return ret;
130+
131+
return count;
132+
}
133+
static DEVICE_ATTR_RW(min_freq);
134+
135+
static ssize_t max_freq_show(struct device *dev,
136+
struct device_attribute *attr, char *buf)
137+
{
138+
struct xe_guc_pc *pc = dev_to_pc(dev);
139+
u32 freq;
140+
ssize_t ret;
141+
142+
ret = xe_guc_pc_get_max_freq(pc, &freq);
143+
if (ret)
144+
return ret;
145+
146+
return sysfs_emit(buf, "%d\n", freq);
147+
}
148+
149+
static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
150+
const char *buff, size_t count)
151+
{
152+
struct xe_guc_pc *pc = dev_to_pc(dev);
153+
u32 freq;
154+
ssize_t ret;
155+
156+
ret = kstrtou32(buff, 0, &freq);
157+
if (ret)
158+
return ret;
159+
160+
ret = xe_guc_pc_set_max_freq(pc, freq);
161+
if (ret)
162+
return ret;
163+
164+
return count;
165+
}
166+
static DEVICE_ATTR_RW(max_freq);
167+
168+
static const struct attribute *freq_attrs[] = {
169+
&dev_attr_act_freq.attr,
170+
&dev_attr_cur_freq.attr,
171+
&dev_attr_rp0_freq.attr,
172+
&dev_attr_rpe_freq.attr,
173+
&dev_attr_rpn_freq.attr,
174+
&dev_attr_min_freq.attr,
175+
&dev_attr_max_freq.attr,
176+
NULL
177+
};
178+
179+
static void freq_fini(struct drm_device *drm, void *arg)
180+
{
181+
struct kobject *kobj = arg;
182+
183+
sysfs_remove_files(kobj, freq_attrs);
184+
kobject_put(kobj);
185+
}
186+
187+
/**
188+
* xe_gt_freq_init - Initialize Xe Freq component
189+
* @gt: Xe GT object
190+
*
191+
* It needs to be initialized after GT Sysfs and GuC PC components are ready.
192+
*/
193+
void xe_gt_freq_init(struct xe_gt *gt)
194+
{
195+
struct xe_device *xe = gt_to_xe(gt);
196+
int err;
197+
198+
gt->freq = kobject_create_and_add("freq0", gt->sysfs);
199+
if (!gt->freq) {
200+
drm_warn(&xe->drm, "failed to add freq0 directory to %s, err: %d\n",
201+
kobject_name(gt->sysfs), err);
202+
return;
203+
}
204+
205+
err = drmm_add_action_or_reset(&xe->drm, freq_fini, gt->freq);
206+
if (err) {
207+
drm_warn(&xe->drm, "%s: drmm_add_action_or_reset failed, err: %d\n",
208+
__func__, err);
209+
return;
210+
}
211+
212+
err = sysfs_create_files(gt->freq, freq_attrs);
213+
if (err)
214+
drm_warn(&xe->drm, "failed to add freq attrs to %s, err: %d\n",
215+
kobject_name(gt->freq), err);
216+
}

drivers/gpu/drm/xe/xe_gt_freq.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* SPDX-License-Identifier: MIT */
2+
/*
3+
* Copyright © 2023 Intel Corporation
4+
*/
5+
6+
#ifndef _XE_GT_FREQ_H_
7+
#define _XE_GT_FREQ_H_
8+
9+
struct xe_gt;
10+
11+
void xe_gt_freq_init(struct xe_gt *gt);
12+
13+
#endif

drivers/gpu/drm/xe/xe_gt_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ struct xe_gt {
307307
/** @sysfs: sysfs' kobj used by xe_gt_sysfs */
308308
struct kobject *sysfs;
309309

310+
/** @freq: Main GT freq sysfs control */
311+
struct kobject *freq;
312+
310313
/** @mocs: info */
311314
struct {
312315
/** @uc_index: UC index */

0 commit comments

Comments
 (0)