linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / video / aty / radeon_pm.c
index f31e606..1f8d805 100644 (file)
 #include <linux/agp_backend.h>
 
 #ifdef CONFIG_PPC_PMAC
-#include <asm/machdep.h>
+#include <asm/processor.h>
 #include <asm/prom.h>
 #include <asm/pmac_feature.h>
 #endif
 
 #include "ati_ids.h"
 
-static void radeon_reinitialize_M10(struct radeonfb_info *rinfo);
-
-/*
- * Workarounds for bugs in PC laptops:
- * - enable D2 sleep in some IBM Thinkpads
- * - special case for Samsung P35
- *
- * Whitelist by subsystem vendor/device because
- * its the subsystem vendor's fault!
- */
-
-#if defined(CONFIG_PM) && defined(CONFIG_X86)
-struct radeon_device_id {
-        const char *ident;                     /* (arbitrary) Name */
-        const unsigned short subsystem_vendor; /* Subsystem Vendor ID */
-        const unsigned short subsystem_device; /* Subsystem Device ID */
-       const enum radeon_pm_mode pm_mode_modifier; /* modify pm_mode */
-       const reinit_function_ptr new_reinit_func;   /* changed reinit_func */
-};
-
-#define BUGFIX(model, sv, sd, pm, fn) { \
-       .ident = model, \
-       .subsystem_vendor = sv, \
-       .subsystem_device = sd, \
-       .pm_mode_modifier = pm, \
-       .new_reinit_func  = fn  \
-}
-
-static struct radeon_device_id radeon_workaround_list[] = {
-       BUGFIX("IBM Thinkpad R32",
-              PCI_VENDOR_ID_IBM, 0x1905,
-              radeon_pm_d2, NULL),
-       BUGFIX("IBM Thinkpad R40",
-              PCI_VENDOR_ID_IBM, 0x0526,
-              radeon_pm_d2, NULL),
-       BUGFIX("IBM Thinkpad R40",
-              PCI_VENDOR_ID_IBM, 0x0527,
-              radeon_pm_d2, NULL),
-       BUGFIX("IBM Thinkpad R50/R51/T40/T41",
-              PCI_VENDOR_ID_IBM, 0x0531,
-              radeon_pm_d2, NULL),
-       BUGFIX("IBM Thinkpad R51/T40/T41/T42",
-              PCI_VENDOR_ID_IBM, 0x0530,
-              radeon_pm_d2, NULL),
-       BUGFIX("IBM Thinkpad T30",
-              PCI_VENDOR_ID_IBM, 0x0517,
-              radeon_pm_d2, NULL),
-       BUGFIX("IBM Thinkpad T40p",
-              PCI_VENDOR_ID_IBM, 0x054d,
-              radeon_pm_d2, NULL),
-       BUGFIX("IBM Thinkpad T42",
-              PCI_VENDOR_ID_IBM, 0x0550,
-              radeon_pm_d2, NULL),
-       BUGFIX("IBM Thinkpad X31/X32",
-              PCI_VENDOR_ID_IBM, 0x052f,
-              radeon_pm_d2, NULL),
-       BUGFIX("Samsung P35",
-              PCI_VENDOR_ID_SAMSUNG, 0xc00c,
-              radeon_pm_off, radeon_reinitialize_M10),
-       { .ident = NULL }
-};
-
-static int radeon_apply_workarounds(struct radeonfb_info *rinfo)
-{
-       struct radeon_device_id *id;
-
-       for (id = radeon_workaround_list; id->ident != NULL; id++ )
-               if ((id->subsystem_vendor == rinfo->pdev->subsystem_vendor ) &&
-                   (id->subsystem_device == rinfo->pdev->subsystem_device )) {
-
-                       /* we found a device that requires workaround */
-                       printk(KERN_DEBUG "radeonfb: %s detected"
-                              ", enabling workaround\n", id->ident);
-
-                       rinfo->pm_mode |= id->pm_mode_modifier;
-
-                       if (id->new_reinit_func != NULL)
-                               rinfo->reinit_func = id->new_reinit_func;
-
-                       return 1;
-               }
-       return 0;  /* not found */
-}
-
-#else  /* defined(CONFIG_PM) && defined(CONFIG_X86) */
-static inline int radeon_apply_workarounds(struct radeonfb_info *rinfo)
-{
-        return 0;
-}
-#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */
-
-
-
 static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
 {
        u32 tmp;
@@ -945,26 +852,18 @@ static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
        /* because both INPLL and OUTPLL take the same lock, that's why. */
        tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND;
        OUTPLL( pllMCLK_MISC, tmp);
+       
+       /* AGP PLL control */
+       if (rinfo->family <= CHIP_FAMILY_RV280) {
+               OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
 
-       /* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset
-        * and radeon chip dependent. Thus we only enable it on Mac for
-        * now (until we get more info on how to compute the correct
-        * value for various X86 bridges).
-        */
-#ifdef CONFIG_PPC_PMAC
-       if (machine_is(powermac)) {
-               /* AGP PLL control */
-               if (rinfo->family <= CHIP_FAMILY_RV280) {
-                       OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
-                       OUTREG(BUS_CNTL1,
-                              (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
-                              | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT));   // 440BX
-               } else {
-                       OUTREG(BUS_CNTL1, INREG(BUS_CNTL1));
-                       OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000);
-               }
+               OUTREG(BUS_CNTL1,
+                      (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
+                      | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT));   // 440BX
+       } else {
+               OUTREG(BUS_CNTL1, INREG(BUS_CNTL1));
+               OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000);
        }
