diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-02-02 19:02:03 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-05-24 02:31:23 -0400 |
commit | 5f54d29ee9dace1e2ef4e8c9873ad4dd7a06d11a (patch) | |
tree | 18320c04c83f01d5c801b8a2f81dab2ce79935ee /drivers/gpu/drm | |
parent | 001a3990f6f767d364edab3c4b01a9ce4dde9cda (diff) |
drm/nva3/pm: make pll->pll mode work
This probably wants a cleanup, but I'm holding off until I know for sure
how the rest of the things that need doing fit together.
Tested on NVS300 by hacking up perflvl 1 to require PLL mode, and switching
between perflvl 3 and 1.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/nouveau/nva3_pm.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c index 0ab6d436fbd1..3a237887961e 100644 --- a/drivers/gpu/drm/nouveau/nva3_pm.c +++ b/drivers/gpu/drm/nouveau/nva3_pm.c | |||
@@ -377,10 +377,23 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec) | |||
377 | { | 377 | { |
378 | struct drm_device *dev = exec->dev; | 378 | struct drm_device *dev = exec->dev; |
379 | struct nva3_pm_state *info = exec->priv; | 379 | struct nva3_pm_state *info = exec->priv; |
380 | u32 ctrl; | ||
380 | 381 | ||
382 | ctrl = nv_rd32(dev, 0x004000); | ||
383 | if (!(ctrl & 0x00000008) && info->mclk.pll) { | ||
384 | nv_wr32(dev, 0x004000, (ctrl |= 0x00000008)); | ||
385 | nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000); | ||
386 | nv_wr32(dev, 0x004018, 0x00001000); /*XXX*/ | ||
387 | nv_wr32(dev, 0x004000, (ctrl &= ~0x00000001)); | ||
388 | nv_wr32(dev, 0x004004, info->mclk.pll); | ||
389 | nv_wr32(dev, 0x004000, (ctrl |= 0x00000001)); | ||
390 | udelay(64); | ||
391 | nv_wr32(dev, 0x004018, 0x10005000); /*XXX*/ | ||
392 | udelay(20); | ||
393 | } else | ||
381 | if (!info->mclk.pll) { | 394 | if (!info->mclk.pll) { |
382 | nv_mask(dev, 0x004168, 0x003f3040, info->mclk.clk); | 395 | nv_mask(dev, 0x004168, 0x003f3040, info->mclk.clk); |
383 | nv_mask(dev, 0x004000, 0x00000008, 0x00000008); | 396 | nv_wr32(dev, 0x004000, (ctrl |= 0x00000008)); |
384 | nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000); | 397 | nv_mask(dev, 0x1110e0, 0x00088000, 0x00088000); |
385 | nv_wr32(dev, 0x004018, 0x1000d000); /*XXX*/ | 398 | nv_wr32(dev, 0x004018, 0x1000d000); /*XXX*/ |
386 | } | 399 | } |
@@ -406,7 +419,7 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec) | |||
406 | 419 | ||
407 | if (info->mclk.pll) { | 420 | if (info->mclk.pll) { |
408 | nv_mask(dev, 0x1110e0, 0x00088000, 0x00011000); | 421 | nv_mask(dev, 0x1110e0, 0x00088000, 0x00011000); |
409 | nv_mask(dev, 0x004000, 0x00000008, 0x00000000); | 422 | nv_wr32(dev, 0x004000, (ctrl &= ~0x00000008)); |
410 | } | 423 | } |
411 | } | 424 | } |
412 | 425 | ||
@@ -477,10 +490,12 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info) | |||
477 | nv_wr32(dev, 0x004000, (ctrl |= 0x00000004)); | 490 | nv_wr32(dev, 0x004000, (ctrl |= 0x00000004)); |
478 | } | 491 | } |
479 | } else { | 492 | } else { |
480 | if (!info->mclk.pll) { | 493 | u32 ssel = 0x00000101; |
481 | nv_mask(dev, 0x004168, 0x003f3141, | 494 | if (info->mclk.clk) |
482 | 0x00000101 | info->mclk.clk); | 495 | ssel |= info->mclk.clk; |
483 | } | 496 | else |
497 | ssel |= 0x00080000; /* 324MHz, shouldn't matter... */ | ||
498 | nv_mask(dev, 0x004168, 0x003f3141, ctrl); | ||
484 | } | 499 | } |
485 | 500 | ||
486 | if (info->rammap && !(info->rammap[4] & 0x02)) | 501 | if (info->rammap && !(info->rammap[4] & 0x02)) |