aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_pm.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-09-26 20:13:23 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-10-04 19:57:49 -0400
commitaee582de806c7008756df23aa444c8e7d58004a9 (patch)
tree375bf48a622d8732ddc4681dccc9fe71505bb73d /drivers/gpu/drm/nouveau/nv50_pm.c
parent5c6dc6575460a0afe56d8cae7666e769e08ef942 (diff)
drm/nouveau: run perflvl and M table scripts on mem clock change
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_pm.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
index eaf69c83ce92..2a9fabdf1b75 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -24,6 +24,7 @@
24 24
25#include "drmP.h" 25#include "drmP.h"
26#include "nouveau_drv.h" 26#include "nouveau_drv.h"
27#include "nouveau_bios.h"
27#include "nouveau_pm.h" 28#include "nouveau_pm.h"
28 29
29/*XXX: boards using limits 0x40 need fixing, the register layout 30/*XXX: boards using limits 0x40 need fixing, the register layout
@@ -33,6 +34,7 @@
33 */ 34 */
34 35
35struct nv50_pm_state { 36struct nv50_pm_state {
37 struct nouveau_pm_level *perflvl;
36 struct pll_lims pll; 38 struct pll_lims pll;
37 enum pll_types type; 39 enum pll_types type;
38 int N, M, P; 40 int N, M, P;
@@ -77,6 +79,7 @@ nv50_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl,
77 if (!state) 79 if (!state)
78 return ERR_PTR(-ENOMEM); 80 return ERR_PTR(-ENOMEM);
79 state->type = id; 81 state->type = id;
82 state->perflvl = perflvl;
80 83
81 ret = get_pll_limits(dev, id, &state->pll); 84 ret = get_pll_limits(dev, id, &state->pll);
82 if (ret < 0) { 85 if (ret < 0) {
@@ -98,11 +101,30 @@ void
98nv50_pm_clock_set(struct drm_device *dev, void *pre_state) 101nv50_pm_clock_set(struct drm_device *dev, void *pre_state)
99{ 102{
100 struct nv50_pm_state *state = pre_state; 103 struct nv50_pm_state *state = pre_state;
104 struct nouveau_pm_level *perflvl = state->perflvl;
101 u32 reg = state->pll.reg, tmp; 105 u32 reg = state->pll.reg, tmp;
106 struct bit_entry BIT_M;
107 u16 script;
102 int N = state->N; 108 int N = state->N;
103 int M = state->M; 109 int M = state->M;
104 int P = state->P; 110 int P = state->P;
105 111
112 if (state->type == PLL_MEMORY && perflvl->memscript &&
113 bit_table(dev, 'M', &BIT_M) == 0 &&
114 BIT_M.version == 1 && BIT_M.length >= 0x0b) {
115 script = ROM16(BIT_M.data[0x05]);
116 if (script)
117 nouveau_bios_run_init_table(dev, script, NULL);
118 script = ROM16(BIT_M.data[0x07]);
119 if (script)
120 nouveau_bios_run_init_table(dev, script, NULL);
121 script = ROM16(BIT_M.data[0x09]);
122 if (script)
123 nouveau_bios_run_init_table(dev, script, NULL);
124
125 nouveau_bios_run_init_table(dev, perflvl->memscript, NULL);
126 }
127
106 if (state->pll.vco2.maxfreq) { 128 if (state->pll.vco2.maxfreq) {
107 if (state->type == PLL_MEMORY) { 129 if (state->type == PLL_MEMORY) {
108 nv_wr32(dev, 0x100210, 0); 130 nv_wr32(dev, 0x100210, 0);