radeonfb: Add support for Radeon Xpress 200M (RS485)
[safe/jmp/linux-2.6] / drivers / video / aty / radeon_base.c
index 68b1564..47ca62f 100644 (file)
 
 #define RADEON_VERSION "0.2.0"
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/tty.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/time.h>
        { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) }
 
 static struct pci_device_id radeonfb_pci_table[] = {
+        /* Radeon Xpress 200m */
+       CHIP_DEF(PCI_CHIP_RS480_5955,   RS480,  CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
        /* Mobility M6 */
        CHIP_DEF(PCI_CHIP_RADEON_LY,    RV100,  CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
        CHIP_DEF(PCI_CHIP_RADEON_LZ,    RV100,  CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
@@ -153,6 +153,8 @@ static struct pci_device_id radeonfb_pci_table[] = {
        /* Mobility 9200 (M9+) */
        CHIP_DEF(PCI_CHIP_RV280_5C61,   RV280,  CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
        CHIP_DEF(PCI_CHIP_RV280_5C63,   RV280,  CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+       /*Mobility Xpress 200 */
+       CHIP_DEF(PCI_CHIP_RS485_5975,   R300,   CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
        /* 9200 */
        CHIP_DEF(PCI_CHIP_RV280_5960,   RV280,  CHIP_HAS_CRTC2),
        CHIP_DEF(PCI_CHIP_RV280_5961,   RV280,  CHIP_HAS_CRTC2),
@@ -268,6 +270,13 @@ static int force_measure_pll = 0;
 #ifdef CONFIG_MTRR
 static int nomtrr = 0;
 #endif
+static int force_sleep;
+static int ignore_devlist;
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int backlight = 1;
+#else
+static int backlight = 0;
+#endif
 
 /*
  * prototypes
@@ -405,7 +414,7 @@ static int  __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo)
 }
 #endif
 
-#ifdef CONFIG_PPC_OF
+#if defined(CONFIG_PPC_OF) || defined(CONFIG_SPARC)
 /*
  * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device
  * tree. Hopefully, ATI OF driver is kind enough to fill these
@@ -413,11 +422,11 @@ static int  __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo)
 static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
 {
        struct device_node *dp = rinfo->of_node;
-       u32 *val;
+       const u32 *val;
 
        if (dp == NULL)
                return -ENODEV;
-       val = (u32 *) get_property(dp, "ATY,RefCLK", NULL);
+       val = of_get_property(dp, "ATY,RefCLK", NULL);
        if (!val || !*val) {
                printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n");
                return -EINVAL;
@@ -425,17 +434,17 @@ static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
 
        rinfo->pll.ref_clk = (*val) / 10;
 
-       val = (u32 *) get_property(dp, "ATY,SCLK", NULL);
+       val = of_get_property(dp, "ATY,SCLK", NULL);
        if (val && *val)
                rinfo->pll.sclk = (*val) / 10;
 
-       val = (u32 *) get_property(dp, "ATY,MCLK", NULL);
+       val = of_get_property(dp, "ATY,MCLK", NULL);
        if (val && *val)
                rinfo->pll.mclk = (*val) / 10;
 
                return 0;
 }
-#endif /* CONFIG_PPC_OF */
+#endif /* CONFIG_PPC_OF || CONFIG_SPARC */
 
 /*
  * Read PLL infos from chip registers
@@ -640,7 +649,7 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
        rinfo->pll.ref_div = INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
 
 
-#ifdef CONFIG_PPC_OF
+#if defined(CONFIG_PPC_OF) || defined(CONFIG_SPARC)
        /*
         * Retrieve PLL infos from Open Firmware first
         */
@@ -648,7 +657,7 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
                        printk(KERN_INFO "radeonfb: Retrieved PLL infos from Open Firmware\n");
                goto found;
        }
-#endif /* CONFIG_PPC_OF */
+#endif /* CONFIG_PPC_OF || CONFIG_SPARC */
 
        /*
         * Check out if we have an X86 which gave us some PLL informations
@@ -1026,8 +1035,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
                break;
        }
 
-       /* let fbcon do a soft blank for us */
-       return (blank == FB_BLANK_NORMAL) ? -EINVAL : 0;
+       return 0;
 }
 
 static int radeonfb_blank (int blank, struct fb_info *info)
@@ -1990,7 +1998,8 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
        /* framebuffer size */
         if ((rinfo->family == CHIP_FAMILY_RS100) ||
             (rinfo->family == CHIP_FAMILY_RS200) ||
-            (rinfo->family == CHIP_FAMILY_RS300)) {
+            (rinfo->family == CHIP_FAMILY_RS300) ||
+           (rinfo->family == CHIP_FAMILY_RS480) ) {
           u32 tom = INREG(NB_TOM);
           tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
 
@@ -2095,7 +2104,9 @@ static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u
 }
 
 
-static ssize_t radeon_show_edid1(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t radeon_show_edid1(struct kobject *kobj,
+                                struct bin_attribute *bin_attr,
+                                char *buf, loff_t off, size_t count)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
        struct pci_dev *pdev = to_pci_dev(dev);
@@ -2106,7 +2117,9 @@ static ssize_t radeon_show_edid1(struct kobject *kobj, char *buf, loff_t off, si
 }
 
 
-static ssize_t radeon_show_edid2(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t radeon_show_edid2(struct kobject *kobj,
+                                struct bin_attribute *bin_attr,
+                                char *buf, loff_t off, size_t count)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
        struct pci_dev *pdev = to_pci_dev(dev);
@@ -2119,7 +2132,6 @@ static ssize_t radeon_show_edid2(struct kobject *kobj, char *buf, loff_t off, si
 static struct bin_attribute edid1_attr = {
        .attr   = {
                .name   = "edid1",
-               .owner  = THIS_MODULE,
                .mode   = 0444,
        },
        .size   = EDID_LENGTH,
@@ -2129,7 +2141,6 @@ static struct bin_attribute edid1_attr = {
 static struct bin_attribute edid2_attr = {
        .attr   = {
                .name   = "edid2",
-               .owner  = THIS_MODULE,
                .mode   = 0444,
        },
        .size   = EDID_LENGTH,
@@ -2227,7 +2238,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
            rinfo->family == CHIP_FAMILY_RS200)
                rinfo->errata |= CHIP_ERRATA_PLL_DELAY;
 
-#ifdef CONFIG_PPC_OF
+#if defined(CONFIG_PPC_OF) || defined(CONFIG_SPARC)
        /* On PPC, we obtain the OF device-node pointer to the firmware
         * data for this chip
         */
@@ -2236,6 +2247,8 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
                printk(KERN_WARNING "radeonfb (%s): Cannot match card to OF node !\n",
                       pci_name(rinfo->pdev));
 
+#endif /* CONFIG_PPC_OF || CONFIG_SPARC */
+#ifdef CONFIG_PPC_OF
        /* On PPC, the firmware sets up a memory mapping that tends
         * to cause lockups when enabling the engine. We reconfigure
         * the card internal memory mappings properly
@@ -2329,9 +2342,9 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
                /* -2 is special: means  ON on mobility chips and do not
                 * change on others
                 */
-               radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1);
+               radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep);
        } else
-               radeonfb_pm_init(rinfo, default_dynclk);
+               radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep);
 
        pci_set_drvdata(pdev, info);
 
@@ -2349,7 +2362,8 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
                                                 MTRR_TYPE_WRCOMB, 1);
 #endif
 
-       radeonfb_bl_init(rinfo);
+       if (backlight)
+               radeonfb_bl_init(rinfo);
 
        printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name);
 
@@ -2393,7 +2407,6 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
         if (!rinfo)
                 return;
 
-       radeonfb_bl_exit(rinfo);
        radeonfb_pm_exit(rinfo);
 
        if (rinfo->mon1_EDID)
@@ -2420,6 +2433,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
 
         unregister_framebuffer(info);
 
+        radeonfb_bl_exit(rinfo);
+
         iounmap(rinfo->mmio_base);
         iounmap(rinfo->fb_base);
  
@@ -2469,6 +2484,8 @@ static int __init radeonfb_setup (char *options)
                        force_dfp = 1;
                } else if (!strncmp(this_opt, "panel_yres:", 11)) {
                        panel_yres = simple_strtoul((this_opt+11), NULL, 0);
+               } else if (!strncmp(this_opt, "backlight:", 10)) {
+                       backlight = simple_strtoul(this_opt+10, NULL, 0);
 #ifdef CONFIG_MTRR
                } else if (!strncmp(this_opt, "nomtrr", 6)) {
                        nomtrr = 1;
@@ -2479,6 +2496,12 @@ static int __init radeonfb_setup (char *options)
                        force_measure_pll = 1;
                } else if (!strncmp(this_opt, "ignore_edid", 11)) {
                        ignore_edid = 1;
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+               } else if (!strncmp(this_opt, "force_sleep", 11)) {
+                       force_sleep = 1;
+               } else if (!strncmp(this_opt, "ignore_devlist", 14)) {
+                       ignore_devlist = 1;
+#endif
                } else
                        mode_option = this_opt;
        }
@@ -2534,3 +2557,9 @@ module_param(panel_yres, int, 0);
 MODULE_PARM_DESC(panel_yres, "int: set panel yres");
 module_param(mode_option, charp, 0);
 MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
+#if defined(CONFIG_PM) && defined(CONFIG_X86)
+module_param(force_sleep, bool, 0);
+MODULE_PARM_DESC(force_sleep, "bool: force D2 sleep mode on all hardware");
+module_param(ignore_devlist, bool, 0);
+MODULE_PARM_DESC(ignore_devlist, "bool: ignore workarounds for bugs in specific laptops");
+#endif