diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-09-26 20:13:23 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-10-04 19:57:49 -0400 |
commit | aee582de806c7008756df23aa444c8e7d58004a9 (patch) | |
tree | 375bf48a622d8732ddc4681dccc9fe71505bb73d /drivers/gpu/drm/nouveau/nv50_pm.c | |
parent | 5c6dc6575460a0afe56d8cae7666e769e08ef942 (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.c | 22 |
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 | ||
35 | struct nv50_pm_state { | 36 | struct 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 | |||
98 | nv50_pm_clock_set(struct drm_device *dev, void *pre_state) | 101 | nv50_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); |