--- drivers/video/aty/radeon_base.c 2007-04-08 11:41:52.000000000 +0200 +++ drivers/video/aty/radeon_base.c 2007-04-06 00:36:15.000000000 +0200 @@ -100,6 +100,8 @@ { 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), @@ -268,6 +270,11 @@ #endif static int force_sleep; static int ignore_devlist; +#ifdef CONFIG_PMAC_BACKLIGHT +static int backlight = 1; +#else +static int backlight = 0; +#endif /* * prototypes @@ -575,6 +582,32 @@ return 0; } +static void radeon_detect_bios_type(struct radeonfb_info *rinfo) +{ +#ifndef CONFIG_PPC_OF + int offset = rinfo->fp_bios_start + 4; + unsigned char sign[4]; + + sign[0] = BIOS_IN8(offset); + sign[1] = BIOS_IN8(offset + 1); + sign[2] = BIOS_IN8(offset + 2); + sign[3] = BIOS_IN8(offset + 3); + + if (!memcmp(sign, "ATOM", 4) || !memcmp(sign, "MOTA", 4)) { + rinfo->is_atom_bios = 1; + rinfo->atom_data_start = BIOS_IN16(rinfo->fp_bios_start + 32); + + printk(KERN_INFO "radeonfb: ATOM BIOS signature found\n"); + + return; + } +#endif /* NOT CONFIG_PPC_OF */ + + rinfo->is_atom_bios = 0; + + return; +} + /* * Retrieve PLL infos by different means (BIOS, Open Firmware, register probing...) */ @@ -651,20 +684,38 @@ #endif /* CONFIG_PPC_OF */ /* - * Check out if we have an X86 which gave us some PLL informations + * Check out if we have an ATOM BIOS which gave us some PLL informations * and if yes, retrieve them */ + if (!force_measure_pll && rinfo->bios_seg) { - u16 pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30); + u16 pll_info_block; - rinfo->pll.sclk = BIOS_IN16(pll_info_block + 0x08); - rinfo->pll.mclk = BIOS_IN16(pll_info_block + 0x0a); - rinfo->pll.ref_clk = BIOS_IN16(pll_info_block + 0x0e); - rinfo->pll.ref_div = BIOS_IN16(pll_info_block + 0x10); - rinfo->pll.ppll_min = BIOS_IN32(pll_info_block + 0x12); - rinfo->pll.ppll_max = BIOS_IN32(pll_info_block + 0x16); + if(rinfo->is_atom_bios) { + pll_info_block = BIOS_IN16(rinfo->atom_data_start + 12); + rinfo->pll.sclk = BIOS_IN32(pll_info_block + 8); + rinfo->pll.mclk = BIOS_IN32(pll_info_block + 12); + rinfo->pll.ref_clk = BIOS_IN16(pll_info_block + 82); + rinfo->pll.ref_div = 0; /* Have to get it elsewhere */ + rinfo->pll.ppll_min = BIOS_IN16(pll_info_block + 78); + rinfo->pll.ppll_max = BIOS_IN32(pll_info_block + 32); + } else { + /* + * Check out if we have an X86 which gave us some PLL informations + * and if yes, retrieve them + */ + pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30); + + rinfo->pll.sclk = BIOS_IN16(pll_info_block + 0x08); + rinfo->pll.mclk = BIOS_IN16(pll_info_block + 0x0a); + rinfo->pll.ref_clk = BIOS_IN16(pll_info_block + 0x0e); + rinfo->pll.ref_div = BIOS_IN16(pll_info_block + 0x10); + rinfo->pll.ppll_min = BIOS_IN32(pll_info_block + 0x12); + rinfo->pll.ppll_max = BIOS_IN32(pll_info_block + 0x16); + } printk(KERN_INFO "radeonfb: Retrieved PLL infos from BIOS\n"); + goto found; } @@ -680,18 +731,38 @@ /* * Fall back to already-set defaults... */ - printk(KERN_INFO "radeonfb: Used default PLL infos\n"); + printk(KERN_INFO "radeonfb: Fall back to default PLL infos\n"); found: + /* Check and fix-up the PLL divisor if necessary */ + if (rinfo->pll.ref_div < 2) { + int tmp = INPLL(PPLL_REF_DIV); + if (rinfo->family == CHIP_FAMILY_RS300) { + rinfo->pll.ref_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT; + } else { + rinfo->pll.ref_div = tmp & PPLL_REF_DIV_MASK; + } + + /* Sane default */ + if (rinfo->pll.ref_div < 2) { + printk(KERN_INFO "radeonfb: Set a sane default PLL divisor\n"); + rinfo->pll.ref_div = 12; + } + } + /* * Some methods fail to retrieve SCLK and MCLK values, we apply default - * settings in this case (200Mhz). If that really happne often, we could + * settings in this case (200Mhz). If that really happen often, we could * fetch from registers instead... */ - if (rinfo->pll.mclk == 0) + if (rinfo->pll.mclk == 0) { + printk(KERN_INFO "radeonfb: Set a sane default MCLK value\n"); rinfo->pll.mclk = 20000; - if (rinfo->pll.sclk == 0) + } + if (rinfo->pll.mclk == 0) { + printk(KERN_INFO "radeonfb: Set a sane default SCLK value\n"); rinfo->pll.sclk = 20000; + } printk("radeonfb: Reference=%d.%02d MHz (RefDiv=%d) Memory=%d.%02d Mhz, System=%d.%02d MHz\n", rinfo->pll.ref_clk / 100, rinfo->pll.ref_clk % 100, @@ -1026,8 +1097,7 @@ 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 +2060,8 @@ /* 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); @@ -2295,6 +2366,9 @@ if (rinfo->bios_seg == NULL && rinfo->is_mobility) radeon_map_ROM(rinfo, pdev); + /* Check BIOS Type */ + radeon_detect_bios_type(rinfo); + /* Get informations about the board's PLL */ radeon_get_pllinfo(rinfo); @@ -2349,7 +2423,8 @@ 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 +2468,6 @@ if (!rinfo) return; - radeonfb_bl_exit(rinfo); radeonfb_pm_exit(rinfo); if (rinfo->mon1_EDID) @@ -2420,6 +2494,8 @@ unregister_framebuffer(info); + radeonfb_bl_exit(rinfo); + iounmap(rinfo->mmio_base); iounmap(rinfo->fb_base); @@ -2469,6 +2545,8 @@ 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;