From 9a39cb9b9a51516abcaf795fa6e38cbeb22d7db9 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 12 Apr 2007 12:43:47 -0700 Subject: 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. --- linux-core/intel_drv.h | 1 + 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); } -- cgit v1.2.3