aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-02-05 20:34:20 -0500
committerBen Skeggs <bskeggs@redhat.com>2012-05-24 02:31:30 -0400
commit6b91d6b056ba39633cbdf24b9973df4ac99d7130 (patch)
treee0bc270e0e4e93e160bf5d5df31f070aaa46e573
parenta1da205f4203811978ceb4721bfc3728b473bad7 (diff)
drm/nvc0/pm: enable mpll src pll, and calc mpll coefficients
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_pm.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c
index 1348f29b544d..a2f6ae0fa4bd 100644
--- a/drivers/gpu/drm/nouveau/nvc0_pm.c
+++ b/drivers/gpu/drm/nouveau/nvc0_pm.c
@@ -166,6 +166,7 @@ struct nvc0_pm_clock {
166struct nvc0_pm_state { 166struct nvc0_pm_state {
167 struct nouveau_pm_level *perflvl; 167 struct nouveau_pm_level *perflvl;
168 struct nvc0_pm_clock eng[16]; 168 struct nvc0_pm_clock eng[16];
169 struct nvc0_pm_clock mem;
169}; 170};
170 171
171static u32 172static u32
@@ -304,6 +305,48 @@ calc_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info, u32 freq)
304 return 0; 305 return 0;
305} 306}
306 307
308static int
309calc_mem(struct drm_device *dev, struct nvc0_pm_clock *info, u32 freq)
310{
311 struct pll_lims pll;
312 int N, M, P, ret;
313 u32 ctrl;
314
315 /* mclk pll input freq comes from another pll, make sure it's on */
316 ctrl = nv_rd32(dev, 0x132020);
317 if (!(ctrl & 0x00000001)) {
318 /* if not, program it to 567MHz. nfi where this value comes
319 * from - it looks like it's in the pll limits table for
320 * 132000 but the binary driver ignores all my attempts to
321 * change this value.
322 */
323 nv_wr32(dev, 0x137320, 0x00000103);
324 nv_wr32(dev, 0x137330, 0x81200606);
325 nv_wait(dev, 0x132020, 0x00010000, 0x00010000);
326 nv_wr32(dev, 0x132024, 0x0001150f);
327 nv_mask(dev, 0x132020, 0x00000001, 0x00000001);
328 nv_wait(dev, 0x137390, 0x00020000, 0x00020000);
329 nv_mask(dev, 0x132020, 0x00000004, 0x00000004);
330 }
331
332 /* for the moment, until the clock tree is better understood, use
333 * pll mode for all clock frequencies
334 */
335 ret = get_pll_limits(dev, 0x132000, &pll);
336 if (ret == 0) {
337 pll.refclk = read_pll(dev, 0x132020);
338 if (pll.refclk) {
339 ret = nva3_calc_pll(dev, &pll, freq, &N, NULL, &M, &P);
340 if (ret > 0) {
341 info->coef = (P << 16) | (N << 8) | M;
342 return 0;
343 }
344 }
345 }
346
347 return -EINVAL;
348}
349
307void * 350void *
308nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) 351nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
309{ 352{
@@ -336,6 +379,14 @@ nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
336 return ERR_PTR(ret); 379 return ERR_PTR(ret);
337 } 380 }
338 381
382 if (perflvl->memory) {
383 ret = calc_mem(dev, &info->mem, perflvl->memory);
384 if (ret) {
385 kfree(info);
386 return ERR_PTR(ret);
387 }
388 }
389
339 info->perflvl = perflvl; 390 info->perflvl = perflvl;
340 return info; 391 return info;
341} 392}