diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-09-16 23:35:25 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-09-24 02:27:35 -0400 |
commit | 64f1c11a477cb76e1572ee0793234739e045b3d5 (patch) | |
tree | 155d3420728d4c5411049e64dcf61c19a3f4210a /drivers | |
parent | 6f876986bedf23b40ab707543e88fae7eac27f1f (diff) |
drm/nouveau: restore perflvl on resume, and restore boot perflvl on unload
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_pm.c | 64 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_pm.h | 1 |
3 files changed, 49 insertions, 19 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index b03bb6d5b987..f919e411e39a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "nouveau_hw.h" | 31 | #include "nouveau_hw.h" |
32 | #include "nouveau_fb.h" | 32 | #include "nouveau_fb.h" |
33 | #include "nouveau_fbcon.h" | 33 | #include "nouveau_fbcon.h" |
34 | #include "nouveau_pm.h" | ||
34 | #include "nv50_display.h" | 35 | #include "nv50_display.h" |
35 | 36 | ||
36 | #include "drm_pciids.h" | 37 | #include "drm_pciids.h" |
@@ -279,6 +280,8 @@ nouveau_pci_resume(struct pci_dev *pdev) | |||
279 | if (ret) | 280 | if (ret) |
280 | return ret; | 281 | return ret; |
281 | 282 | ||
283 | nouveau_pm_resume(dev); | ||
284 | |||
282 | if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { | 285 | if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { |
283 | ret = nouveau_mem_init_agp(dev); | 286 | ret = nouveau_mem_init_agp(dev); |
284 | if (ret) { | 287 | if (ret) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 9e8e14eb6df3..4e92d215f05d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c | |||
@@ -47,12 +47,38 @@ nouveau_pm_clock_set(struct drm_device *dev, u8 id, u32 khz) | |||
47 | } | 47 | } |
48 | 48 | ||
49 | static int | 49 | static int |
50 | nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl) | ||
51 | { | ||
52 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
53 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; | ||
54 | int ret; | ||
55 | |||
56 | if (perflvl == pm->cur) | ||
57 | return 0; | ||
58 | |||
59 | if (pm->voltage.supported && pm->voltage_set && perflvl->voltage) { | ||
60 | ret = pm->voltage_set(dev, perflvl->voltage); | ||
61 | if (ret) { | ||
62 | NV_ERROR(dev, "voltage_set %d failed: %d\n", | ||
63 | perflvl->voltage, ret); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | nouveau_pm_clock_set(dev, PLL_CORE, perflvl->core); | ||
68 | nouveau_pm_clock_set(dev, PLL_SHADER, perflvl->shader); | ||
69 | nouveau_pm_clock_set(dev, PLL_MEMORY, perflvl->memory); | ||
70 | nouveau_pm_clock_set(dev, PLL_UNK05, perflvl->unk05); | ||
71 | |||
72 | pm->cur = perflvl; | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int | ||
50 | nouveau_pm_profile_set(struct drm_device *dev, const char *profile) | 77 | nouveau_pm_profile_set(struct drm_device *dev, const char *profile) |
51 | { | 78 | { |
52 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 79 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
53 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; | 80 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; |
54 | struct nouveau_pm_level *perflvl = NULL; | 81 | struct nouveau_pm_level *perflvl = NULL; |
55 | int ret; | ||
56 | 82 | ||
57 | /* safety precaution, for now */ | 83 | /* safety precaution, for now */ |
58 | if (nouveau_perflvl_wr != 7777) | 84 | if (nouveau_perflvl_wr != 7777) |
@@ -78,25 +104,8 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile) | |||
78 | return -EINVAL; | 104 | return -EINVAL; |
79 | } | 105 | } |
80 | 106 | ||
81 | if (perflvl == pm->cur) | ||
82 | return 0; | ||
83 | |||
84 | NV_INFO(dev, "setting performance level: %s\n", profile); | 107 | NV_INFO(dev, "setting performance level: %s\n", profile); |
85 | if (pm->voltage.supported && pm->voltage_set && perflvl->voltage) { | 108 | return nouveau_pm_perflvl_set(dev, perflvl); |
86 | ret = pm->voltage_set(dev, perflvl->voltage); | ||
87 | if (ret) { | ||
88 | NV_ERROR(dev, "voltage_set %d failed: %d\n", | ||
89 | perflvl->voltage, ret); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | nouveau_pm_clock_set(dev, PLL_CORE, perflvl->core); | ||
94 | nouveau_pm_clock_set(dev, PLL_SHADER, perflvl->shader); | ||
95 | nouveau_pm_clock_set(dev, PLL_MEMORY, perflvl->memory); | ||
96 | nouveau_pm_clock_set(dev, PLL_UNK05, perflvl->unk05); | ||
97 | |||
98 | pm->cur = perflvl; | ||
99 | return 0; | ||
100 | } | 109 | } |
101 | 110 | ||
102 | static int | 111 | static int |
@@ -285,6 +294,9 @@ nouveau_pm_fini(struct drm_device *dev) | |||
285 | struct device *d = &dev->pdev->dev; | 294 | struct device *d = &dev->pdev->dev; |
286 | int i; | 295 | int i; |
287 | 296 | ||
297 | if (pm->cur != &pm->boot) | ||
298 | nouveau_pm_perflvl_set(dev, &pm->boot); | ||
299 | |||
288 | device_remove_file(d, &dev_attr_performance_level); | 300 | device_remove_file(d, &dev_attr_performance_level); |
289 | for (i = 0; i < pm->nr_perflvl; i++) { | 301 | for (i = 0; i < pm->nr_perflvl; i++) { |
290 | struct nouveau_pm_level *pl = &pm->perflvl[i]; | 302 | struct nouveau_pm_level *pl = &pm->perflvl[i]; |
@@ -299,3 +311,17 @@ nouveau_pm_fini(struct drm_device *dev) | |||
299 | nouveau_volt_fini(dev); | 311 | nouveau_volt_fini(dev); |
300 | } | 312 | } |
301 | 313 | ||
314 | void | ||
315 | nouveau_pm_resume(struct drm_device *dev) | ||
316 | { | ||
317 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
318 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; | ||
319 | struct nouveau_pm_level *perflvl; | ||
320 | |||
321 | if (pm->cur == &pm->boot) | ||
322 | return; | ||
323 | |||
324 | perflvl = pm->cur; | ||
325 | pm->cur = &pm->boot; | ||
326 | nouveau_pm_perflvl_set(dev, perflvl); | ||
327 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h index 70e1862572f8..f3de5a68c41f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.h +++ b/drivers/gpu/drm/nouveau/nouveau_pm.h | |||
@@ -28,6 +28,7 @@ | |||
28 | /* nouveau_pm.c */ | 28 | /* nouveau_pm.c */ |
29 | int nouveau_pm_init(struct drm_device *dev); | 29 | int nouveau_pm_init(struct drm_device *dev); |
30 | void nouveau_pm_fini(struct drm_device *dev); | 30 | void nouveau_pm_fini(struct drm_device *dev); |
31 | void nouveau_pm_resume(struct drm_device *dev); | ||
31 | 32 | ||
32 | /* nouveau_volt.c */ | 33 | /* nouveau_volt.c */ |
33 | void nouveau_volt_init(struct drm_device *); | 34 | void nouveau_volt_init(struct drm_device *); |