aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/aty
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/aty')
-rw-r--r--drivers/video/aty/aty128fb.c36
-rw-r--r--drivers/video/aty/atyfb_base.c20
-rw-r--r--drivers/video/aty/radeon_pm.c119
-rw-r--r--drivers/video/aty/radeonfb.h2
4 files changed, 92 insertions, 85 deletions
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index fb2b0f5b23bd..35e8eb02b9e9 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1853,13 +1853,14 @@ static void aty128_bl_exit(struct backlight_device *bd)
1853 * Initialisation 1853 * Initialisation
1854 */ 1854 */
1855 1855
1856#ifdef CONFIG_PPC_PMAC 1856#ifdef CONFIG_PPC_PMAC__disabled
1857static void aty128_early_resume(void *data) 1857static void aty128_early_resume(void *data)
1858{ 1858{
1859 struct aty128fb_par *par = data; 1859 struct aty128fb_par *par = data;
1860 1860
1861 if (try_acquire_console_sem()) 1861 if (try_acquire_console_sem())
1862 return; 1862 return;
1863 pci_restore_state(par->pdev);
1863 aty128_do_resume(par->pdev); 1864 aty128_do_resume(par->pdev);
1864 release_console_sem(); 1865 release_console_sem();
1865} 1866}
@@ -1907,7 +1908,14 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
1907 /* Indicate sleep capability */ 1908 /* Indicate sleep capability */
1908 if (par->chip_gen == rage_M3) { 1909 if (par->chip_gen == rage_M3) {
1909 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1); 1910 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1);
1911#if 0 /* Disable the early video resume hack for now as it's causing problems, among
1912 * others we now rely on the PCI core restoring the config space for us, which
1913 * isn't the case with that hack, and that code path causes various things to
1914 * be called with interrupts off while they shouldn't. I'm leaving the code in
1915 * as it can be useful for debugging purposes
1916 */
1910 pmac_set_early_video_resume(aty128_early_resume, par); 1917 pmac_set_early_video_resume(aty128_early_resume, par);
1918#endif
1911 } 1919 }
1912 1920
1913 /* Find default mode */ 1921 /* Find default mode */
@@ -2365,7 +2373,6 @@ static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx
2365static void aty128_set_suspend(struct aty128fb_par *par, int suspend) 2373static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
2366{ 2374{
2367 u32 pmgt; 2375 u32 pmgt;
2368 u16 pwr_command;
2369 struct pci_dev *pdev = par->pdev; 2376 struct pci_dev *pdev = par->pdev;
2370 2377
2371 if (!par->pm_reg) 2378 if (!par->pm_reg)
@@ -2374,6 +2381,8 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
2374 /* Set the chip into the appropriate suspend mode (we use D2, 2381 /* Set the chip into the appropriate suspend mode (we use D2,
2375 * D3 would require a complete re-initialisation of the chip, 2382 * D3 would require a complete re-initialisation of the chip,
2376 * including PCI config registers, clocks, AGP configuration, ...) 2383 * including PCI config registers, clocks, AGP configuration, ...)
2384 *
2385 * For resume, the core will have already brought us back to D0
2377 */ 2386 */
2378 if (suspend) { 2387 if (suspend) {
2379 /* Make sure CRTC2 is reset. Remove that the day we decide to 2388 /* Make sure CRTC2 is reset. Remove that the day we decide to
@@ -2391,17 +2400,9 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
2391 aty_st_le32(BUS_CNTL1, 0x00000010); 2400 aty_st_le32(BUS_CNTL1, 0x00000010);
2392 aty_st_le32(MEM_POWER_MISC, 0x0c830000); 2401 aty_st_le32(MEM_POWER_MISC, 0x0c830000);
2393 mdelay(100); 2402 mdelay(100);
2394 pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command); 2403
2395 /* Switch PCI power management to D2 */ 2404 /* Switch PCI power management to D2 */
2396 pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 2405 pci_set_power_state(pdev, PCI_D2);
2397 (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
2398 pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
2399 } else {
2400 /* Switch back PCI power management to D0 */
2401 mdelay(100);
2402 pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
2403 pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
2404 mdelay(100);
2405 } 2406 }
2406} 2407}
2407 2408
@@ -2410,6 +2411,12 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2410 struct fb_info *info = pci_get_drvdata(pdev); 2411 struct fb_info *info = pci_get_drvdata(pdev);
2411 struct aty128fb_par *par = info->par; 2412 struct aty128fb_par *par = info->par;
2412 2413
2414 /* Because we may change PCI D state ourselves, we need to
2415 * first save the config space content so the core can
2416 * restore it properly on resume.
2417 */
2418 pci_save_state(pdev);
2419
2413 /* We don't do anything but D2, for now we return 0, but 2420 /* We don't do anything but D2, for now we return 0, but
2414 * we may want to change that. How do we know if the BIOS 2421 * we may want to change that. How do we know if the BIOS
2415 * can properly take care of D3 ? Also, with swsusp, we 2422 * can properly take care of D3 ? Also, with swsusp, we
@@ -2476,6 +2483,11 @@ static int aty128_do_resume(struct pci_dev *pdev)
2476 if (pdev->dev.power.power_state.event == PM_EVENT_ON) 2483 if (pdev->dev.power.power_state.event == PM_EVENT_ON)
2477 return 0; 2484 return 0;
2478 2485
2486 /* PCI state will have been restored by the core, so
2487 * we should be in D0 now with our config space fully
2488 * restored
2489 */
2490
2479 /* Wakeup chip */ 2491 /* Wakeup chip */
2480 aty128_set_suspend(par, 0); 2492 aty128_set_suspend(par, 0);
2481 par->asleep = 0; 2493 par->asleep = 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 1d6e16d346a5..1207c208a30b 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -1978,7 +1978,7 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par)
1978 1978
1979 return timeout ? 0 : -EIO; 1979 return timeout ? 0 : -EIO;
1980} 1980}
1981#endif 1981#endif /* CONFIG_PPC_PMAC */
1982 1982
1983static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) 1983static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1984{ 1984{
@@ -2002,9 +2002,15 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2002 par->asleep = 1; 2002 par->asleep = 1;
2003 par->lock_blank = 1; 2003 par->lock_blank = 1;
2004 2004
2005 /* Because we may change PCI D state ourselves, we need to
2006 * first save the config space content so the core can
2007 * restore it properly on resume.
2008 */
2009 pci_save_state(pdev);
2010
2005#ifdef CONFIG_PPC_PMAC 2011#ifdef CONFIG_PPC_PMAC
2006 /* Set chip to "suspend" mode */ 2012 /* Set chip to "suspend" mode */
2007 if (aty_power_mgmt(1, par)) { 2013 if (machine_is(powermac) && aty_power_mgmt(1, par)) {
2008 par->asleep = 0; 2014 par->asleep = 0;
2009 par->lock_blank = 0; 2015 par->lock_blank = 0;
2010 atyfb_blank(FB_BLANK_UNBLANK, info); 2016 atyfb_blank(FB_BLANK_UNBLANK, info);
@@ -2047,11 +2053,15 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
2047 2053
2048 acquire_console_sem(); 2054 acquire_console_sem();
2049 2055
2056 /* PCI state will have been restored by the core, so
2057 * we should be in D0 now with our config space fully
2058 * restored
2059 */
2060
2050#ifdef CONFIG_PPC_PMAC 2061#ifdef CONFIG_PPC_PMAC
2051 if (pdev->dev.power.power_state.event == 2) 2062 if (machine_is(powermac) &&
2063 pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
2052 aty_power_mgmt(0, par); 2064 aty_power_mgmt(0, par);
2053#else
2054 pci_set_power_state(pdev, PCI_D0);
2055#endif 2065#endif
2056 2066
2057 aty_resume_chip(info); 2067 aty_resume_chip(info);
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index c4ac2a032fcb..c6d7cc76516f 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -2507,11 +2507,28 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
2507 2507
2508#endif /* CONFIG_PPC_OF */ 2508#endif /* CONFIG_PPC_OF */
2509 2509
2510static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend) 2510static void radeonfb_whack_power_state(struct radeonfb_info *rinfo, pci_power_t state)
2511{ 2511{
2512 u16 pwr_cmd; 2512 u16 pwr_cmd;
2513
2514 for (;;) {
2515 pci_read_config_word(rinfo->pdev,
2516 rinfo->pm_reg+PCI_PM_CTRL,
2517 &pwr_cmd);
2518 if (pwr_cmd & 2)
2519 break;
2520 pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2;
2521 pci_write_config_word(rinfo->pdev,
2522 rinfo->pm_reg+PCI_PM_CTRL,
2523 pwr_cmd);
2524 msleep(500);
2525 }
2526 rinfo->pdev->current_state = state;
2527}
2528
2529static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
2530{
2513 u32 tmp; 2531 u32 tmp;
2514 int i;
2515 2532
2516 if (!rinfo->pm_reg) 2533 if (!rinfo->pm_reg)
2517 return; 2534 return;
@@ -2557,32 +2574,19 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
2557 } 2574 }
2558 } 2575 }
2559 2576
2560 for (i = 0; i < 64; ++i)
2561 pci_read_config_dword(rinfo->pdev, i * 4,
2562 &rinfo->cfg_save[i]);
2563
2564 /* Switch PCI power management to D2. */ 2577 /* Switch PCI power management to D2. */
2565 pci_disable_device(rinfo->pdev); 2578 pci_disable_device(rinfo->pdev);
2566 for (;;) { 2579 pci_save_state(rinfo->pdev);
2567 pci_read_config_word( 2580 /* The chip seems to need us to whack the PM register
2568 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 2581 * repeatedly until it sticks. We do that -prior- to
2569 &pwr_cmd); 2582 * calling pci_set_power_state()
2570 if (pwr_cmd & 2) 2583 */
2571 break; 2584 radeonfb_whack_power_state(rinfo, PCI_D2);
2572 pci_write_config_word( 2585 pci_set_power_state(rinfo->pdev, PCI_D2);
2573 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2574 (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
2575 mdelay(500);
2576 }
2577 } else { 2586 } else {
2578 printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n", 2587 printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n",
2579 pci_name(rinfo->pdev)); 2588 pci_name(rinfo->pdev));
2580 2589
2581 /* Switch back PCI powermanagment to D0 */
2582 mdelay(200);
2583 pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
2584 mdelay(500);
2585
2586 if (rinfo->family <= CHIP_FAMILY_RV250) { 2590 if (rinfo->family <= CHIP_FAMILY_RV250) {
2587 /* Reset the SDRAM controller */ 2591 /* Reset the SDRAM controller */
2588 radeon_pm_full_reset_sdram(rinfo); 2592 radeon_pm_full_reset_sdram(rinfo);
@@ -2598,37 +2602,10 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
2598 } 2602 }
2599} 2603}
2600 2604
2601static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo)
2602{
2603 int i;
2604 static u32 radeon_cfg_after_resume[64];
2605
2606 for (i = 0; i < 64; ++i)
2607 pci_read_config_dword(rinfo->pdev, i * 4,
2608 &radeon_cfg_after_resume[i]);
2609
2610 if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4]
2611 == rinfo->cfg_save[PCI_BASE_ADDRESS_0/4])
2612 return 0; /* assume everything is ok */
2613
2614 for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) {
2615 if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i])
2616 pci_write_config_dword(rinfo->pdev, i * 4,
2617 rinfo->cfg_save[i]);
2618 }
2619 pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE,
2620 rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]);
2621 pci_write_config_word(rinfo->pdev, PCI_COMMAND,
2622 rinfo->cfg_save[PCI_COMMAND/4]);
2623 return 1;
2624}
2625
2626
2627int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) 2605int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
2628{ 2606{
2629 struct fb_info *info = pci_get_drvdata(pdev); 2607 struct fb_info *info = pci_get_drvdata(pdev);
2630 struct radeonfb_info *rinfo = info->par; 2608 struct radeonfb_info *rinfo = info->par;
2631 int i;
2632 2609
2633 if (mesg.event == pdev->dev.power.power_state.event) 2610 if (mesg.event == pdev->dev.power.power_state.event)
2634 return 0; 2611 return 0;
@@ -2674,6 +2651,11 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
2674 pmac_suspend_agp_for_card(pdev); 2651 pmac_suspend_agp_for_card(pdev);
2675#endif /* CONFIG_PPC_PMAC */ 2652#endif /* CONFIG_PPC_PMAC */
2676 2653
2654 /* It's unclear whether or when the generic code will do that, so let's
2655 * do it ourselves. We save state before we do any power management
2656 */
2657 pci_save_state(pdev);
2658
2677 /* If we support wakeup from poweroff, we save all regs we can including cfg 2659 /* If we support wakeup from poweroff, we save all regs we can including cfg
2678 * space 2660 * space
2679 */ 2661 */
@@ -2698,9 +2680,6 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
2698 mdelay(20); 2680 mdelay(20);
2699 OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON)); 2681 OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON));
2700 } 2682 }
2701 // FIXME: Use PCI layer
2702 for (i = 0; i < 64; ++i)
2703 pci_read_config_dword(pdev, i * 4, &rinfo->cfg_save[i]);
2704 pci_disable_device(pdev); 2683 pci_disable_device(pdev);
2705 } 2684 }
2706 /* If we support D2, we go to it (should be fixed later with a flag forcing 2685 /* If we support D2, we go to it (should be fixed later with a flag forcing
@@ -2717,6 +2696,13 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
2717 return 0; 2696 return 0;
2718} 2697}
2719 2698
2699static int radeon_check_power_loss(struct radeonfb_info *rinfo)
2700{
2701 return rinfo->save_regs[4] != INPLL(CLK_PIN_CNTL) ||
2702 rinfo->save_regs[2] != INPLL(MCLK_CNTL) ||
2703 rinfo->save_regs[3] != INPLL(SCLK_CNTL);
2704}
2705
2720int radeonfb_pci_resume(struct pci_dev *pdev) 2706int radeonfb_pci_resume(struct pci_dev *pdev)
2721{ 2707{
2722 struct fb_info *info = pci_get_drvdata(pdev); 2708 struct fb_info *info = pci_get_drvdata(pdev);
@@ -2735,20 +2721,13 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
2735 printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n", 2721 printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n",
2736 pci_name(pdev), pdev->dev.power.power_state.event); 2722 pci_name(pdev), pdev->dev.power.power_state.event);
2737 2723
2738 2724 /* PCI state will have been restored by the core, so
2739 if (pci_enable_device(pdev)) { 2725 * we should be in D0 now with our config space fully
2740 rc = -ENODEV; 2726 * restored
2741 printk(KERN_ERR "radeonfb (%s): can't enable PCI device !\n", 2727 */
2742 pci_name(pdev));
2743 goto bail;
2744 }
2745 pci_set_master(pdev);
2746
2747 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { 2728 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
2748 /* Wakeup chip. Check from config space if we were powered off 2729 /* Wakeup chip */
2749 * (todo: additionally, check CLK_PIN_CNTL too) 2730 if ((rinfo->pm_mode & radeon_pm_off) && radeon_check_power_loss(rinfo)) {
2750 */
2751 if ((rinfo->pm_mode & radeon_pm_off) && radeon_restore_pci_cfg(rinfo)) {
2752 if (rinfo->reinit_func != NULL) 2731 if (rinfo->reinit_func != NULL)
2753 rinfo->reinit_func(rinfo); 2732 rinfo->reinit_func(rinfo);
2754 else { 2733 else {
@@ -2807,12 +2786,13 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
2807 return rc; 2786 return rc;
2808} 2787}
2809 2788
2810#ifdef CONFIG_PPC_OF 2789#ifdef CONFIG_PPC_OF__disabled
2811static void radeonfb_early_resume(void *data) 2790static void radeonfb_early_resume(void *data)
2812{ 2791{
2813 struct radeonfb_info *rinfo = data; 2792 struct radeonfb_info *rinfo = data;
2814 2793
2815 rinfo->no_schedule = 1; 2794 rinfo->no_schedule = 1;
2795 pci_restore_state(rinfo->pdev);
2816 radeonfb_pci_resume(rinfo->pdev); 2796 radeonfb_pci_resume(rinfo->pdev);
2817 rinfo->no_schedule = 0; 2797 rinfo->no_schedule = 0;
2818} 2798}
@@ -2879,7 +2859,14 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis
2879 */ 2859 */
2880 if (rinfo->pm_mode != radeon_pm_none) { 2860 if (rinfo->pm_mode != radeon_pm_none) {
2881 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, rinfo->of_node, 0, 1); 2861 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, rinfo->of_node, 0, 1);
2862#if 0 /* Disable the early video resume hack for now as it's causing problems, among
2863 * others we now rely on the PCI core restoring the config space for us, which
2864 * isn't the case with that hack, and that code path causes various things to
2865 * be called with interrupts off while they shouldn't. I'm leaving the code in
2866 * as it can be useful for debugging purposes
2867 */
2882 pmac_set_early_video_resume(radeonfb_early_resume, rinfo); 2868 pmac_set_early_video_resume(radeonfb_early_resume, rinfo);
2869#endif
2883 } 2870 }
2884 2871
2885#if 0 2872#if 0
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 3ea1b00fdd22..7351e66c7f54 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -361,8 +361,6 @@ struct radeonfb_info {
361#ifdef CONFIG_FB_RADEON_I2C 361#ifdef CONFIG_FB_RADEON_I2C
362 struct radeon_i2c_chan i2c[4]; 362 struct radeon_i2c_chan i2c[4];
363#endif 363#endif
364
365 u32 cfg_save[64];
366}; 364};
367 365
368 366