drm/nouveau/pm: add hooks to get/set *all* clocks at once
authorBen Skeggs <bskeggs@redhat.com>
Fri, 17 Jun 2011 01:25:57 +0000 (11:25 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 20 Sep 2011 06:01:45 +0000 (16:01 +1000)
This is probably better than having to tell the common code about all the
clocks that exist on every chipset.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_pm.c

index 491158d730467828d1c97b7a74a428004839e2d4..7a88d9cb2ac111a9326f236f2c2bdf769d660f09 100644 (file)
@@ -498,6 +498,11 @@ struct nouveau_pm_engine {
        void *(*clock_pre)(struct drm_device *, struct nouveau_pm_level *,
                           u32 id, int khz);
        void (*clock_set)(struct drm_device *, void *);
+
+       int  (*clocks_get)(struct drm_device *, struct nouveau_pm_level *);
+       void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *);
+       void (*clocks_set)(struct drm_device *, void *);
+
        int (*voltage_get)(struct drm_device *);
        int (*voltage_set)(struct drm_device *, int voltage);
        int (*fanspeed_get)(struct drm_device *);
index 179067a1d2610e1a93187ba6802927fb7230abd4..db68531b81149eb3a9d8b03a99c574264b861dc5 100644 (file)
@@ -72,6 +72,12 @@ nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl)
                }
        }
 
+       if (pm->clocks_pre) {
+               void *state = pm->clocks_pre(dev, perflvl);
+               if (IS_ERR(state))
+                       return PTR_ERR(state);
+               pm->clocks_set(dev, state);
+       } else
        if (pm->clock_set) {
                nouveau_pm_clock_set(dev, perflvl, PLL_CORE, perflvl->core);
                nouveau_pm_clock_set(dev, perflvl, PLL_SHADER, perflvl->shader);
@@ -124,6 +130,11 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 
        memset(perflvl, 0, sizeof(*perflvl));
 
+       if (pm->clocks_get) {
+               ret = pm->clocks_get(dev, perflvl);
+               if (ret)
+                       return ret;
+       } else
        if (pm->clock_get) {
                ret = pm->clock_get(dev, PLL_CORE);
                if (ret > 0)