diff options
author | Jesse Barnes <jbarnes@hobbes.virtuousgeek.org> | 2007-04-12 12:43:47 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@hobbes.virtuousgeek.org> | 2007-04-12 12:43:47 -0700 |
commit | 9a39cb9b9a51516abcaf795fa6e38cbeb22d7db9 (patch) | |
tree | 3d41c6df956dc4c1974111a94415abaab2d280bf /linux-core | |
parent | 6b229c1e59e8d070e1822030f8f0c1d61140508d (diff) |
Use crtc_from_pipe call in intel_lvds.c and add get_mode panel mode detection. Also fix up error case for when LVDS mode can't be determined. Leave placeholder code in place for BIOS mode probing and platform quirks.
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/intel_drv.h | 1 | ||||
-rw-r--r-- | linux-core/intel_lvds.c | 71 |
2 files changed, 40 insertions, 32 deletions
diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h index f47e6233..aa33437d 100644 --- a/linux-core/intel_drv.h +++ b/linux-core/intel_drv.h @@ -74,5 +74,6 @@ extern void intel_output_commit (struct drm_output *output); extern struct drm_display_mode *intel_crtc_mode_get(drm_device_t *dev, struct drm_crtc *crtc); extern void intel_wait_for_vblank(drm_device_t *dev); +extern struct drm_crtc *intel_get_crtc_from_pipe(drm_device_t *dev, int pipe); #endif /* __INTEL_DRV_H__ */ diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index d2725e21..4020ec6e 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -164,8 +164,6 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, struct intel_crtc *intel_crtc = output->crtc->driver_private; struct drm_output *tmp_output; -#if 0 /* FIXME: Check for other outputs on this pipe */ - spin_lock(&dev->mode_config.config_lock); list_for_each_entry(tmp_output, &dev->mode_config.output_list, head) { if (tmp_output != output && tmp_output->crtc == output->crtc) { printk(KERN_ERR "Can't enable LVDS and another " @@ -173,8 +171,6 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, return false; } } - spin_lock(&dev->mode_config.config_lock); -#endif if (intel_crtc->pipe == 0) { printk(KERN_ERR "Can't support LVDS on pipe A\n"); @@ -262,7 +258,6 @@ static enum drm_output_status intel_lvds_detect(struct drm_output *output) */ static int intel_lvds_get_modes(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; struct drm_device *dev = output->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct edid *edid_info; @@ -317,9 +312,7 @@ static void intel_lvds_destroy(struct drm_output *output) struct intel_output *intel_output = output->driver_private; intel_i2c_destroy(intel_output->ddc_bus); - - if (output->driver_private) - kfree(output->driver_private); + kfree(output->driver_private); } static const struct drm_output_funcs intel_lvds_output_funcs = { @@ -349,6 +342,9 @@ void intel_lvds_init(struct drm_device *dev) struct drm_output *output; struct intel_output *intel_output; struct drm_display_mode *scan; /* *modes, *bios_mode; */ + struct drm_crtc *crtc; + u32 lvds; + int pipe; output = drm_output_create(dev, &intel_lvds_output_funcs, "LVDS"); if (!output) @@ -384,34 +380,34 @@ void intel_lvds_init(struct drm_device *dev) if (scan->type & DRM_MODE_TYPE_PREFERRED) { dev_priv->panel_fixed_mode = drm_mode_duplicate(dev, scan); - break; + goto out; /* FIXME: check for quirks */ } } -#if 0 /* * If we didn't get EDID, try checking if the panel is already turned * on. If so, assume that whatever is currently programmed is the * correct mode. */ - if (!dev_priv->panel_fixed_mode) { - u32 lvds = I915_READ(LVDS); - int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_crtc *crtc; - /* FIXME: need drm_crtc_from_pipe */ - //crtc = drm_crtc_from_pipe(mode_config, pipe); + lvds = I915_READ(LVDS); + pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; + crtc = intel_get_crtc_from_pipe(dev, pipe); - if (lvds & LVDS_PORT_EN && 0) { - dev_priv->panel_fixed_mode = - intel_crtc_mode_get(dev, crtc); - if (dev_priv->panel_fixed_mode) - dev_priv->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; + if (crtc && (lvds & LVDS_PORT_EN)) { + dev_priv->panel_fixed_mode = intel_crtc_mode_get(dev, crtc); + if (dev_priv->panel_fixed_mode) { + dev_priv->panel_fixed_mode->type |= + DRM_MODE_TYPE_PREFERRED; + goto out; /* FIXME: check for quirks */ } } -/* No BIOS poking yet... */ + /* If we still don't have a mode after all that, give up. */ + if (!dev_priv->panel_fixed_mode) + goto failed; + + /* FIXME: probe the BIOS for modes and check for LVDS quirks */ +#if 0 /* Get the LVDS fixed mode out of the BIOS. We should support LVDS * with the BIOS being unavailable or broken, but lack the * configuration options for now. @@ -442,22 +438,25 @@ void intel_lvds_init(struct drm_device *dev) goto disable_exit; } - /* Blacklist machines with BIOSes that list an LVDS panel without actually - * having one. + /* + * Blacklist machines with BIOSes that list an LVDS panel without + * actually having one. */ if (dev_priv->PciInfo->chipType == PCI_CHIP_I945_GM) { - if (dev_priv->PciInfo->subsysVendor == 0xa0a0) /* aopen mini pc */ + /* aopen mini pc */ + if (dev_priv->PciInfo->subsysVendor == 0xa0a0) goto disable_exit; if ((dev_priv->PciInfo->subsysVendor == 0x8086) && (dev_priv->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. + * 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 && @@ -472,5 +471,13 @@ void intel_lvds_init(struct drm_device *dev) } #endif + +out: return; + +failed: + DRM_DEBUG("No LVDS modes found, disabling.\n"); + intel_i2c_destroy(intel_output->ddc_bus); + kfree(output->driver_private); + drm_output_destroy(output); } |