diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/nva3_pm.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c index 98588292c802..c9a1f63d1c93 100644 --- a/drivers/gpu/drm/nouveau/nva3_pm.c +++ b/drivers/gpu/drm/nouveau/nva3_pm.c | |||
@@ -360,14 +360,12 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec) | |||
360 | u32 freq = perflvl->memory; | 360 | u32 freq = perflvl->memory; |
361 | u8 *rammap, *ramcfg, ver, hdr, cnt, len; | 361 | u8 *rammap, *ramcfg, ver, hdr, cnt, len; |
362 | 362 | ||
363 | nv_wr32(dev, 0x004018, 0x00001000); | 363 | if (!info->mclk.pll) { |
364 | 364 | nv_mask(dev, 0x004168, 0x003f3040, info->mclk.clk); | |
365 | prog_pll(dev, 0x02, 0x004000, &info->mclk); | 365 | nv_mask(dev, 0x004000, 0x00000008, 0x00000008); |
366 | 366 | nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000); | |
367 | if (nv_rd32(dev, 0x4000) & 0x00000008) | 367 | nv_wr32(dev, 0x004018, 0x1000d000); /*XXX*/ |
368 | nv_wr32(dev, 0x004018, 0x1000d000); | 368 | } |
369 | else | ||
370 | nv_wr32(dev, 0x004018, 0x10005000); | ||
371 | 369 | ||
372 | rammap = nouveau_perf_rammap(dev, freq, &ver, &hdr, &cnt, &len); | 370 | rammap = nouveau_perf_rammap(dev, freq, &ver, &hdr, &cnt, &len); |
373 | if (rammap && ver == 0x10 && hdr >= 5) { | 371 | if (rammap && ver == 0x10 && hdr >= 5) { |
@@ -388,6 +386,11 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec) | |||
388 | nv_mask(dev, 0x10f804, 0x80000000, 0x00000000); | 386 | nv_mask(dev, 0x10f804, 0x80000000, 0x00000000); |
389 | } | 387 | } |
390 | } | 388 | } |
389 | |||
390 | if (info->mclk.pll) { | ||
391 | nv_mask(dev, 0x1110e0, 0x00088000, 0x00011000); | ||
392 | nv_mask(dev, 0x004000, 0x00000008, 0x00000000); | ||
393 | } | ||
391 | } | 394 | } |
392 | 395 | ||
393 | static void | 396 | static void |
@@ -439,10 +442,39 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info) | |||
439 | .timing_set = mclk_timing_set, | 442 | .timing_set = mclk_timing_set, |
440 | .priv = info | 443 | .priv = info |
441 | }; | 444 | }; |
445 | u32 ctrl; | ||
446 | |||
447 | ctrl = nv_rd32(dev, 0x004000); | ||
448 | if (ctrl & 0x00000008) { | ||
449 | if (info->mclk.pll) { | ||
450 | nv_mask(dev, 0x004128, 0x00000101, 0x00000101); | ||
451 | nv_wr32(dev, 0x004004, info->mclk.pll); | ||
452 | nv_wr32(dev, 0x004000, (ctrl |= 0x00000001)); | ||
453 | nv_wr32(dev, 0x004000, (ctrl &= 0xffffffef)); | ||
454 | nv_wait(dev, 0x004000, 0x00020000, 0x00020000); | ||
455 | nv_wr32(dev, 0x004000, (ctrl |= 0x00000010)); | ||
456 | nv_wr32(dev, 0x004018, 0x00005000); /*XXX*/ | ||
457 | nv_wr32(dev, 0x004000, (ctrl |= 0x00000004)); | ||
458 | } | ||
459 | } else { | ||
460 | if (!info->mclk.pll) { | ||
461 | nv_mask(dev, 0x004168, 0x003f3141, | ||
462 | 0x00000101 | info->mclk.clk); | ||
463 | } | ||
464 | } | ||
442 | 465 | ||
443 | nv_wr32(dev, 0x611200, 0x00003300); | 466 | nv_wr32(dev, 0x611200, 0x00003300); |
444 | nouveau_mem_exec(&exec, info->perflvl); | 467 | nouveau_mem_exec(&exec, info->perflvl); |
445 | nv_wr32(dev, 0x611200, 0x00003330); | 468 | nv_wr32(dev, 0x611200, 0x00003330); |
469 | |||
470 | if (info->mclk.pll) { | ||
471 | nv_mask(dev, 0x004168, 0x00000001, 0x00000000); | ||
472 | nv_mask(dev, 0x004168, 0x00000100, 0x00000000); | ||
473 | } else { | ||
474 | nv_mask(dev, 0x004000, 0x00000001, 0x00000000); | ||
475 | nv_mask(dev, 0x004128, 0x00000001, 0x00000000); | ||
476 | nv_mask(dev, 0x004128, 0x00000100, 0x00000000); | ||
477 | } | ||
446 | } | 478 | } |
447 | 479 | ||
448 | int | 480 | int |