diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-04-16 18:24:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:24:19 -0400 |
commit | 0c541b4406a68e74d94ddb667c69d9e03bce8681 (patch) | |
tree | 869506b6c3f7c00ac13f2aa80c35fb5e229cc329 /drivers/video/aty | |
parent | 7a648b9ec09f32606fe0f27fb9d095311cf968ca (diff) |
[PATCH] ppc32: Fix AGP and sleep again
My previous patch that added sleep support for uninorth-agp and some AGP
"off" stuff in radeonfb and aty128fb is breaking some configs. More
specifically, it has problems with rage128 setups since the DRI code for
these in X doesn't properly re-enable AGP on wakeup or console switch
(unlike the radeon DRM).
This patch fixes the problem for pmac once for all by using a different
approach. The AGP driver "registers" special suspend/resume callbacks with
some arch code that the fbdev's can later on call to suspend and resume
AGP, making sure it's resumed back in the same state it was when suspended.
This is platform specific for now. It would be too complicated to try to
do a generic implementation of this at this point due to all sort of weird
things going on with AGP on other architectures. We'll re-work that whole
problem cleanly once we finally merge fbdev's and DRI.
In the meantime, please apply this patch which brings back some r128 based
laptops into working condition as far as system sleep is concerned.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/aty')
-rw-r--r-- | drivers/video/aty/aty128fb.c | 34 | ||||
-rw-r--r-- | drivers/video/aty/radeon_pm.c | 43 |
2 files changed, 29 insertions, 48 deletions
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 8a4ba3bb9872..9789115980a5 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -2331,7 +2331,6 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2331 | { | 2331 | { |
2332 | struct fb_info *info = pci_get_drvdata(pdev); | 2332 | struct fb_info *info = pci_get_drvdata(pdev); |
2333 | struct aty128fb_par *par = info->par; | 2333 | struct aty128fb_par *par = info->par; |
2334 | u8 agp; | ||
2335 | 2334 | ||
2336 | /* We don't do anything but D2, for now we return 0, but | 2335 | /* We don't do anything but D2, for now we return 0, but |
2337 | * we may want to change that. How do we know if the BIOS | 2336 | * we may want to change that. How do we know if the BIOS |
@@ -2369,26 +2368,13 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2369 | par->asleep = 1; | 2368 | par->asleep = 1; |
2370 | par->lock_blank = 1; | 2369 | par->lock_blank = 1; |
2371 | 2370 | ||
2372 | /* Disable AGP. The AGP host should have done it, but since ordering | 2371 | #ifdef CONFIG_PPC_PMAC |
2373 | * isn't always properly guaranteed in this specific case, let's make | 2372 | /* On powermac, we have hooks to properly suspend/resume AGP now, |
2374 | * sure it's disabled on card side now. Ultimately, when merging fbdev | 2373 | * use them here. We'll ultimately need some generic support here, |
2375 | * and dri into some common infrastructure, this will be handled | 2374 | * but the generic code isn't quite ready for that yet |
2376 | * more nicely. The host bridge side will (or will not) be dealt with | ||
2377 | * by the bridge AGP driver, we don't attempt to touch it here. | ||
2378 | */ | 2375 | */ |
2379 | agp = pci_find_capability(pdev, PCI_CAP_ID_AGP); | 2376 | pmac_suspend_agp_for_card(pdev); |
2380 | if (agp) { | 2377 | #endif /* CONFIG_PPC_PMAC */ |
2381 | u32 cmd; | ||
2382 | |||
2383 | pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd); | ||
2384 | if (cmd & PCI_AGP_COMMAND_AGP) { | ||
2385 | printk(KERN_INFO "aty128fb: AGP was enabled, " | ||
2386 | "disabling ...\n"); | ||
2387 | cmd &= ~PCI_AGP_COMMAND_AGP; | ||
2388 | pci_write_config_dword(pdev, agp + PCI_AGP_COMMAND, | ||
2389 | cmd); | ||
2390 | } | ||
2391 | } | ||
2392 | 2378 | ||
2393 | /* We need a way to make sure the fbdev layer will _not_ touch the | 2379 | /* We need a way to make sure the fbdev layer will _not_ touch the |
2394 | * framebuffer before we put the chip to suspend state. On 2.4, I | 2380 | * framebuffer before we put the chip to suspend state. On 2.4, I |
@@ -2432,6 +2418,14 @@ static int aty128_do_resume(struct pci_dev *pdev) | |||
2432 | par->lock_blank = 0; | 2418 | par->lock_blank = 0; |
2433 | aty128fb_blank(0, info); | 2419 | aty128fb_blank(0, info); |
2434 | 2420 | ||
2421 | #ifdef CONFIG_PPC_PMAC | ||
2422 | /* On powermac, we have hooks to properly suspend/resume AGP now, | ||
2423 | * use them here. We'll ultimately need some generic support here, | ||
2424 | * but the generic code isn't quite ready for that yet | ||
2425 | */ | ||
2426 | pmac_resume_agp_for_card(pdev); | ||
2427 | #endif /* CONFIG_PPC_PMAC */ | ||
2428 | |||
2435 | pdev->dev.power.power_state = PMSG_ON; | 2429 | pdev->dev.power.power_state = PMSG_ON; |
2436 | 2430 | ||
2437 | printk(KERN_DEBUG "aty128fb: resumed !\n"); | 2431 | printk(KERN_DEBUG "aty128fb: resumed !\n"); |
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 23c677e5093f..98352af39325 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c | |||
@@ -2520,13 +2520,10 @@ static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo) | |||
2520 | } | 2520 | } |
2521 | 2521 | ||
2522 | 2522 | ||
2523 | static/*extern*/ int susdisking = 0; | ||
2524 | |||
2525 | int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 2523 | int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
2526 | { | 2524 | { |
2527 | struct fb_info *info = pci_get_drvdata(pdev); | 2525 | struct fb_info *info = pci_get_drvdata(pdev); |
2528 | struct radeonfb_info *rinfo = info->par; | 2526 | struct radeonfb_info *rinfo = info->par; |
2529 | u8 agp; | ||
2530 | int i; | 2527 | int i; |
2531 | 2528 | ||
2532 | if (state == pdev->dev.power.power_state) | 2529 | if (state == pdev->dev.power.power_state) |
@@ -2542,11 +2539,6 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2542 | */ | 2539 | */ |
2543 | if (state != PM_SUSPEND_MEM) | 2540 | if (state != PM_SUSPEND_MEM) |
2544 | goto done; | 2541 | goto done; |
2545 | if (susdisking) { | ||
2546 | printk("radeonfb (%s): suspending to disk but state = %d\n", | ||
2547 | pci_name(pdev), state); | ||
2548 | goto done; | ||
2549 | } | ||
2550 | 2542 | ||
2551 | acquire_console_sem(); | 2543 | acquire_console_sem(); |
2552 | 2544 | ||
@@ -2567,27 +2559,13 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2567 | rinfo->lock_blank = 1; | 2559 | rinfo->lock_blank = 1; |
2568 | del_timer_sync(&rinfo->lvds_timer); | 2560 | del_timer_sync(&rinfo->lvds_timer); |
2569 | 2561 | ||
2570 | /* Disable AGP. The AGP host should have done it, but since ordering | 2562 | #ifdef CONFIG_PPC_PMAC |
2571 | * isn't always properly guaranteed in this specific case, let's make | 2563 | /* On powermac, we have hooks to properly suspend/resume AGP now, |
2572 | * sure it's disabled on card side now. Ultimately, when merging fbdev | 2564 | * use them here. We'll ultimately need some generic support here, |
2573 | * and dri into some common infrastructure, this will be handled | 2565 | * but the generic code isn't quite ready for that yet |
2574 | * more nicely. The host bridge side will (or will not) be dealt with | ||
2575 | * by the bridge AGP driver, we don't attempt to touch it here. | ||
2576 | */ | 2566 | */ |
2577 | agp = pci_find_capability(pdev, PCI_CAP_ID_AGP); | 2567 | pmac_suspend_agp_for_card(pdev); |
2578 | if (agp) { | 2568 | #endif /* CONFIG_PPC_PMAC */ |
2579 | u32 cmd; | ||
2580 | |||
2581 | pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd); | ||
2582 | if (cmd & PCI_AGP_COMMAND_AGP) { | ||
2583 | printk(KERN_INFO "radeonfb (%s): AGP was enabled, " | ||
2584 | "disabling ...\n", | ||
2585 | pci_name(pdev)); | ||
2586 | cmd &= ~PCI_AGP_COMMAND_AGP; | ||
2587 | pci_write_config_dword(pdev, agp + PCI_AGP_COMMAND, | ||
2588 | cmd); | ||
2589 | } | ||
2590 | } | ||
2591 | 2569 | ||
2592 | /* If we support wakeup from poweroff, we save all regs we can including cfg | 2570 | /* If we support wakeup from poweroff, we save all regs we can including cfg |
2593 | * space | 2571 | * space |
@@ -2699,6 +2677,15 @@ int radeonfb_pci_resume(struct pci_dev *pdev) | |||
2699 | rinfo->lock_blank = 0; | 2677 | rinfo->lock_blank = 0; |
2700 | radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 1); | 2678 | radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 1); |
2701 | 2679 | ||
2680 | #ifdef CONFIG_PPC_PMAC | ||
2681 | /* On powermac, we have hooks to properly suspend/resume AGP now, | ||
2682 | * use them here. We'll ultimately need some generic support here, | ||
2683 | * but the generic code isn't quite ready for that yet | ||
2684 | */ | ||
2685 | pmac_resume_agp_for_card(pdev); | ||
2686 | #endif /* CONFIG_PPC_PMAC */ | ||
2687 | |||
2688 | |||
2702 | /* Check status of dynclk */ | 2689 | /* Check status of dynclk */ |
2703 | if (rinfo->dynclk == 1) | 2690 | if (rinfo->dynclk == 1) |
2704 | radeon_pm_enable_dynamic_mode(rinfo); | 2691 | radeon_pm_enable_dynamic_mode(rinfo); |