aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-01-24 18:03:25 +1000
committerBen Skeggs <bskeggs@redhat.com>2012-03-13 17:09:11 +1000
commit25c53c1068a804c6b51f86e937cebab6274dc056 (patch)
treefc52ae0515b86341801b19940d070bdaa4c98924
parent8d7bb400638906075c38cb07891993cf95076aa7 (diff)
drm/nouveau/pm: extend profile interface for destroy/init/fini
Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Martin Peres <martin.peres@labri.fr>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c21
2 files changed, 25 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 009089e093f..63e77fc282f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -487,6 +487,9 @@ struct nouveau_pm_tbl_entry {
struct nouveau_pm_profile;
struct nouveau_pm_profile_func {
+ void (*destroy)(struct nouveau_pm_profile *);
+ void (*init)(struct nouveau_pm_profile *);
+ void (*fini)(struct nouveau_pm_profile *);
struct nouveau_pm_level *(*select)(struct nouveau_pm_profile *);
};
@@ -556,6 +559,7 @@ struct nouveau_pm_engine {
struct nouveau_pm_profile *profile_ac;
struct nouveau_pm_profile *profile_dc;
+ struct nouveau_pm_profile *profile;
struct list_head profiles;
struct nouveau_pm_level boot;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 4fff09e3f59..dcc16927716 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -183,6 +183,12 @@ nouveau_pm_trigger(struct drm_device *dev)
else
profile = pm->profile_dc;
+ if (profile != pm->profile) {
+ pm->profile->func->fini(pm->profile);
+ pm->profile = profile;
+ pm->profile->func->init(pm->profile);
+ }
+
/* select performance level based on profile */
perflvl = profile->func->select(profile);
@@ -251,6 +257,11 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile)
return 0;
}
+static void
+nouveau_pm_static_dummy(struct nouveau_pm_profile *profile)
+{
+}
+
static struct nouveau_pm_level *
nouveau_pm_static_select(struct nouveau_pm_profile *profile)
{
@@ -258,6 +269,9 @@ nouveau_pm_static_select(struct nouveau_pm_profile *profile)
}
const struct nouveau_pm_profile_func nouveau_pm_static_profile_func = {
+ .destroy = nouveau_pm_static_dummy,
+ .init = nouveau_pm_static_dummy,
+ .fini = nouveau_pm_static_dummy,
.select = nouveau_pm_static_select,
};
@@ -856,6 +870,7 @@ nouveau_pm_init(struct drm_device *dev)
pm->profile_ac = &pm->boot.profile;
pm->profile_dc = &pm->boot.profile;
+ pm->profile = &pm->boot.profile;
pm->cur = &pm->boot;
/* add performance levels from vbios */
@@ -893,6 +908,12 @@ nouveau_pm_fini(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm_profile *profile, *tmp;
+
+ list_for_each_entry_safe(profile, tmp, &pm->profiles, head) {
+ list_del(&profile->head);
+ profile->func->destroy(profile);
+ }
if (pm->cur != &pm->boot)
nouveau_pm_perflvl_set(dev, &pm->boot);