xref: /dragonfly/sys/dev/drm/i915/i915_sysfs.c (revision 3f2dd94a)
1477eb7f9SFrançois Tigeot /*
2477eb7f9SFrançois Tigeot  * Copyright © 2012 Intel Corporation
3477eb7f9SFrançois Tigeot  *
4477eb7f9SFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining a
5477eb7f9SFrançois Tigeot  * copy of this software and associated documentation files (the "Software"),
6477eb7f9SFrançois Tigeot  * to deal in the Software without restriction, including without limitation
7477eb7f9SFrançois Tigeot  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8477eb7f9SFrançois Tigeot  * and/or sell copies of the Software, and to permit persons to whom the
9477eb7f9SFrançois Tigeot  * Software is furnished to do so, subject to the following conditions:
10477eb7f9SFrançois Tigeot  *
11477eb7f9SFrançois Tigeot  * The above copyright notice and this permission notice (including the next
12477eb7f9SFrançois Tigeot  * paragraph) shall be included in all copies or substantial portions of the
13477eb7f9SFrançois Tigeot  * Software.
14477eb7f9SFrançois Tigeot  *
15477eb7f9SFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16477eb7f9SFrançois Tigeot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17477eb7f9SFrançois Tigeot  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18477eb7f9SFrançois Tigeot  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19477eb7f9SFrançois Tigeot  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20477eb7f9SFrançois Tigeot  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21477eb7f9SFrançois Tigeot  * IN THE SOFTWARE.
22477eb7f9SFrançois Tigeot  *
23477eb7f9SFrançois Tigeot  * Authors:
24477eb7f9SFrançois Tigeot  *    Ben Widawsky <ben@bwidawsk.net>
25477eb7f9SFrançois Tigeot  *
26477eb7f9SFrançois Tigeot  */
27477eb7f9SFrançois Tigeot 
28477eb7f9SFrançois Tigeot #include <linux/device.h>
29477eb7f9SFrançois Tigeot #include <linux/module.h>
301e12ee3bSFrançois Tigeot #include <linux/stat.h>
311e12ee3bSFrançois Tigeot #include <linux/sysfs.h>
32477eb7f9SFrançois Tigeot #include "intel_drv.h"
33477eb7f9SFrançois Tigeot #include "i915_drv.h"
34477eb7f9SFrançois Tigeot 
35477eb7f9SFrançois Tigeot #if 0
361e12ee3bSFrançois Tigeot static inline struct drm_i915_private *kdev_minor_to_i915(struct device *kdev)
371e12ee3bSFrançois Tigeot {
381e12ee3bSFrançois Tigeot 	struct drm_minor *minor = dev_get_drvdata(kdev);
391e12ee3bSFrançois Tigeot 	return to_i915(minor->dev);
401e12ee3bSFrançois Tigeot }
41477eb7f9SFrançois Tigeot 
42477eb7f9SFrançois Tigeot #ifdef CONFIG_PM
431e12ee3bSFrançois Tigeot static u32 calc_residency(struct drm_i915_private *dev_priv,
44aee94f86SFrançois Tigeot 			  i915_reg_t reg)
45477eb7f9SFrançois Tigeot {
46a85cb24fSFrançois Tigeot 	return intel_rc6_residency(dev_priv, reg);
47477eb7f9SFrançois Tigeot }
48477eb7f9SFrançois Tigeot 
49477eb7f9SFrançois Tigeot static ssize_t
50477eb7f9SFrançois Tigeot show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
51477eb7f9SFrançois Tigeot {
52*3f2dd94aSFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%x\n", intel_rc6_enabled());
53477eb7f9SFrançois Tigeot }
54477eb7f9SFrançois Tigeot 
55477eb7f9SFrançois Tigeot static ssize_t
56477eb7f9SFrançois Tigeot show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
57477eb7f9SFrançois Tigeot {
581e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
591e12ee3bSFrançois Tigeot 	u32 rc6_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6);
60477eb7f9SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency);
61477eb7f9SFrançois Tigeot }
62477eb7f9SFrançois Tigeot 
63477eb7f9SFrançois Tigeot static ssize_t
64477eb7f9SFrançois Tigeot show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf)
65477eb7f9SFrançois Tigeot {
661e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
671e12ee3bSFrançois Tigeot 	u32 rc6p_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6p);
68477eb7f9SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%u\n", rc6p_residency);
69477eb7f9SFrançois Tigeot }
70477eb7f9SFrançois Tigeot 
71477eb7f9SFrançois Tigeot static ssize_t
72477eb7f9SFrançois Tigeot show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf)
73477eb7f9SFrançois Tigeot {
741e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
751e12ee3bSFrançois Tigeot 	u32 rc6pp_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6pp);
76477eb7f9SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%u\n", rc6pp_residency);
77477eb7f9SFrançois Tigeot }
78477eb7f9SFrançois Tigeot 
79477eb7f9SFrançois Tigeot static ssize_t
80477eb7f9SFrançois Tigeot show_media_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
81477eb7f9SFrançois Tigeot {
821e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
831e12ee3bSFrançois Tigeot 	u32 rc6_residency = calc_residency(dev_priv, VLV_GT_MEDIA_RC6);
84477eb7f9SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency);
85477eb7f9SFrançois Tigeot }
86477eb7f9SFrançois Tigeot 
87477eb7f9SFrançois Tigeot static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL);
88477eb7f9SFrançois Tigeot static DEVICE_ATTR(rc6_residency_ms, S_IRUGO, show_rc6_ms, NULL);
89477eb7f9SFrançois Tigeot static DEVICE_ATTR(rc6p_residency_ms, S_IRUGO, show_rc6p_ms, NULL);
90477eb7f9SFrançois Tigeot static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL);
91477eb7f9SFrançois Tigeot static DEVICE_ATTR(media_rc6_residency_ms, S_IRUGO, show_media_rc6_ms, NULL);
92477eb7f9SFrançois Tigeot 
93477eb7f9SFrançois Tigeot static struct attribute *rc6_attrs[] = {
94477eb7f9SFrançois Tigeot 	&dev_attr_rc6_enable.attr,
95477eb7f9SFrançois Tigeot 	&dev_attr_rc6_residency_ms.attr,
96477eb7f9SFrançois Tigeot 	NULL
97477eb7f9SFrançois Tigeot };
98477eb7f9SFrançois Tigeot 
99*3f2dd94aSFrançois Tigeot static const struct attribute_group rc6_attr_group = {
100477eb7f9SFrançois Tigeot 	.name = power_group_name,
101477eb7f9SFrançois Tigeot 	.attrs =  rc6_attrs
102477eb7f9SFrançois Tigeot };
103477eb7f9SFrançois Tigeot 
104477eb7f9SFrançois Tigeot static struct attribute *rc6p_attrs[] = {
105477eb7f9SFrançois Tigeot 	&dev_attr_rc6p_residency_ms.attr,
106477eb7f9SFrançois Tigeot 	&dev_attr_rc6pp_residency_ms.attr,
107477eb7f9SFrançois Tigeot 	NULL
108477eb7f9SFrançois Tigeot };
109477eb7f9SFrançois Tigeot 
110*3f2dd94aSFrançois Tigeot static const struct attribute_group rc6p_attr_group = {
111477eb7f9SFrançois Tigeot 	.name = power_group_name,
112477eb7f9SFrançois Tigeot 	.attrs =  rc6p_attrs
113477eb7f9SFrançois Tigeot };
114477eb7f9SFrançois Tigeot 
115477eb7f9SFrançois Tigeot static struct attribute *media_rc6_attrs[] = {
116477eb7f9SFrançois Tigeot 	&dev_attr_media_rc6_residency_ms.attr,
117477eb7f9SFrançois Tigeot 	NULL
118477eb7f9SFrançois Tigeot };
119477eb7f9SFrançois Tigeot 
120*3f2dd94aSFrançois Tigeot static const struct attribute_group media_rc6_attr_group = {
121477eb7f9SFrançois Tigeot 	.name = power_group_name,
122477eb7f9SFrançois Tigeot 	.attrs =  media_rc6_attrs
123477eb7f9SFrançois Tigeot };
124477eb7f9SFrançois Tigeot #endif
125477eb7f9SFrançois Tigeot 
1261e12ee3bSFrançois Tigeot static int l3_access_valid(struct drm_i915_private *dev_priv, loff_t offset)
127477eb7f9SFrançois Tigeot {
1281e12ee3bSFrançois Tigeot 	if (!HAS_L3_DPF(dev_priv))
129477eb7f9SFrançois Tigeot 		return -EPERM;
130477eb7f9SFrançois Tigeot 
131477eb7f9SFrançois Tigeot 	if (offset % 4 != 0)
132477eb7f9SFrançois Tigeot 		return -EINVAL;
133477eb7f9SFrançois Tigeot 
134477eb7f9SFrançois Tigeot 	if (offset >= GEN7_L3LOG_SIZE)
135477eb7f9SFrançois Tigeot 		return -ENXIO;
136477eb7f9SFrançois Tigeot 
137477eb7f9SFrançois Tigeot 	return 0;
138477eb7f9SFrançois Tigeot }
139477eb7f9SFrançois Tigeot 
140477eb7f9SFrançois Tigeot static ssize_t
141477eb7f9SFrançois Tigeot i915_l3_read(struct file *filp, struct kobject *kobj,
142477eb7f9SFrançois Tigeot 	     struct bin_attribute *attr, char *buf,
143477eb7f9SFrançois Tigeot 	     loff_t offset, size_t count)
144477eb7f9SFrançois Tigeot {
1451e12ee3bSFrançois Tigeot 	struct device *kdev = kobj_to_dev(kobj);
1461e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
1471e12ee3bSFrançois Tigeot 	struct drm_device *dev = &dev_priv->drm;
148477eb7f9SFrançois Tigeot 	int slice = (int)(uintptr_t)attr->private;
149477eb7f9SFrançois Tigeot 	int ret;
150477eb7f9SFrançois Tigeot 
151477eb7f9SFrançois Tigeot 	count = round_down(count, 4);
152477eb7f9SFrançois Tigeot 
1531e12ee3bSFrançois Tigeot 	ret = l3_access_valid(dev_priv, offset);
154477eb7f9SFrançois Tigeot 	if (ret)
155477eb7f9SFrançois Tigeot 		return ret;
156477eb7f9SFrançois Tigeot 
157477eb7f9SFrançois Tigeot 	count = min_t(size_t, GEN7_L3LOG_SIZE - offset, count);
158477eb7f9SFrançois Tigeot 
1591e12ee3bSFrançois Tigeot 	ret = i915_mutex_lock_interruptible(dev);
160477eb7f9SFrançois Tigeot 	if (ret)
161477eb7f9SFrançois Tigeot 		return ret;
162477eb7f9SFrançois Tigeot 
163477eb7f9SFrançois Tigeot 	if (dev_priv->l3_parity.remap_info[slice])
164477eb7f9SFrançois Tigeot 		memcpy(buf,
165477eb7f9SFrançois Tigeot 		       dev_priv->l3_parity.remap_info[slice] + (offset/4),
166477eb7f9SFrançois Tigeot 		       count);
167477eb7f9SFrançois Tigeot 	else
168477eb7f9SFrançois Tigeot 		memset(buf, 0, count);
169477eb7f9SFrançois Tigeot 
1701e12ee3bSFrançois Tigeot 	mutex_unlock(&dev->struct_mutex);
171477eb7f9SFrançois Tigeot 
172477eb7f9SFrançois Tigeot 	return count;
173477eb7f9SFrançois Tigeot }
174477eb7f9SFrançois Tigeot 
175477eb7f9SFrançois Tigeot static ssize_t
176477eb7f9SFrançois Tigeot i915_l3_write(struct file *filp, struct kobject *kobj,
177477eb7f9SFrançois Tigeot 	      struct bin_attribute *attr, char *buf,
178477eb7f9SFrançois Tigeot 	      loff_t offset, size_t count)
179477eb7f9SFrançois Tigeot {
1801e12ee3bSFrançois Tigeot 	struct device *kdev = kobj_to_dev(kobj);
1811e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
1821e12ee3bSFrançois Tigeot 	struct drm_device *dev = &dev_priv->drm;
1831487f786SFrançois Tigeot 	struct i915_gem_context *ctx;
184477eb7f9SFrançois Tigeot 	int slice = (int)(uintptr_t)attr->private;
185*3f2dd94aSFrançois Tigeot 	u32 **remap_info;
186477eb7f9SFrançois Tigeot 	int ret;
187477eb7f9SFrançois Tigeot 
1881e12ee3bSFrançois Tigeot 	ret = l3_access_valid(dev_priv, offset);
189477eb7f9SFrançois Tigeot 	if (ret)
190477eb7f9SFrançois Tigeot 		return ret;
191477eb7f9SFrançois Tigeot 
1921e12ee3bSFrançois Tigeot 	ret = i915_mutex_lock_interruptible(dev);
193477eb7f9SFrançois Tigeot 	if (ret)
194477eb7f9SFrançois Tigeot 		return ret;
195477eb7f9SFrançois Tigeot 
196*3f2dd94aSFrançois Tigeot 	remap_info = &dev_priv->l3_parity.remap_info[slice];
197*3f2dd94aSFrançois Tigeot 	if (!*remap_info) {
198*3f2dd94aSFrançois Tigeot 		*remap_info = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL);
199*3f2dd94aSFrançois Tigeot 		if (!*remap_info) {
200*3f2dd94aSFrançois Tigeot 			ret = -ENOMEM;
201*3f2dd94aSFrançois Tigeot 			goto out;
202477eb7f9SFrançois Tigeot 		}
203477eb7f9SFrançois Tigeot 	}
204477eb7f9SFrançois Tigeot 
205477eb7f9SFrançois Tigeot 	/* TODO: Ideally we really want a GPU reset here to make sure errors
206477eb7f9SFrançois Tigeot 	 * aren't propagated. Since I cannot find a stable way to reset the GPU
207477eb7f9SFrançois Tigeot 	 * at this point it is left as a TODO.
208477eb7f9SFrançois Tigeot 	*/
209*3f2dd94aSFrançois Tigeot 	memcpy(*remap_info + (offset/4), buf, count);
210477eb7f9SFrançois Tigeot 
211477eb7f9SFrançois Tigeot 	/* NB: We defer the remapping until we switch to the context */
212*3f2dd94aSFrançois Tigeot 	list_for_each_entry(ctx, &dev_priv->contexts.list, link)
213477eb7f9SFrançois Tigeot 		ctx->remap_slice |= (1<<slice);
214477eb7f9SFrançois Tigeot 
215*3f2dd94aSFrançois Tigeot 	ret = count;
216*3f2dd94aSFrançois Tigeot 
217*3f2dd94aSFrançois Tigeot out:
2181e12ee3bSFrançois Tigeot 	mutex_unlock(&dev->struct_mutex);
219477eb7f9SFrançois Tigeot 
220*3f2dd94aSFrançois Tigeot 	return ret;
221477eb7f9SFrançois Tigeot }
222477eb7f9SFrançois Tigeot 
223*3f2dd94aSFrançois Tigeot static const struct bin_attribute dpf_attrs = {
224477eb7f9SFrançois Tigeot 	.attr = {.name = "l3_parity", .mode = (S_IRUSR | S_IWUSR)},
225477eb7f9SFrançois Tigeot 	.size = GEN7_L3LOG_SIZE,
226477eb7f9SFrançois Tigeot 	.read = i915_l3_read,
227477eb7f9SFrançois Tigeot 	.write = i915_l3_write,
228477eb7f9SFrançois Tigeot 	.mmap = NULL,
229477eb7f9SFrançois Tigeot 	.private = (void *)0
230477eb7f9SFrançois Tigeot };
231477eb7f9SFrançois Tigeot 
232*3f2dd94aSFrançois Tigeot static const struct bin_attribute dpf_attrs_1 = {
233477eb7f9SFrançois Tigeot 	.attr = {.name = "l3_parity_slice_1", .mode = (S_IRUSR | S_IWUSR)},
234477eb7f9SFrançois Tigeot 	.size = GEN7_L3LOG_SIZE,
235477eb7f9SFrançois Tigeot 	.read = i915_l3_read,
236477eb7f9SFrançois Tigeot 	.write = i915_l3_write,
237477eb7f9SFrançois Tigeot 	.mmap = NULL,
238477eb7f9SFrançois Tigeot 	.private = (void *)1
239477eb7f9SFrançois Tigeot };
240477eb7f9SFrançois Tigeot 
241477eb7f9SFrançois Tigeot static ssize_t gt_act_freq_mhz_show(struct device *kdev,
242477eb7f9SFrançois Tigeot 				    struct device_attribute *attr, char *buf)
243477eb7f9SFrançois Tigeot {
2441e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
245477eb7f9SFrançois Tigeot 	int ret;
246477eb7f9SFrançois Tigeot 
247477eb7f9SFrançois Tigeot 	intel_runtime_pm_get(dev_priv);
248477eb7f9SFrançois Tigeot 
249*3f2dd94aSFrançois Tigeot 	mutex_lock(&dev_priv->pcu_lock);
250aee94f86SFrançois Tigeot 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
251477eb7f9SFrançois Tigeot 		u32 freq;
252477eb7f9SFrançois Tigeot 		freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
253477eb7f9SFrançois Tigeot 		ret = intel_gpu_freq(dev_priv, (freq >> 8) & 0xff);
254477eb7f9SFrançois Tigeot 	} else {
255477eb7f9SFrançois Tigeot 		u32 rpstat = I915_READ(GEN6_RPSTAT1);
256*3f2dd94aSFrançois Tigeot 		if (INTEL_GEN(dev_priv) >= 9)
257477eb7f9SFrançois Tigeot 			ret = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
258477eb7f9SFrançois Tigeot 		else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
259477eb7f9SFrançois Tigeot 			ret = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
260477eb7f9SFrançois Tigeot 		else
261477eb7f9SFrançois Tigeot 			ret = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
262477eb7f9SFrançois Tigeot 		ret = intel_gpu_freq(dev_priv, ret);
263477eb7f9SFrançois Tigeot 	}
264*3f2dd94aSFrançois Tigeot 	mutex_unlock(&dev_priv->pcu_lock);
265477eb7f9SFrançois Tigeot 
266477eb7f9SFrançois Tigeot 	intel_runtime_pm_put(dev_priv);
267477eb7f9SFrançois Tigeot 
268477eb7f9SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
269477eb7f9SFrançois Tigeot }
270477eb7f9SFrançois Tigeot 
271477eb7f9SFrançois Tigeot static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
272477eb7f9SFrançois Tigeot 				    struct device_attribute *attr, char *buf)
273477eb7f9SFrançois Tigeot {
2741e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
275477eb7f9SFrançois Tigeot 
27687df8fc6SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%d\n",
27787df8fc6SFrançois Tigeot 			intel_gpu_freq(dev_priv,
278*3f2dd94aSFrançois Tigeot 				       dev_priv->gt_pm.rps.cur_freq));
27987df8fc6SFrançois Tigeot }
280477eb7f9SFrançois Tigeot 
28187df8fc6SFrançois Tigeot static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
28287df8fc6SFrançois Tigeot {
2831e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
28487df8fc6SFrançois Tigeot 
28587df8fc6SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%d\n",
28687df8fc6SFrançois Tigeot 			intel_gpu_freq(dev_priv,
287*3f2dd94aSFrançois Tigeot 				       dev_priv->gt_pm.rps.boost_freq));
28887df8fc6SFrançois Tigeot }
28987df8fc6SFrançois Tigeot 
29087df8fc6SFrançois Tigeot static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
29187df8fc6SFrançois Tigeot 				       struct device_attribute *attr,
29287df8fc6SFrançois Tigeot 				       const char *buf, size_t count)
29387df8fc6SFrançois Tigeot {
2941e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
295*3f2dd94aSFrançois Tigeot 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
29687df8fc6SFrançois Tigeot 	u32 val;
29787df8fc6SFrançois Tigeot 	ssize_t ret;
29887df8fc6SFrançois Tigeot 
29987df8fc6SFrançois Tigeot 	ret = kstrtou32(buf, 0, &val);
30087df8fc6SFrançois Tigeot 	if (ret)
30187df8fc6SFrançois Tigeot 		return ret;
30287df8fc6SFrançois Tigeot 
30387df8fc6SFrançois Tigeot 	/* Validate against (static) hardware limits */
30487df8fc6SFrançois Tigeot 	val = intel_freq_opcode(dev_priv, val);
305*3f2dd94aSFrançois Tigeot 	if (val < rps->min_freq || val > rps->max_freq)
30687df8fc6SFrançois Tigeot 		return -EINVAL;
307477eb7f9SFrançois Tigeot 
308*3f2dd94aSFrançois Tigeot 	mutex_lock(&dev_priv->pcu_lock);
309*3f2dd94aSFrançois Tigeot 	rps->boost_freq = val;
310*3f2dd94aSFrançois Tigeot 	mutex_unlock(&dev_priv->pcu_lock);
311477eb7f9SFrançois Tigeot 
31287df8fc6SFrançois Tigeot 	return count;
313477eb7f9SFrançois Tigeot }
314477eb7f9SFrançois Tigeot 
315477eb7f9SFrançois Tigeot static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
316477eb7f9SFrançois Tigeot 				     struct device_attribute *attr, char *buf)
317477eb7f9SFrançois Tigeot {
3181e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
319477eb7f9SFrançois Tigeot 
32087df8fc6SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%d\n",
32187df8fc6SFrançois Tigeot 			intel_gpu_freq(dev_priv,
322*3f2dd94aSFrançois Tigeot 				       dev_priv->gt_pm.rps.efficient_freq));
323477eb7f9SFrançois Tigeot }
324477eb7f9SFrançois Tigeot 
325477eb7f9SFrançois Tigeot static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
326477eb7f9SFrançois Tigeot {
3271e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
328477eb7f9SFrançois Tigeot 
32987df8fc6SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%d\n",
33087df8fc6SFrançois Tigeot 			intel_gpu_freq(dev_priv,
331*3f2dd94aSFrançois Tigeot 				       dev_priv->gt_pm.rps.max_freq_softlimit));
332477eb7f9SFrançois Tigeot }
333477eb7f9SFrançois Tigeot 
334477eb7f9SFrançois Tigeot static ssize_t gt_max_freq_mhz_store(struct device *kdev,
335477eb7f9SFrançois Tigeot 				     struct device_attribute *attr,
336477eb7f9SFrançois Tigeot 				     const char *buf, size_t count)
337477eb7f9SFrançois Tigeot {
3381e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
339*3f2dd94aSFrançois Tigeot 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
340477eb7f9SFrançois Tigeot 	u32 val;
341477eb7f9SFrançois Tigeot 	ssize_t ret;
342477eb7f9SFrançois Tigeot 
343477eb7f9SFrançois Tigeot 	ret = kstrtou32(buf, 0, &val);
344477eb7f9SFrançois Tigeot 	if (ret)
345477eb7f9SFrançois Tigeot 		return ret;
346477eb7f9SFrançois Tigeot 
3478621f407SFrançois Tigeot 	intel_runtime_pm_get(dev_priv);
3488621f407SFrançois Tigeot 
349*3f2dd94aSFrançois Tigeot 	mutex_lock(&dev_priv->pcu_lock);
350477eb7f9SFrançois Tigeot 
351477eb7f9SFrançois Tigeot 	val = intel_freq_opcode(dev_priv, val);
352477eb7f9SFrançois Tigeot 
353*3f2dd94aSFrançois Tigeot 	if (val < rps->min_freq ||
354*3f2dd94aSFrançois Tigeot 	    val > rps->max_freq ||
355*3f2dd94aSFrançois Tigeot 	    val < rps->min_freq_softlimit) {
356*3f2dd94aSFrançois Tigeot 		mutex_unlock(&dev_priv->pcu_lock);
3578621f407SFrançois Tigeot 		intel_runtime_pm_put(dev_priv);
358477eb7f9SFrançois Tigeot 		return -EINVAL;
359477eb7f9SFrançois Tigeot 	}
360477eb7f9SFrançois Tigeot 
361*3f2dd94aSFrançois Tigeot 	if (val > rps->rp0_freq)
362477eb7f9SFrançois Tigeot 		DRM_DEBUG("User requested overclocking to %d\n",
363477eb7f9SFrançois Tigeot 			  intel_gpu_freq(dev_priv, val));
364477eb7f9SFrançois Tigeot 
365*3f2dd94aSFrançois Tigeot 	rps->max_freq_softlimit = val;
366477eb7f9SFrançois Tigeot 
367*3f2dd94aSFrançois Tigeot 	val = clamp_t(int, rps->cur_freq,
368*3f2dd94aSFrançois Tigeot 		      rps->min_freq_softlimit,
369*3f2dd94aSFrançois Tigeot 		      rps->max_freq_softlimit);
370477eb7f9SFrançois Tigeot 
371477eb7f9SFrançois Tigeot 	/* We still need *_set_rps to process the new max_delay and
372477eb7f9SFrançois Tigeot 	 * update the interrupt limits and PMINTRMSK even though
373477eb7f9SFrançois Tigeot 	 * frequency request may be unchanged. */
374a85cb24fSFrançois Tigeot 	ret = intel_set_rps(dev_priv, val);
375477eb7f9SFrançois Tigeot 
376*3f2dd94aSFrançois Tigeot 	mutex_unlock(&dev_priv->pcu_lock);
377477eb7f9SFrançois Tigeot 
3788621f407SFrançois Tigeot 	intel_runtime_pm_put(dev_priv);
3798621f407SFrançois Tigeot 
380a85cb24fSFrançois Tigeot 	return ret ?: count;
381477eb7f9SFrançois Tigeot }
382477eb7f9SFrançois Tigeot 
383477eb7f9SFrançois Tigeot static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
384477eb7f9SFrançois Tigeot {
3851e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
386477eb7f9SFrançois Tigeot 
38787df8fc6SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%d\n",
38887df8fc6SFrançois Tigeot 			intel_gpu_freq(dev_priv,
389*3f2dd94aSFrançois Tigeot 				       dev_priv->gt_pm.rps.min_freq_softlimit));
390477eb7f9SFrançois Tigeot }
391477eb7f9SFrançois Tigeot 
392477eb7f9SFrançois Tigeot static ssize_t gt_min_freq_mhz_store(struct device *kdev,
393477eb7f9SFrançois Tigeot 				     struct device_attribute *attr,
394477eb7f9SFrançois Tigeot 				     const char *buf, size_t count)
395477eb7f9SFrançois Tigeot {
3961e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
397*3f2dd94aSFrançois Tigeot 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
398477eb7f9SFrançois Tigeot 	u32 val;
399477eb7f9SFrançois Tigeot 	ssize_t ret;
400477eb7f9SFrançois Tigeot 
401477eb7f9SFrançois Tigeot 	ret = kstrtou32(buf, 0, &val);
402477eb7f9SFrançois Tigeot 	if (ret)
403477eb7f9SFrançois Tigeot 		return ret;
404477eb7f9SFrançois Tigeot 
4058621f407SFrançois Tigeot 	intel_runtime_pm_get(dev_priv);
4068621f407SFrançois Tigeot 
407*3f2dd94aSFrançois Tigeot 	mutex_lock(&dev_priv->pcu_lock);
408477eb7f9SFrançois Tigeot 
409477eb7f9SFrançois Tigeot 	val = intel_freq_opcode(dev_priv, val);
410477eb7f9SFrançois Tigeot 
411*3f2dd94aSFrançois Tigeot 	if (val < rps->min_freq ||
412*3f2dd94aSFrançois Tigeot 	    val > rps->max_freq ||
413*3f2dd94aSFrançois Tigeot 	    val > rps->max_freq_softlimit) {
414*3f2dd94aSFrançois Tigeot 		mutex_unlock(&dev_priv->pcu_lock);
4158621f407SFrançois Tigeot 		intel_runtime_pm_put(dev_priv);
416477eb7f9SFrançois Tigeot 		return -EINVAL;
417477eb7f9SFrançois Tigeot 	}
418477eb7f9SFrançois Tigeot 
419*3f2dd94aSFrançois Tigeot 	rps->min_freq_softlimit = val;
420477eb7f9SFrançois Tigeot 
421*3f2dd94aSFrançois Tigeot 	val = clamp_t(int, rps->cur_freq,
422*3f2dd94aSFrançois Tigeot 		      rps->min_freq_softlimit,
423*3f2dd94aSFrançois Tigeot 		      rps->max_freq_softlimit);
424477eb7f9SFrançois Tigeot 
425477eb7f9SFrançois Tigeot 	/* We still need *_set_rps to process the new min_delay and
426477eb7f9SFrançois Tigeot 	 * update the interrupt limits and PMINTRMSK even though
427477eb7f9SFrançois Tigeot 	 * frequency request may be unchanged. */
428a85cb24fSFrançois Tigeot 	ret = intel_set_rps(dev_priv, val);
429477eb7f9SFrançois Tigeot 
430*3f2dd94aSFrançois Tigeot 	mutex_unlock(&dev_priv->pcu_lock);
431477eb7f9SFrançois Tigeot 
4328621f407SFrançois Tigeot 	intel_runtime_pm_put(dev_priv);
4338621f407SFrançois Tigeot 
434a85cb24fSFrançois Tigeot 	return ret ?: count;
435477eb7f9SFrançois Tigeot }
436477eb7f9SFrançois Tigeot 
437477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL);
438477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL);
4394be47400SFrançois Tigeot static DEVICE_ATTR(gt_boost_freq_mhz, S_IRUGO | S_IWUSR, gt_boost_freq_mhz_show, gt_boost_freq_mhz_store);
440477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store);
441477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store);
442477eb7f9SFrançois Tigeot 
443477eb7f9SFrançois Tigeot static DEVICE_ATTR(vlv_rpe_freq_mhz, S_IRUGO, vlv_rpe_freq_mhz_show, NULL);
444477eb7f9SFrançois Tigeot 
445477eb7f9SFrançois Tigeot static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf);
446477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_RP0_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
447477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_RP1_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
448477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
449477eb7f9SFrançois Tigeot 
450477eb7f9SFrançois Tigeot /* For now we have a static number of RP states */
451477eb7f9SFrançois Tigeot static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
452477eb7f9SFrançois Tigeot {
4531e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
454*3f2dd94aSFrançois Tigeot 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
455477eb7f9SFrançois Tigeot 	u32 val;
456477eb7f9SFrançois Tigeot 
457477eb7f9SFrançois Tigeot 	if (attr == &dev_attr_gt_RP0_freq_mhz)
458*3f2dd94aSFrançois Tigeot 		val = intel_gpu_freq(dev_priv, rps->rp0_freq);
459477eb7f9SFrançois Tigeot 	else if (attr == &dev_attr_gt_RP1_freq_mhz)
460*3f2dd94aSFrançois Tigeot 		val = intel_gpu_freq(dev_priv, rps->rp1_freq);
461477eb7f9SFrançois Tigeot 	else if (attr == &dev_attr_gt_RPn_freq_mhz)
462*3f2dd94aSFrançois Tigeot 		val = intel_gpu_freq(dev_priv, rps->min_freq);
463477eb7f9SFrançois Tigeot 	else
464477eb7f9SFrançois Tigeot 		BUG();
465477eb7f9SFrançois Tigeot 
466477eb7f9SFrançois Tigeot 	return snprintf(buf, PAGE_SIZE, "%d\n", val);
467477eb7f9SFrançois Tigeot }
468477eb7f9SFrançois Tigeot 
469477eb7f9SFrançois Tigeot static const struct attribute *gen6_attrs[] = {
470477eb7f9SFrançois Tigeot 	&dev_attr_gt_act_freq_mhz.attr,
471477eb7f9SFrançois Tigeot 	&dev_attr_gt_cur_freq_mhz.attr,
47287df8fc6SFrançois Tigeot 	&dev_attr_gt_boost_freq_mhz.attr,
473477eb7f9SFrançois Tigeot 	&dev_attr_gt_max_freq_mhz.attr,
474477eb7f9SFrançois Tigeot 	&dev_attr_gt_min_freq_mhz.attr,
475477eb7f9SFrançois Tigeot 	&dev_attr_gt_RP0_freq_mhz.attr,
476477eb7f9SFrançois Tigeot 	&dev_attr_gt_RP1_freq_mhz.attr,
477477eb7f9SFrançois Tigeot 	&dev_attr_gt_RPn_freq_mhz.attr,
478477eb7f9SFrançois Tigeot 	NULL,
479477eb7f9SFrançois Tigeot };
480477eb7f9SFrançois Tigeot 
481477eb7f9SFrançois Tigeot static const struct attribute *vlv_attrs[] = {
482477eb7f9SFrançois Tigeot 	&dev_attr_gt_act_freq_mhz.attr,
483477eb7f9SFrançois Tigeot 	&dev_attr_gt_cur_freq_mhz.attr,
48487df8fc6SFrançois Tigeot 	&dev_attr_gt_boost_freq_mhz.attr,
485477eb7f9SFrançois Tigeot 	&dev_attr_gt_max_freq_mhz.attr,
486477eb7f9SFrançois Tigeot 	&dev_attr_gt_min_freq_mhz.attr,
487477eb7f9SFrançois Tigeot 	&dev_attr_gt_RP0_freq_mhz.attr,
488477eb7f9SFrançois Tigeot 	&dev_attr_gt_RP1_freq_mhz.attr,
489477eb7f9SFrançois Tigeot 	&dev_attr_gt_RPn_freq_mhz.attr,
490477eb7f9SFrançois Tigeot 	&dev_attr_vlv_rpe_freq_mhz.attr,
491477eb7f9SFrançois Tigeot 	NULL,
492477eb7f9SFrançois Tigeot };
493477eb7f9SFrançois Tigeot 
4941e12ee3bSFrançois Tigeot #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
4951e12ee3bSFrançois Tigeot 
496477eb7f9SFrançois Tigeot static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
497477eb7f9SFrançois Tigeot 				struct bin_attribute *attr, char *buf,
498477eb7f9SFrançois Tigeot 				loff_t off, size_t count)
499477eb7f9SFrançois Tigeot {
500477eb7f9SFrançois Tigeot 
501c0e85e96SFrançois Tigeot 	struct device *kdev = kobj_to_dev(kobj);
5021e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
503477eb7f9SFrançois Tigeot 	struct drm_i915_error_state_buf error_str;
504a85cb24fSFrançois Tigeot 	struct i915_gpu_state *gpu;
505a85cb24fSFrançois Tigeot 	ssize_t ret;
506477eb7f9SFrançois Tigeot 
507a85cb24fSFrançois Tigeot 	ret = i915_error_state_buf_init(&error_str, dev_priv, count, off);
508477eb7f9SFrançois Tigeot 	if (ret)
509477eb7f9SFrançois Tigeot 		return ret;
510477eb7f9SFrançois Tigeot 
511a85cb24fSFrançois Tigeot 	gpu = i915_first_error_state(dev_priv);
512a85cb24fSFrançois Tigeot 	ret = i915_error_state_to_str(&error_str, gpu);
513477eb7f9SFrançois Tigeot 	if (ret)
514477eb7f9SFrançois Tigeot 		goto out;
515477eb7f9SFrançois Tigeot 
516a85cb24fSFrançois Tigeot 	ret = count < error_str.bytes ? count : error_str.bytes;
517a85cb24fSFrançois Tigeot 	memcpy(buf, error_str.buf, ret);
518477eb7f9SFrançois Tigeot 
519477eb7f9SFrançois Tigeot out:
520a85cb24fSFrançois Tigeot 	i915_gpu_state_put(gpu);
521477eb7f9SFrançois Tigeot 	i915_error_state_buf_release(&error_str);
522477eb7f9SFrançois Tigeot 
523a85cb24fSFrançois Tigeot 	return ret;
524477eb7f9SFrançois Tigeot }
525477eb7f9SFrançois Tigeot 
526477eb7f9SFrançois Tigeot static ssize_t error_state_write(struct file *file, struct kobject *kobj,
527477eb7f9SFrançois Tigeot 				 struct bin_attribute *attr, char *buf,
528477eb7f9SFrançois Tigeot 				 loff_t off, size_t count)
529477eb7f9SFrançois Tigeot {
530c0e85e96SFrançois Tigeot 	struct device *kdev = kobj_to_dev(kobj);
5311e12ee3bSFrançois Tigeot 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
532477eb7f9SFrançois Tigeot 
533477eb7f9SFrançois Tigeot 	DRM_DEBUG_DRIVER("Resetting error state\n");
534a85cb24fSFrançois Tigeot 	i915_reset_error_state(dev_priv);
535477eb7f9SFrançois Tigeot 
536477eb7f9SFrançois Tigeot 	return count;
537477eb7f9SFrançois Tigeot }
538477eb7f9SFrançois Tigeot 
539*3f2dd94aSFrançois Tigeot static const struct bin_attribute error_state_attr = {
540477eb7f9SFrançois Tigeot 	.attr.name = "error",
541477eb7f9SFrançois Tigeot 	.attr.mode = S_IRUSR | S_IWUSR,
542477eb7f9SFrançois Tigeot 	.size = 0,
543477eb7f9SFrançois Tigeot 	.read = error_state_read,
544477eb7f9SFrançois Tigeot 	.write = error_state_write,
545477eb7f9SFrançois Tigeot };
546477eb7f9SFrançois Tigeot #endif
547477eb7f9SFrançois Tigeot 
5481e12ee3bSFrançois Tigeot static void i915_setup_error_capture(struct device *kdev)
549477eb7f9SFrançois Tigeot {
5501e12ee3bSFrançois Tigeot 	if (sysfs_create_bin_file(&kdev->kobj, &error_state_attr))
5511e12ee3bSFrançois Tigeot 		DRM_ERROR("error_state sysfs setup failed\n");
5521e12ee3bSFrançois Tigeot }
5531e12ee3bSFrançois Tigeot 
5541e12ee3bSFrançois Tigeot static void i915_teardown_error_capture(struct device *kdev)
5551e12ee3bSFrançois Tigeot {
5561e12ee3bSFrançois Tigeot 	sysfs_remove_bin_file(&kdev->kobj, &error_state_attr);
5571e12ee3bSFrançois Tigeot }
5581e12ee3bSFrançois Tigeot #else
i915_setup_error_capture(struct device * kdev)5591e12ee3bSFrançois Tigeot static void i915_setup_error_capture(struct device *kdev) {}
i915_teardown_error_capture(struct device * kdev)5601e12ee3bSFrançois Tigeot static void i915_teardown_error_capture(struct device *kdev) {}
5611e12ee3bSFrançois Tigeot #endif
5621e12ee3bSFrançois Tigeot 
i915_setup_sysfs(struct drm_i915_private * dev_priv)5631e12ee3bSFrançois Tigeot void i915_setup_sysfs(struct drm_i915_private *dev_priv)
5641e12ee3bSFrançois Tigeot {
5651e12ee3bSFrançois Tigeot 	struct device *kdev = dev_priv->drm.primary->kdev;
566477eb7f9SFrançois Tigeot #if 0
567477eb7f9SFrançois Tigeot 	int ret;
568477eb7f9SFrançois Tigeot 
569477eb7f9SFrançois Tigeot #ifdef CONFIG_PM
5701e12ee3bSFrançois Tigeot 	if (HAS_RC6(dev_priv)) {
5711e12ee3bSFrançois Tigeot 		ret = sysfs_merge_group(&kdev->kobj,
572477eb7f9SFrançois Tigeot 					&rc6_attr_group);
573477eb7f9SFrançois Tigeot 		if (ret)
574477eb7f9SFrançois Tigeot 			DRM_ERROR("RC6 residency sysfs setup failed\n");
575477eb7f9SFrançois Tigeot 	}
5761e12ee3bSFrançois Tigeot 	if (HAS_RC6p(dev_priv)) {
5771e12ee3bSFrançois Tigeot 		ret = sysfs_merge_group(&kdev->kobj,
578477eb7f9SFrançois Tigeot 					&rc6p_attr_group);
579477eb7f9SFrançois Tigeot 		if (ret)
580477eb7f9SFrançois Tigeot 			DRM_ERROR("RC6p residency sysfs setup failed\n");
581477eb7f9SFrançois Tigeot 	}
5821e12ee3bSFrançois Tigeot 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
5831e12ee3bSFrançois Tigeot 		ret = sysfs_merge_group(&kdev->kobj,
584477eb7f9SFrançois Tigeot 					&media_rc6_attr_group);
585477eb7f9SFrançois Tigeot 		if (ret)
586477eb7f9SFrançois Tigeot 			DRM_ERROR("Media RC6 residency sysfs setup failed\n");
587477eb7f9SFrançois Tigeot 	}
588477eb7f9SFrançois Tigeot #endif
5891e12ee3bSFrançois Tigeot 	if (HAS_L3_DPF(dev_priv)) {
5901e12ee3bSFrançois Tigeot 		ret = device_create_bin_file(kdev, &dpf_attrs);
591477eb7f9SFrançois Tigeot 		if (ret)
592477eb7f9SFrançois Tigeot 			DRM_ERROR("l3 parity sysfs setup failed\n");
593477eb7f9SFrançois Tigeot 
5941e12ee3bSFrançois Tigeot 		if (NUM_L3_SLICES(dev_priv) > 1) {
5951e12ee3bSFrançois Tigeot 			ret = device_create_bin_file(kdev,
596477eb7f9SFrançois Tigeot 						     &dpf_attrs_1);
597477eb7f9SFrançois Tigeot 			if (ret)
598477eb7f9SFrançois Tigeot 				DRM_ERROR("l3 parity slice 1 setup failed\n");
599477eb7f9SFrançois Tigeot 		}
600477eb7f9SFrançois Tigeot 	}
601477eb7f9SFrançois Tigeot 
602477eb7f9SFrançois Tigeot 	ret = 0;
6031e12ee3bSFrançois Tigeot 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
6041e12ee3bSFrançois Tigeot 		ret = sysfs_create_files(&kdev->kobj, vlv_attrs);
6051e12ee3bSFrançois Tigeot 	else if (INTEL_GEN(dev_priv) >= 6)
6061e12ee3bSFrançois Tigeot 		ret = sysfs_create_files(&kdev->kobj, gen6_attrs);
607477eb7f9SFrançois Tigeot 	if (ret)
608477eb7f9SFrançois Tigeot 		DRM_ERROR("RPS sysfs setup failed\n");
609477eb7f9SFrançois Tigeot 
610477eb7f9SFrançois Tigeot #endif
6111e12ee3bSFrançois Tigeot 	i915_setup_error_capture(kdev);
612477eb7f9SFrançois Tigeot }
613477eb7f9SFrançois Tigeot 
i915_teardown_sysfs(struct drm_i915_private * dev_priv)6141e12ee3bSFrançois Tigeot void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
615477eb7f9SFrançois Tigeot {
6161e12ee3bSFrançois Tigeot 	struct device *kdev = dev_priv->drm.primary->kdev;
6171e12ee3bSFrançois Tigeot 
6181e12ee3bSFrançois Tigeot 	i915_teardown_error_capture(kdev);
6191e12ee3bSFrançois Tigeot 
620477eb7f9SFrançois Tigeot #if 0
6211e12ee3bSFrançois Tigeot 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
6221e12ee3bSFrançois Tigeot 		sysfs_remove_files(&kdev->kobj, vlv_attrs);
623477eb7f9SFrançois Tigeot 	else
6241e12ee3bSFrançois Tigeot 		sysfs_remove_files(&kdev->kobj, gen6_attrs);
6251e12ee3bSFrançois Tigeot 	device_remove_bin_file(kdev,  &dpf_attrs_1);
6261e12ee3bSFrançois Tigeot 	device_remove_bin_file(kdev,  &dpf_attrs);
627477eb7f9SFrançois Tigeot #ifdef CONFIG_PM
6281e12ee3bSFrançois Tigeot 	sysfs_unmerge_group(&kdev->kobj, &rc6_attr_group);
6291e12ee3bSFrançois Tigeot 	sysfs_unmerge_group(&kdev->kobj, &rc6p_attr_group);
630477eb7f9SFrançois Tigeot #endif
631477eb7f9SFrançois Tigeot #endif
632477eb7f9SFrançois Tigeot }
633