aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv04_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv04_pm.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv04_pm.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c
index 76b5340603a9..410be011c2f0 100644
--- a/drivers/gpu/drm/nouveau/nv04_pm.c
+++ b/drivers/gpu/drm/nouveau/nv04_pm.c
@@ -23,10 +23,15 @@
23 */ 23 */
24 24
25#include "drmP.h" 25#include "drmP.h"
26#include "nouveau_drv.h" 26#include "nouveau_drm.h"
27#include "nouveau_reg.h"
27#include "nouveau_hw.h" 28#include "nouveau_hw.h"
28#include "nouveau_pm.h" 29#include "nouveau_pm.h"
29 30
31#include <subdev/bios/pll.h>
32#include <subdev/clock.h>
33#include <subdev/timer.h>
34
30int 35int
31nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) 36nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
32{ 37{
@@ -58,13 +63,16 @@ struct nv04_pm_state {
58static int 63static int
59calc_pll(struct drm_device *dev, u32 id, int khz, struct nv04_pm_clock *clk) 64calc_pll(struct drm_device *dev, u32 id, int khz, struct nv04_pm_clock *clk)
60{ 65{
66 struct nouveau_device *device = nouveau_dev(dev);
67 struct nouveau_bios *bios = nouveau_bios(device);
68 struct nouveau_clock *pclk = nouveau_clock(device);
61 int ret; 69 int ret;
62 70
63 ret = get_pll_limits(dev, id, &clk->pll); 71 ret = nvbios_pll_parse(bios, id, &clk->pll);
64 if (ret) 72 if (ret)
65 return ret; 73 return ret;
66 74
67 ret = nouveau_calc_pll_mnp(dev, &clk->pll, khz, &clk->calc); 75 ret = pclk->pll_calc(pclk, &clk->pll, khz, &clk->calc);
68 if (!ret) 76 if (!ret)
69 return -EINVAL; 77 return -EINVAL;
70 78
@@ -100,38 +108,38 @@ error:
100static void 108static void
101prog_pll(struct drm_device *dev, struct nv04_pm_clock *clk) 109prog_pll(struct drm_device *dev, struct nv04_pm_clock *clk)
102{ 110{
103 struct drm_nouveau_private *dev_priv = dev->dev_private; 111 struct nouveau_device *device = nouveau_dev(dev);
112 struct nouveau_clock *pclk = nouveau_clock(device);
104 u32 reg = clk->pll.reg; 113 u32 reg = clk->pll.reg;
105 114
106 /* thank the insane nouveau_hw_setpll() interface for this */ 115 /* thank the insane nouveau_hw_setpll() interface for this */
107 if (dev_priv->card_type >= NV_40) 116 if (device->card_type >= NV_40)
108 reg += 4; 117 reg += 4;
109 118
110 nouveau_hw_setpll(dev, reg, &clk->calc); 119 pclk->pll_prog(pclk, reg, &clk->calc);
111} 120}
112 121
113int 122int
114nv04_pm_clocks_set(struct drm_device *dev, void *pre_state) 123nv04_pm_clocks_set(struct drm_device *dev, void *pre_state)
115{ 124{
116 struct drm_nouveau_private *dev_priv = dev->dev_private; 125 struct nouveau_device *device = nouveau_dev(dev);
126 struct nouveau_timer *ptimer = nouveau_timer(device);
117 struct nv04_pm_state *state = pre_state; 127 struct nv04_pm_state *state = pre_state;
118 128
119 prog_pll(dev, &state->core); 129 prog_pll(dev, &state->core);
120 130
121 if (state->memory.pll.reg) { 131 if (state->memory.pll.reg) {
122 prog_pll(dev, &state->memory); 132 prog_pll(dev, &state->memory);
123 if (dev_priv->card_type < NV_30) { 133 if (device->card_type < NV_30) {
124 if (dev_priv->card_type == NV_20) 134 if (device->card_type == NV_20)
125 nv_mask(dev, 0x1002c4, 0, 1 << 20); 135 nv_mask(device, 0x1002c4, 0, 1 << 20);
126 136
127 /* Reset the DLLs */ 137 /* Reset the DLLs */
128 nv_mask(dev, 0x1002c0, 0, 1 << 8); 138 nv_mask(device, 0x1002c0, 0, 1 << 8);
129 } 139 }
130 } 140 }
131 141
132#if 0 /*XXX*/ 142 nv_ofuncs(ptimer)->init(nv_object(ptimer));
133 ptimer->init(dev);
134#endif
135 143
136 kfree(state); 144 kfree(state);
137 return 0; 145 return 0;