@@ -22,11 +22,6 @@ bool is_object_gt(struct kobject *kobj)
return !strncmp(kobj->name, "gt", 2);
}
-static struct intel_gt *kobj_to_gt(struct kobject *kobj)
-{
- return container_of(kobj, struct intel_gt, sysfs_gt);
-}
-
struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
const char *name)
{
@@ -101,6 +96,10 @@ void intel_gt_sysfs_register(struct intel_gt *gt)
gt->i915->sysfs_gt, "gt%d", gt->info.id))
goto exit_fail;
+ gt->sysfs_defaults = kobject_create_and_add(".defaults", >->sysfs_gt);
+ if (!gt->sysfs_defaults)
+ goto exit_fail;
+
intel_gt_sysfs_pm_init(gt, >->sysfs_gt);
return;
@@ -113,5 +112,6 @@ void intel_gt_sysfs_register(struct intel_gt *gt)
void intel_gt_sysfs_unregister(struct intel_gt *gt)
{
+ kobject_put(gt->sysfs_defaults);
kobject_put(>->sysfs_gt);
}
@@ -10,6 +10,7 @@
#include <linux/kobject.h>
#include "i915_gem.h" /* GEM_BUG_ON() */
+#include "intel_gt_types.h"
struct intel_gt;
@@ -22,6 +23,11 @@ intel_gt_create_kobj(struct intel_gt *gt,
struct kobject *dir,
const char *name);
+static inline struct intel_gt *kobj_to_gt(struct kobject *kobj)
+{
+ return container_of(kobj, struct intel_gt, sysfs_gt);
+}
+
void intel_gt_sysfs_register(struct intel_gt *gt);
void intel_gt_sysfs_unregister(struct intel_gt *gt);
struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
@@ -727,6 +727,51 @@ static const struct attribute *media_perf_power_attrs[] = {
NULL
};
+static ssize_t
+default_min_freq_mhz_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ struct intel_gt *gt = kobj_to_gt(kobj->parent);
+
+ return sysfs_emit(buf, "%d\n", gt->rps_defaults.min_freq);
+}
+
+static struct kobj_attribute default_min_freq_mhz =
+__ATTR(rps_min_freq_mhz, 0444, default_min_freq_mhz_show, NULL);
+
+static ssize_t
+default_max_freq_mhz_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ struct intel_gt *gt = kobj_to_gt(kobj->parent);
+
+ return sysfs_emit(buf, "%d\n", gt->rps_defaults.max_freq);
+}
+
+static struct kobj_attribute default_max_freq_mhz =
+__ATTR(rps_max_freq_mhz, 0444, default_max_freq_mhz_show, NULL);
+
+static ssize_t
+default_boost_freq_mhz_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ struct intel_gt *gt = kobj_to_gt(kobj->parent);
+
+ return sysfs_emit(buf, "%d\n", gt->rps_defaults.boost_freq);
+}
+
+static struct kobj_attribute default_boost_freq_mhz =
+__ATTR(rps_boost_freq_mhz, 0444, default_boost_freq_mhz_show, NULL);
+
+static const struct attribute * const rps_defaults_attrs[] = {
+ &default_min_freq_mhz.attr,
+ &default_max_freq_mhz.attr,
+ &default_boost_freq_mhz.attr,
+ NULL
+};
+
+static int add_rps_defaults(struct intel_gt *gt)
+{
+ return sysfs_create_files(gt->sysfs_defaults, rps_defaults_attrs);
+}
+
static int intel_sysfs_rps_init(struct intel_gt *gt, struct kobject *kobj,
const struct attribute * const *attrs)
{
@@ -776,4 +821,10 @@ void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj)
"failed to create gt%u media_perf_power_attrs sysfs (%pe)\n",
gt->info.id, ERR_PTR(ret));
}
+
+ ret = add_rps_defaults(gt);
+ if (ret)
+ drm_warn(>->i915->drm,
+ "failed to add gt%u rps defaults (%pe)\n",
+ gt->info.id, ERR_PTR(ret));
}
@@ -62,6 +62,12 @@ enum intel_steering_type {
NUM_STEERING_TYPES
};
+struct intel_rps_defaults {
+ u32 min_freq;
+ u32 max_freq;
+ u32 boost_freq;
+};
+
enum intel_submission_method {
INTEL_SUBMISSION_RING,
INTEL_SUBMISSION_ELSP,
@@ -228,6 +234,10 @@ struct intel_gt {
/* gt/gtN sysfs */
struct kobject sysfs_gt;
+
+ /* sysfs defaults per gt */
+ struct intel_rps_defaults rps_defaults;
+ struct kobject *sysfs_defaults;
};
enum intel_gt_scratch_field {
@@ -1979,7 +1979,9 @@ void intel_rps_init(struct intel_rps *rps)
/* Derive initial user preferences/limits from the hardware limits */
rps->max_freq_softlimit = rps->max_freq;
+ rps_to_gt(rps)->rps_defaults.max_freq = rps->max_freq_softlimit;
rps->min_freq_softlimit = rps->min_freq;
+ rps_to_gt(rps)->rps_defaults.min_freq = rps->min_freq_softlimit;
/* After setting max-softlimit, find the overclock max freq */
if (GRAPHICS_VER(i915) == 6 || IS_IVYBRIDGE(i915) || IS_HASWELL(i915)) {
@@ -1997,6 +1999,7 @@ void intel_rps_init(struct intel_rps *rps)
/* Finally allow us to boost to max by default */
rps->boost_freq = rps->max_freq;
+ rps_to_gt(rps)->rps_defaults.boost_freq = rps->boost_freq;
rps->idle_freq = rps->min_freq;
/* Start in the middle, from here we will autotune based on workload */
@@ -547,20 +547,24 @@ static int slpc_set_softlimits(struct intel_guc_slpc *slpc)
* unless they have deviated from defaults, in which case,
* we retain the values and set min/max accordingly.
*/
- if (!slpc->max_freq_softlimit)
+ if (!slpc->max_freq_softlimit) {
slpc->max_freq_softlimit = slpc->rp0_freq;
- else if (slpc->max_freq_softlimit != slpc->rp0_freq)
+ slpc_to_gt(slpc)->rps_defaults.max_freq = slpc->max_freq_softlimit;
+ } else if (slpc->max_freq_softlimit != slpc->rp0_freq) {
ret = intel_guc_slpc_set_max_freq(slpc,
slpc->max_freq_softlimit);
+ }
if (unlikely(ret))
return ret;
- if (!slpc->min_freq_softlimit)
+ if (!slpc->min_freq_softlimit) {
slpc->min_freq_softlimit = slpc->min_freq;
- else if (slpc->min_freq_softlimit != slpc->min_freq)
+ slpc_to_gt(slpc)->rps_defaults.min_freq = slpc->min_freq_softlimit;
+ } else if (slpc->min_freq_softlimit != slpc->min_freq) {
return intel_guc_slpc_set_min_freq(slpc,
slpc->min_freq_softlimit);
+ }
return 0;
}
@@ -606,8 +610,11 @@ static void slpc_get_rp_values(struct intel_guc_slpc *slpc)
slpc->rp1_freq = intel_gpu_freq(rps, caps.rp1_freq);
slpc->min_freq = intel_gpu_freq(rps, caps.min_freq);
- if (!slpc->boost_freq)
+ /* Boost freq is RP0, unless already set */
+ if (!slpc->boost_freq) {
slpc->boost_freq = slpc->rp0_freq;
+ slpc_to_gt(slpc)->rps_defaults.boost_freq = slpc->boost_freq;
+ }
}
/*