-#endif
 
        OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL)
                                  & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
@@ -2181,7 +2080,7 @@ static void radeon_reinitialize_M9P(struct radeonfb_info *rinfo)
        OUTREG(0x2ec, 0x6332a3f0);
        mdelay(17);
 
-       OUTPLL(pllPPLL_REF_DIV, rinfo->pll.ref_div);
+       OUTPLL(pllPPLL_REF_DIV, rinfo->pll.ref_div);;
        OUTPLL(pllPPLL_DIV_0, rinfo->save_regs[92]);
 
        mdelay(40);
@@ -2814,7 +2713,7 @@ static void radeonfb_early_resume(void *data)
 
 #endif /* CONFIG_PM */
 
-void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep)
+void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
 {
        /* Find PM registers in config space if any*/
        rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
@@ -2830,14 +2729,23 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis
        }
 
 #if defined(CONFIG_PM)
-#if defined(CONFIG_PPC_PMAC)
        /* Check if we can power manage on suspend/resume. We can do
         * D2 on M6, M7 and M9, and we can resume from D3 cold a few other
         * "Mac" cards, but that's all. We need more infos about what the
         * BIOS does tho. Right now, all this PM stuff is pmac-only for that
         * reason. --BenH
         */
-       if (machine_is(powermac) && rinfo->of_node) {
+       /* Special case for Samsung P35 laptops
+        */
+       if ((rinfo->pdev->vendor == PCI_VENDOR_ID_ATI) &&
+           (rinfo->pdev->device == PCI_CHIP_RV350_NP) &&
+           (rinfo->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) &&
+           (rinfo->pdev->subsystem_device == 0xc00c)) {
+               rinfo->reinit_func = radeon_reinitialize_M10;
+               rinfo->pm_mode |= radeon_pm_off;
+       }
+#if defined(CONFIG_PPC_PMAC)
+       if (_machine == _MACH_Pmac && rinfo->of_node) {
                if (rinfo->is_mobility && rinfo->pm_reg &&
                    rinfo->family <= CHIP_FAMILY_RV250)
                        rinfo->pm_mode |= radeon_pm_d2;
@@ -2882,18 +2790,6 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis
        }
 #endif /* defined(CONFIG_PPC_PMAC) */
 #endif /* defined(CONFIG_PM) */
-
-       if (ignore_devlist)
-               printk(KERN_DEBUG
-                      "radeonfb: skipping test for device workarounds\n");
-       else
-               radeon_apply_workarounds(rinfo);
-
-       if (force_sleep) {
-               printk(KERN_DEBUG
-                      "radeonfb: forcefully enabling D2 sleep mode\n");
-               rinfo->pm_mode |= radeon_pm_d2;
-       }
 }
 
 void radeonfb_pm_exit(struct radeonfb_info *rinfo)