2 * Copyright 2013 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
25 #include "nouveau_sysfs.h"
27 #include <core/object.h>
28 #include <core/class.h>
30 static inline struct drm_device
*
31 drm_device(struct device
*d
)
33 return pci_get_drvdata(to_pci_dev(d
));
36 #define snappendf(p,r,f,a...) do { \
37 snprintf(p, r, f, ##a); \
43 nouveau_sysfs_pstate_get(struct device
*d
, struct device_attribute
*a
, char *b
)
45 struct nouveau_sysfs
*sysfs
= nouveau_sysfs(drm_device(d
));
46 struct nv_control_pstate_info info
;
47 size_t cnt
= PAGE_SIZE
;
51 ret
= nv_exec(sysfs
->ctrl
, NV_CONTROL_PSTATE_INFO
, &info
, sizeof(info
));
55 for (i
= 0; i
< info
.count
+ 1; i
++) {
56 const s32 state
= i
< info
.count
? i
:
57 NV_CONTROL_PSTATE_ATTR_STATE_CURRENT
;
58 struct nv_control_pstate_attr attr
= {
63 ret
= nv_exec(sysfs
->ctrl
, NV_CONTROL_PSTATE_ATTR
,
69 snappendf(buf
, cnt
, "%02x:", attr
.state
);
71 snappendf(buf
, cnt
, "--:");
76 ret
= nv_exec(sysfs
->ctrl
, NV_CONTROL_PSTATE_ATTR
,
81 snappendf(buf
, cnt
, " %s %d", attr
.name
, attr
.min
);
82 if (attr
.min
!= attr
.max
)
83 snappendf(buf
, cnt
, "-%d", attr
.max
);
84 snappendf(buf
, cnt
, " %s", attr
.unit
);
87 if ((state
>= 0 && info
.pstate
== state
) ||
88 (state
< 0 && info
.ustate
< 0))
89 snappendf(buf
, cnt
, " *");
90 snappendf(buf
, cnt
, "\n");
97 nouveau_sysfs_pstate_set(struct device
*d
, struct device_attribute
*a
,
98 const char *buf
, size_t count
)
100 struct nouveau_sysfs
*sysfs
= nouveau_sysfs(drm_device(d
));
101 struct nv_control_pstate_user args
;
105 if ((tmp
= strchr(buf
, '\n')))
108 if (!strcasecmp(buf
, "none"))
109 args
.state
= NV_CONTROL_PSTATE_USER_STATE_UNKNOWN
;
111 if (!strcasecmp(buf
, "auto"))
112 args
.state
= NV_CONTROL_PSTATE_USER_STATE_PERFMON
;
114 ret
= kstrtol(buf
, 16, &value
);
120 ret
= nv_exec(sysfs
->ctrl
, NV_CONTROL_PSTATE_USER
, &args
, sizeof(args
));
127 static DEVICE_ATTR(pstate
, S_IRUGO
| S_IWUSR
,
128 nouveau_sysfs_pstate_get
, nouveau_sysfs_pstate_set
);
131 nouveau_sysfs_fini(struct drm_device
*dev
)
133 struct nouveau_sysfs
*sysfs
= nouveau_sysfs(dev
);
134 struct nouveau_drm
*drm
= nouveau_drm(dev
);
137 device_remove_file(&dev
->pdev
->dev
, &dev_attr_pstate
);
138 nouveau_object_del(nv_object(drm
), NVDRM_DEVICE
, NVDRM_CONTROL
);
146 nouveau_sysfs_init(struct drm_device
*dev
)
148 struct nouveau_drm
*drm
= nouveau_drm(dev
);
149 struct nouveau_sysfs
*sysfs
;
152 sysfs
= drm
->sysfs
= kzalloc(sizeof(*sysfs
), GFP_KERNEL
);
156 ret
= nouveau_object_new(nv_object(drm
), NVDRM_DEVICE
, NVDRM_CONTROL
,
157 NV_CONTROL_CLASS
, NULL
, 0, &sysfs
->ctrl
);
159 device_create_file(&dev
->pdev
->dev
, &dev_attr_pstate
);