X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Faty%2Fradeon_base.c;h=085cf80220df862d144bb5a0cf32f3e9f862d052;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=8e3400d5dd21e3f3246b8472287132e2ff73c7ff;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 8e3400d5d..085cf8022 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -52,12 +52,14 @@ #define RADEON_VERSION "0.2.0" +#include #include #include #include #include #include #include +#include #include #include #include @@ -76,6 +78,10 @@ #include #include "../macmodes.h" +#ifdef CONFIG_PMAC_BACKLIGHT +#include +#endif + #ifdef CONFIG_BOOTX_TEXT #include #endif @@ -266,13 +272,28 @@ static int force_measure_pll = 0; #ifdef CONFIG_MTRR static int nomtrr = 0; #endif -static int force_sleep; -static int ignore_devlist; +#if defined(CONFIG_PM) && defined(CONFIG_X86) +int radeon_force_sleep = 0; +#endif /* * prototypes */ + +#ifdef CONFIG_PPC_OF + +#ifdef CONFIG_PMAC_BACKLIGHT +static int radeon_set_backlight_enable(int on, int level, void *data); +static int radeon_set_backlight_level(int level, void *data); +static struct backlight_controller radeon_backlight_controller = { + radeon_set_backlight_enable, + radeon_set_backlight_level +}; +#endif /* CONFIG_PMAC_BACKLIGHT */ + +#endif /* CONFIG_PPC_OF */ + static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) { if (!rinfo->bios_seg) @@ -1895,6 +1916,116 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) return 0; } + +#ifdef CONFIG_PMAC_BACKLIGHT + +/* TODO: Dbl check these tables, we don't go up to full ON backlight + * in these, possibly because we noticed MacOS doesn't, but I'd prefer + * having some more official numbers from ATI + */ +static int backlight_conv_m6[] = { + 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e, + 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24 +}; +static int backlight_conv_m7[] = { + 0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81, + 0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9 +}; + +#define BACKLIGHT_LVDS_OFF +#undef BACKLIGHT_DAC_OFF + +/* We turn off the LCD completely instead of just dimming the backlight. + * This provides some greater power saving and the display is useless + * without backlight anyway. + */ +static int radeon_set_backlight_enable(int on, int level, void *data) +{ + struct radeonfb_info *rinfo = (struct radeonfb_info *)data; + u32 lvds_gen_cntl, tmpPixclksCntl; + int* conv_table; + + if (rinfo->mon1_type != MT_LCD) + return 0; + + /* Pardon me for that hack... maybe some day we can figure + * out in what direction backlight should work on a given + * panel ? + */ + if ((rinfo->family == CHIP_FAMILY_RV200 || + rinfo->family == CHIP_FAMILY_RV250 || + rinfo->family == CHIP_FAMILY_RV280 || + rinfo->family == CHIP_FAMILY_RV350) && + !machine_is_compatible("PowerBook4,3") && + !machine_is_compatible("PowerBook6,3") && + !machine_is_compatible("PowerBook6,5")) + conv_table = backlight_conv_m7; + else + conv_table = backlight_conv_m6; + + del_timer_sync(&rinfo->lvds_timer); + radeon_engine_idle(); + + lvds_gen_cntl = INREG(LVDS_GEN_CNTL); + if (on && (level > BACKLIGHT_OFF)) { + lvds_gen_cntl &= ~LVDS_DISPLAY_DIS; + if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) { + lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON); + lvds_gen_cntl |= LVDS_BLON | LVDS_EN; + OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); + lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; + lvds_gen_cntl |= (conv_table[level] << + LVDS_BL_MOD_LEVEL_SHIFT); + lvds_gen_cntl |= LVDS_ON; + lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN); + rinfo->pending_lvds_gen_cntl = lvds_gen_cntl; + mod_timer(&rinfo->lvds_timer, + jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); + } else { + lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; + lvds_gen_cntl |= (conv_table[level] << + LVDS_BL_MOD_LEVEL_SHIFT); + OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); + } + rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; + rinfo->init_state.lvds_gen_cntl |= rinfo->pending_lvds_gen_cntl + & LVDS_STATE_MASK; + } else { + /* Asic bug, when turning off LVDS_ON, we have to make sure + RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off + */ + tmpPixclksCntl = INPLL(PIXCLKS_CNTL); + if (rinfo->is_mobility || rinfo->is_IGP) + OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); + lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN); + lvds_gen_cntl |= (conv_table[0] << + LVDS_BL_MOD_LEVEL_SHIFT); + lvds_gen_cntl |= LVDS_DISPLAY_DIS; + OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); + udelay(100); + lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN); + OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); + lvds_gen_cntl &= ~(LVDS_DIGON); + rinfo->pending_lvds_gen_cntl = lvds_gen_cntl; + mod_timer(&rinfo->lvds_timer, + jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); + if (rinfo->is_mobility || rinfo->is_IGP) + OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl); + } + rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; + rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK); + + return 0; +} + + +static int radeon_set_backlight_level(int level, void *data) +{ + return radeon_set_backlight_enable(1, level, data); +} +#endif /* CONFIG_PMAC_BACKLIGHT */ + + /* * This reconfigure the card's internal memory map. In theory, we'd like * to setup the card's memory at the same address as it's PCI bus address, @@ -2329,9 +2460,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, ignore_devlist, force_sleep); + radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1); } else - radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep); + radeonfb_pm_init(rinfo, default_dynclk); pci_set_drvdata(pdev, info); @@ -2349,7 +2480,14 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, MTRR_TYPE_WRCOMB, 1); #endif - radeonfb_bl_init(rinfo); +#ifdef CONFIG_PMAC_BACKLIGHT + if (rinfo->mon1_type == MT_LCD) { + register_backlight_controller(&radeon_backlight_controller, + rinfo, "ati"); + register_backlight_controller(&radeon_backlight_controller, + rinfo, "mnca"); + } +#endif printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name); @@ -2379,6 +2517,7 @@ err_release_pci0: err_release_fb: framebuffer_release(info); err_disable: + pci_disable_device(pdev); err_out: return ret; } @@ -2392,8 +2531,7 @@ 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) @@ -2435,6 +2573,7 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) #endif fb_dealloc_cmap(&info->cmap); framebuffer_release(info); + pci_disable_device(pdev); } @@ -2480,10 +2619,8 @@ static int __init radeonfb_setup (char *options) } 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; + } else if (!strncmp(this_opt, "force_sleep", 11)) { + radeon_force_sleep = 1; #endif } else mode_option = this_opt; @@ -2541,8 +2678,6 @@ MODULE_PARM_DESC(panel_yres, "int: set panel yres"); module_param(mode_option, charp, 0); MODULE_PARM_DESC(mode_option, "Specify resolution as \"x[-][@]\" "); #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"); +module_param(radeon_force_sleep, int, 0); +MODULE_PARM_DESC(radeon_force_sleep, "bool: force ACPI sleep mode on untested machines"); #endif