diff options
author | Wang Zhenyu <zhenyu.z.wang@intel.com> | 2007-07-27 09:14:13 +0800 |
---|---|---|
committer | Wang Zhenyu <zhenyu.z.wang@intel.com> | 2007-07-27 09:14:13 +0800 |
commit | 34c82ad7ce83394db47588693b578cf91991bf1c (patch) | |
tree | 261551391d4b95a7434bbb570992e1579eb2c90f /src | |
parent | 0fd3ba0518b3cde9ca0e4e2fc1854c00d8a43d5c (diff) |
Add quirk support
This one trys to use a flag for possible quirks. It adds a quirk
for my Lenovo T61 TV output, and ports some origin LVDS quirks to it.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/i830.h | 7 | ||||
-rw-r--r-- | src/i830_driver.c | 3 | ||||
-rw-r--r-- | src/i830_lvds.c | 39 | ||||
-rw-r--r-- | src/i830_quirks.c | 80 | ||||
-rw-r--r-- | src/i830_tv.c | 3 |
6 files changed, 112 insertions, 21 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 858ffd17..50e913ee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,6 +90,7 @@ intel_drv_la_SOURCES = \ i830_debug.h \ i830_display.c \ i830_display.h \ + i830_quirks.c \ i830_driver.c \ i830_dvo.c \ i830.h \ @@ -541,6 +541,7 @@ typedef struct _I830Rec { /** Enables logging of debug output related to mode switching. */ Bool debug_modes; + unsigned int quirk_flag; } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) @@ -750,4 +751,10 @@ extern const int I830CopyROP[16]; #define _845_DRAM_RW_CONTROL 0x90 #define DRAM_WRITE 0x33330000 +/* quirk flag definition */ +#define QUIRK_IGNORE_TV 0x00000001 +#define QUIRK_IGNORE_LVDS 0x00000002 +#define QUIRK_IGNORE_MACMINI_LVDS 0x00000004 +extern void i830_fixup_devices(ScrnInfoPtr); + #endif /* _I830_H_ */ diff --git a/src/i830_driver.c b/src/i830_driver.c index 9bb12c6b..f293bfde 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1192,6 +1192,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n", (unsigned long)pI830->MMIOAddr); + /* check quirks */ + i830_fixup_devices(pScrn); + /* Allocate an xf86CrtcConfig */ xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); diff --git a/src/i830_lvds.c b/src/i830_lvds.c index e2c6e3ce..246008ba 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -462,6 +462,9 @@ i830_lvds_init(ScrnInfoPtr pScrn) DisplayModePtr modes, scan, bios_mode; struct i830_lvds_priv *dev_priv; + if (pI830->quirk_flag & QUIRK_IGNORE_LVDS) + return; + output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS"); if (!output) return; @@ -575,29 +578,23 @@ i830_lvds_init(ScrnInfoPtr pScrn) /* Blacklist machines with BIOSes that list an LVDS panel without actually * having one. */ - if (pI830->PciInfo->chipType == PCI_CHIP_I945_GM) { - if (pI830->PciInfo->subsysVendor == 0xa0a0) /* aopen mini pc */ - goto disable_exit; - - if ((pI830->PciInfo->subsysVendor == 0x8086) && - (pI830->PciInfo->subsysCard == 0x7270)) { - /* It's a Mac Mini or Macbook Pro. - * - * Apple hardware is out to get us. The macbook pro has a real - * LVDS panel, but the mac mini does not, and they have the same - * device IDs. We'll distinguish by panel size, on the assumption - * that Apple isn't about to make any machines with an 800x600 - * display. - */ - - if (dev_priv->panel_fixed_mode != NULL && + if (pI830->quirk_flag & QUIRK_IGNORE_MACMINI_LVDS) { + /* It's a Mac Mini or Macbook Pro. + * + * Apple hardware is out to get us. The macbook pro has a real + * LVDS panel, but the mac mini does not, and they have the same + * device IDs. We'll distinguish by panel size, on the assumption + * that Apple isn't about to make any machines with an 800x600 + * display. + */ + + if (dev_priv->panel_fixed_mode != NULL && dev_priv->panel_fixed_mode->HDisplay == 800 && dev_priv->panel_fixed_mode->VDisplay == 600) - { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Suspected Mac Mini, ignoring the LVDS\n"); - goto disable_exit; - } + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Suspected Mac Mini, ignoring the LVDS\n"); + goto disable_exit; } } diff --git a/src/i830_quirks.c b/src/i830_quirks.c new file mode 100644 index 00000000..1bf46924 --- /dev/null +++ b/src/i830_quirks.c @@ -0,0 +1,80 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Zhenyu Wang <zhenyu.z.wang@intel.com> + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "i830.h" + +#define SUBSYS_ANY (~0) + +typedef struct { + int chipType; + int subsysVendor; + int subsysCard; + void (*hook)(I830Ptr); +} i830_quirk, *i830_quirk_ptr; + +static void quirk_ignore_tv (I830Ptr pI830) +{ + pI830->quirk_flag |= QUIRK_IGNORE_TV; +} + +static void quirk_ignore_lvds (I830Ptr pI830) +{ + pI830->quirk_flag |= QUIRK_IGNORE_LVDS; +} + +static void quirk_mac_mini (I830Ptr pI830) +{ + pI830->quirk_flag |= QUIRK_IGNORE_MACMINI_LVDS; +} + +static i830_quirk i830_quirk_list[] = { + /* Lenovo T61 has no TV output */ + { PCI_CHIP_I965_GM, 0x17aa, 0x20b5, quirk_ignore_tv }, + /* Aopen mini pc */ + { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, + /* Mac mini has no lvds, but macbook pro does */ + { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini }, + { 0, 0, 0, NULL }, +}; + +void i830_fixup_devices(ScrnInfoPtr scrn) +{ + I830Ptr pI830 = I830PTR(scrn); + i830_quirk_ptr p = i830_quirk_list; + + while (p && p->chipType != 0) { + if (pI830->PciInfo->chipType == p->chipType && + pI830->PciInfo->subsysVendor == p->subsysVendor && + (pI830->PciInfo->subsysCard == p->subsysCard || + p->subsysCard == SUBSYS_ANY)) + p->hook(pI830); + ++p; + } +} diff --git a/src/i830_tv.c b/src/i830_tv.c index 8337d864..aba0e3be 100644 --- a/src/i830_tv.c +++ b/src/i830_tv.c @@ -1625,6 +1625,9 @@ i830_tv_init(ScrnInfoPtr pScrn) struct i830_tv_priv *dev_priv; CARD32 tv_dac_on, tv_dac_off, save_tv_dac; + if (pI830->quirk_flag & QUIRK_IGNORE_TV) + return; + if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) return; |