aboutsummaryrefslogtreecommitdiffstats
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
parent5c6dc6575460a0afe56d8cae7666e769e08ef942 (diff)
drm/nouveau: run perflvl and M table scripts on mem clock change
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_perf.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c22
3 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 01ee63a70cc9..ef74d40d1bf1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -385,6 +385,8 @@ struct nouveau_pm_level {
385 385
386 u8 voltage; 386 u8 voltage;
387 u8 fanspeed; 387 u8 fanspeed;
388
389 u16 memscript;
388}; 390};
389 391
390struct nouveau_pm_temp_sensor_constants { 392struct nouveau_pm_temp_sensor_constants {
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 6b641b69cb77..5a95be654123 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -160,6 +160,7 @@ nouveau_perf_init(struct drm_device *dev)
160 perflvl->memory = ROM16(entry[12]) * 1000; 160 perflvl->memory = ROM16(entry[12]) * 1000;
161 break; 161 break;
162 case 0x30: 162 case 0x30:
163 perflvl->memscript = ROM16(entry[2]);
163 case 0x35: 164 case 0x35:
164 perflvl->fanspeed = entry[6]; 165 perflvl->fanspeed = entry[6];
165 perflvl->voltage = entry[7]; 166 perflvl->voltage = entry[7];
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);