From 52f9028c84baea81230dc673b756552e8e90aecd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 5 Apr 2007 11:21:06 +1000 Subject: Initial import of modesetting for intel driver in DRM --- linux-core/intel_lvds.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 linux-core/intel_lvds.c (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c new file mode 100644 index 00000000..c2ac5679 --- /dev/null +++ b/linux-core/intel_lvds.c @@ -0,0 +1,108 @@ +/* + * Copyright 2006 Dave Airlie + * Copyright © 2006 Intel Corporation + * Eric Anholt + * Jesse Barnes + */ + +#include +#include "drmP.h" +#include "drm.h" +#include "drm_crtc.h" +#include "intel_drv.h" +#include "i915_drm.h" +#include "i915_drv.h" + +/** + * Sets the backlight level. + * + * \param level backlight level, from 0 to i830_lvds_get_max_backlight(). + */ +static void lvds_set_backlight(drm_device_t *dev, u32 level) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long blc_pwm_ctl; + + level &= BACKLIGHT_DUTY_CYCLE_MASK; + blc_pwm_ctl = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | + (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); +} + +/** + * Returns the maximum level of the backlight duty cycle field. + */ +static u32 lvds_get_max_backlight(drm_device_t *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + return ((I915_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; +} + +int lvds_backlight(DRM_IOCTL_ARGS) +{ + DRM_DEVICE; + unsigned long dvoa_enabled, dvob_enabled, dvoc_enabled, lvds_enabled; + drm_i915_private_t *dev_priv = dev->dev_private; + + printk(KERN_ERR "max backlight value: %d\n", + lvds_get_max_backlight(dev)); + dvoa_enabled = I915_READ(DVOA); + dvob_enabled = I915_READ(DVOB); + dvoc_enabled = I915_READ(DVOC); + lvds_enabled = I915_READ(LVDS); + + printk(KERN_ERR "dvoa_enabled: 0x%08lx\n", dvoa_enabled); + printk(KERN_ERR "dvob_enabled: 0x%08lx\n", dvob_enabled); + printk(KERN_ERR "dvoc_enabled: 0x%08lx\n", dvoc_enabled); + printk(KERN_ERR "lvds_enabled: 0x%08lx\n", lvds_enabled); + printk(KERN_ERR "BLC_PWM_CTL: 0x%08x\n", I915_READ(BLC_PWM_CTL)); + + return 0; +} + +static const struct drm_output_funcs intel_lvds_output_funcs; + +/** + * intel_lvds_init - setup LVDS outputs on this device + * @dev: drm device + * + * Create the output, register the LVDS DDC bus, and try to figure out what + * modes we can display on the LVDS panel (if present). + */ +void intel_lvds_init(drm_device_t *dev) +{ + struct drm_output *output; + struct intel_output *intel_output; + int modes; + + output = drm_output_create(dev, &intel_lvds_output_funcs, "LVDS"); + if (!output) + return; + + intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL); + if (!intel_output) { + drm_output_destroy(output); + return; + } + + intel_output->type = INTEL_OUTPUT_LVDS; + output->driver_private = intel_output; + output->subpixel_order = SubPixelHorizontalRGB; + output->interlace_allowed = 0; + output->doublescan_allowed = 0; + + intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return; + } + + modes = intel_ddc_get_modes(output); + printk(KERN_ERR "LVDS: added %d modes from EDID.\n", modes); + intel_i2c_destroy(intel_output->ddc_bus); + drm_output_destroy(output); +} + -- cgit v1.2.3 From 6f3534a13abb0c8afb157511d0871dbc35bc403d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 5 Apr 2007 09:21:31 -0700 Subject: Add copyrights before I forget --- linux-core/intel_lvds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index c2ac5679..a2ac13a0 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -1,6 +1,6 @@ /* - * Copyright 2006 Dave Airlie - * Copyright © 2006 Intel Corporation + * Copyright (c) 2006 Dave Airlie + * Copyright (c) 2006-2007 Intel Corporation * Eric Anholt * Jesse Barnes */ -- cgit v1.2.3 From 1c9ba24c2f37ca78965f8aa57ece02ef5bdb9b06 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Apr 2007 11:34:11 -0700 Subject: Add required permission notices for code copied from X.Org source. --- linux-core/intel_lvds.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index a2ac13a0..a83f7d7a 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -1,7 +1,30 @@ +/* + * Copyright © 2006-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: + * Eric Anholt + */ /* * Copyright (c) 2006 Dave Airlie - * Copyright (c) 2006-2007 Intel Corporation - * Eric Anholt * Jesse Barnes */ -- cgit v1.2.3 From ab7ee9c1af3bd844653a83b5160773db671bbcad Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 7 Apr 2007 19:26:55 -0700 Subject: remove a printk to make things less verbose --- linux-core/intel_lvds.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index a83f7d7a..a444f145 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -124,7 +124,6 @@ void intel_lvds_init(drm_device_t *dev) } modes = intel_ddc_get_modes(output); - printk(KERN_ERR "LVDS: added %d modes from EDID.\n", modes); intel_i2c_destroy(intel_output->ddc_bus); drm_output_destroy(output); } -- cgit v1.2.3 From c446bf50e3ae730f272c6842f4ad04d523bd40c3 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 9 Apr 2007 20:46:38 -0700 Subject: Slam in most of X.Org's i830_lvds (not quite done yet so removed from Makefile.kernel too). --- linux-core/intel_lvds.c | 423 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 383 insertions(+), 40 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index a444f145..7527dfce 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -1,5 +1,6 @@ /* * Copyright © 2006-2007 Intel Corporation + * Copyright (c) 2006 Dave Airlie * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,10 +23,8 @@ * * Authors: * Eric Anholt - */ -/* - * Copyright (c) 2006 Dave Airlie - * Jesse Barnes + * Dave Airlie + * Jesse Barnes */ #include @@ -39,23 +38,22 @@ /** * Sets the backlight level. * - * \param level backlight level, from 0 to i830_lvds_get_max_backlight(). + * \param level backlight level, from 0 to intel_lvds_get_max_backlight(). */ -static void lvds_set_backlight(drm_device_t *dev, u32 level) +static void intel_lvds_set_backlight(struct drm_device *dev, int level) { drm_i915_private_t *dev_priv = dev->dev_private; - unsigned long blc_pwm_ctl; + u32 blc_pwm_ctl; - level &= BACKLIGHT_DUTY_CYCLE_MASK; blc_pwm_ctl = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; - I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); + I915_WRITE(BLC_PWM_CTL, (blc_pwm_ctl | + (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); } /** * Returns the maximum level of the backlight duty cycle field. */ -static u32 lvds_get_max_backlight(drm_device_t *dev) +static u32 intel_lvds_get_max_backlight(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -63,30 +61,386 @@ static u32 lvds_get_max_backlight(drm_device_t *dev) BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; } -int lvds_backlight(DRM_IOCTL_ARGS) +/** + * Sets the power state for the panel. + */ +static void intel_lvds_set_power(struct drm_device *dev, bool on) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + u32 pp_status; + + if (on) { + I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | + POWER_TARGET_ON); + do { + pp_status = I915_READ(PP_STATUS); + } while ((pp_status & PP_ON) == 0); + + intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); + } else { + intel_lvds_set_backlight(dev, 0); + + I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & + ~POWER_TARGET_ON); + do { + pp_status = I915_READ(PP_STATUS); + } while (pp_status & PP_ON); + } +} + +static void intel_lvds_dpms(struct drm_output *output, int mode) +{ + struct drm_device *dev = output->dev; + + if (mode == DPMSModeOn) + intel_lvds_set_power(dev, true); + else + intel_lvds_set_power(dev, false); + + /* XXX: We never power down the LVDS pairs. */ +} + +static void intel_lvds_save(struct drm_output *output) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + dev_priv->savePP_ON = I915_READ(LVDSPP_ON); + dev_priv->savePP_OFF = I915_READ(LVDSPP_OFF); + dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); + dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE); + dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); + dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); + + /* + * If the light is off at server startup, just make it full brightness + */ + if (dev_priv->backlight_duty_cycle == 0) + dev_priv->backlight_duty_cycle = + intel_lvds_get_max_backlight(dev); +} + +static void intel_lvds_restore(struct drm_output *output) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); + I915_WRITE(LVDSPP_ON, dev_priv->savePP_ON); + I915_WRITE(LVDSPP_OFF, dev_priv->savePP_OFF); + I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE); + I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); + if (dev_priv->savePP_CONTROL & POWER_TARGET_ON) + intel_lvds_set_power(dev, true); + else + intel_lvds_set_power(dev, false); +} + +static int intel_lvds_mode_valid(struct drm_output *output, + struct drm_display_mode *mode) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; + + if (fixed_mode) { + if (mode->hdisplay > fixed_mode->hdisplay) + return MODE_PANEL; + if (mode->vdisplay > fixed_mode->vdisplay) + return MODE_PANEL; + } + + return MODE_OK; +} + +static bool intel_lvds_mode_fixup(struct drm_output *output, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = output->crtc->driver_private; + struct drm_output *tmp_output; + + spin_lock(&dev->crtc_config.config_lock); + list_for_each_entry(tmp_output, &dev->crtc_config.output_list, head) { + if (tmp_output != output && tmp_output->crtc == output->crtc) { + printk(KERN_ERR "Can't enable LVDS and another " + "output on the same pipe\n"); + return false; + } + } + spin_lock(&dev->crtc_config.config_lock); + + if (intel_crtc->pipe == 0) { + printk(KERN_ERR "Can't support LVDS on pipe A\n"); + return false; + } + + /* + * If we have timings from the BIOS for the panel, put them in + * to the adjusted mode. The CRTC will be set up for this mode, + * with the panel scaling set up to source from the H/VDisplay + * of the original mode. + */ + if (dev_priv->panel_fixed_mode != NULL) { + adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; + adjusted_mode->hsync_start = + dev_priv->panel_fixed_mode->hsync_start; + adjusted_mode->hsync_end = + dev_priv->panel_fixed_mode->hsync_end; + adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; + adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; + adjusted_mode->vsync_start = + dev_priv->panel_fixed_mode->vsync_start; + adjusted_mode->vsync_end = + dev_priv->panel_fixed_mode->vsync_end; + adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; + adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; +// xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); + } + + /* + * XXX: It would be nice to support lower refresh rates on the + * panels to reduce power consumption, and perhaps match the + * user's requested refresh rate. + */ + + return true; +} + +static void intel_lvds_mode_set(struct drm_output *output, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = output->crtc->driver_private; + u32 pfit_control; + + /* + * The LVDS pin pair will already have been turned on in the + * intel_crtc_mode_set since it has a large impact on the DPLL + * settings. + */ + + /* + * Enable automatic panel scaling so that non-native modes fill the + * screen. Should be enabled before the pipe is enabled, according to + * register description and PRM. + */ + pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | + VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR); + + if (!IS_I965G(dev)) { + if (dev_priv->panel_wants_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + } + else + pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT; + + I915_WRITE(PFIT_CONTROL, pfit_control); +} + +/** + * Detect the LVDS connection. + * + * This always returns OUTPUT_STATUS_CONNECTED. This output should only have + * been set up if the LVDS was actually connected anyway. + */ +static enum drm_output_status intel_lvds_detect(struct drm_output *output) +{ + return output_status_connected; +} + +/** + * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. + */ +static int intel_lvds_get_modes(struct drm_output *output) { - DRM_DEVICE; - unsigned long dvoa_enabled, dvob_enabled, dvoc_enabled, lvds_enabled; + struct intel_output *intel_output = output->driver_private; + struct drm_device *dev = output->dev; drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_monitor_info *edid_mon; + int ret = 0; + + intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return 0; + } + intel_i2c_destroy(intel_output->ddc_bus); + + ret = intel_ddc_get_modes(output); + if (ret) + return ret; +#if 0 + if (!output->monitor_info) { + edid_mon = kzalloc(sizeof(*output->monitor_info), GFP_KERNEL); + if (edid_mon) { + /* Set wide sync ranges so we get all modes + * handed to valid_mode for checking + */ + edid_mon->det_mon[0].type = DS_RANGES; + edid_mon->det_mon[0].section.ranges.min_v = 0; + edid_mon->det_mon[0].section.ranges.max_v = 200; + edid_mon->det_mon[0].section.ranges.min_h = 0; + edid_mon->det_mon[0].section.ranges.max_h = 200; + + output->monitor_info = edid_mon; + } + } +#endif + if (dev_priv->panel_fixed_mode != NULL) { + struct drm_display_mode *mode = + drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); + drm_mode_probed_add(output, mode); + return 1; + } - printk(KERN_ERR "max backlight value: %d\n", - lvds_get_max_backlight(dev)); - dvoa_enabled = I915_READ(DVOA); - dvob_enabled = I915_READ(DVOB); - dvoc_enabled = I915_READ(DVOC); - lvds_enabled = I915_READ(LVDS); - - printk(KERN_ERR "dvoa_enabled: 0x%08lx\n", dvoa_enabled); - printk(KERN_ERR "dvob_enabled: 0x%08lx\n", dvob_enabled); - printk(KERN_ERR "dvoc_enabled: 0x%08lx\n", dvoc_enabled); - printk(KERN_ERR "lvds_enabled: 0x%08lx\n", lvds_enabled); - printk(KERN_ERR "BLC_PWM_CTL: 0x%08x\n", I915_READ(BLC_PWM_CTL)); - return 0; } -static const struct drm_output_funcs intel_lvds_output_funcs; +static void intel_lvds_destroy(struct drm_output *output) +{ + drm_output_destroy(output); +} + +static const struct drm_output_funcs intel_lvds_output_funcs = { + .dpms = intel_lvds_dpms, + .save = intel_lvds_save, + .restore = intel_lvds_restore, + .mode_valid = intel_lvds_mode_valid, + .mode_fixup = intel_lvds_mode_fixup, + .prepare = intel_output_prepare, + .mode_set = intel_lvds_mode_set, + .commit = intel_output_commit, + .detect = intel_lvds_detect, + .get_modes = intel_lvds_get_modes, + .cleanup = intel_lvds_destroy +}; + +void +intel_lvds_init(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_output *output; + struct intel_output *intel_output; + struct drm_display_mode *modes, scan, bios_mode; + + output = drm_output_create(dev, &intel_lvds_output_funcs, "LVDS"); + if (!output) + return; + + intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL); + if (!intel_output) { + drm_output_destroy(output); + return; + } + + intel_output->type = INTEL_OUTPUT_LVDS; + output->driver_private = intel_output; + output->subpixel_order = SubPixelHorizontalRGB; + output->interlace_allowed = FALSE; + output->doublescan_allowed = FALSE; + + /* + * Attempt to get the fixed panel mode from DDC. Assume that the + * preferred mode is the right one. + */ + intel_ddc_get_modes(output); + list_for_each_entry(scan, &output->probed_modes, head) { + if (scan->type & DRM_MODE_TYPE_PREFERRED) + break; + } + + if (scan != NULL) + dev_priv->panel_fixed_mode = scan; + +#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 == NULL) { + u32 lvds = I915_READ(LVDS); + int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; + struct drm_crtc_config *crtc_config = dev->crtc_config; + struct drm_crtc *crtc = crtc_config->crtc[pipe]; + + if (lvds & LVDS_PORT_EN) { + dev_priv->panel_fixed_mode = intel_crtc_mode_get(pScrn, crtc); + if (dev_priv->panel_fixed_mode != NULL) + dev_priv->panel_fixed_mode->type |= M_T_PREFERRED; + } + } + + /* 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. + */ + bios_mode = intel_bios_get_panel_mode(pScrn); + if (bios_mode != NULL) { + if (dev_priv->panel_fixed_mode != NULL) { + if (dev_priv->debug_modes && + !xf86ModesEqual(dev_priv->panel_fixed_mode, bios_mode)) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "BIOS panel mode data doesn't match probed data, " + "continuing with probed.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS mode:\n"); + xf86PrintModeline(pScrn->scrnIndex, bios_mode); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "probed mode:\n"); + xf86PrintModeline(pScrn->scrnIndex, dev_priv->panel_fixed_mode); + xfree(bios_mode->name); + xfree(bios_mode); + } + } else { + dev_priv->panel_fixed_mode = bios_mode; + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't detect panel mode. Disabling panel\n"); + goto disable_exit; + } + + /* 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 */ + 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. + */ + 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; + } + } + } + +#endif + return; +} + +#if 0 /** * intel_lvds_init - setup LVDS outputs on this device * @dev: drm device @@ -115,16 +469,5 @@ void intel_lvds_init(drm_device_t *dev) output->subpixel_order = SubPixelHorizontalRGB; output->interlace_allowed = 0; output->doublescan_allowed = 0; - - intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return; - } - - modes = intel_ddc_get_modes(output); - intel_i2c_destroy(intel_output->ddc_bus); - drm_output_destroy(output); } - +#endif -- cgit v1.2.3 From 183cbd92dd016f8935f9b58ef9345fde1391173e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 10 Apr 2007 09:47:37 -0700 Subject: Finish bringing in LVDS code, re-add to Makefile. Needed other changes too: - move EDID structures to drm_edid.h - add EDID info structure to drm_output - add a few routines to intel_display for getting current mode info - add some prototypes to intel_drv.h and drm_crtc.h --- linux-core/intel_lvds.c | 117 +++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 65 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 7527dfce..4638fb30 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -31,6 +31,7 @@ #include "drmP.h" #include "drm.h" #include "drm_crtc.h" +#include "drm_edid.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" @@ -262,7 +263,7 @@ 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 drm_monitor_info *edid_mon; + struct edid *edid_info; int ret = 0; intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); @@ -276,23 +277,29 @@ static int intel_lvds_get_modes(struct drm_output *output) ret = intel_ddc_get_modes(output); if (ret) return ret; -#if 0 + + /* Didn't get an EDID */ if (!output->monitor_info) { - edid_mon = kzalloc(sizeof(*output->monitor_info), GFP_KERNEL); - if (edid_mon) { - /* Set wide sync ranges so we get all modes - * handed to valid_mode for checking - */ - edid_mon->det_mon[0].type = DS_RANGES; - edid_mon->det_mon[0].section.ranges.min_v = 0; - edid_mon->det_mon[0].section.ranges.max_v = 200; - edid_mon->det_mon[0].section.ranges.min_h = 0; - edid_mon->det_mon[0].section.ranges.max_h = 200; - - output->monitor_info = edid_mon; - } + struct detailed_data_monitor_range *edid_range; + edid_info = kzalloc(sizeof(*output->monitor_info), GFP_KERNEL); + if (!edid_info) + goto out; + + edid_info->detailed_timings[0].data.other_data.type = + EDID_DETAIL_MONITOR_RANGE; + edid_range = &edid_info->detailed_timings[0].data.other_data.data.range; + + /* Set wide sync ranges so we get all modes + * handed to valid_mode for checking + */ + edid_range->min_vfreq = 0; + edid_range->max_vfreq = 200; + edid_range->min_hfreq_khz = 0; + edid_range->max_hfreq_khz = 200; + output->monitor_info = edid_info; } -#endif + +out: if (dev_priv->panel_fixed_mode != NULL) { struct drm_display_mode *mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); @@ -322,13 +329,19 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { .cleanup = intel_lvds_destroy }; -void -intel_lvds_init(struct drm_device *dev) +/** + * intel_lvds_init - setup LVDS outputs on this device + * @dev: drm device + * + * Create the output, register the LVDS DDC bus, and try to figure out what + * modes we can display on the LVDS panel (if present). + */ +void intel_lvds_init(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_output *output; struct intel_output *intel_output; - struct drm_display_mode *modes, scan, bios_mode; + struct drm_display_mode *scan; /* *modes, *bios_mode; */ output = drm_output_create(dev, &intel_lvds_output_funcs, "LVDS"); if (!output) @@ -356,37 +369,43 @@ intel_lvds_init(struct drm_device *dev) break; } - if (scan != NULL) + if (scan) dev_priv->panel_fixed_mode = scan; -#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 == NULL) { + if (!dev_priv->panel_fixed_mode) { u32 lvds = I915_READ(LVDS); int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - struct drm_crtc_config *crtc_config = dev->crtc_config; - struct drm_crtc *crtc = crtc_config->crtc[pipe]; - - if (lvds & LVDS_PORT_EN) { - dev_priv->panel_fixed_mode = intel_crtc_mode_get(pScrn, crtc); - if (dev_priv->panel_fixed_mode != NULL) - dev_priv->panel_fixed_mode->type |= M_T_PREFERRED; + struct drm_crtc_config *crtc_config = &dev->crtc_config; + struct drm_crtc *crtc; + /* FIXME: need drm_crtc_from_pipe */ + //crtc = drm_crtc_from_pipe(crtc_config, 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; } } - /* 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. +/* No BIOS poking yet... */ +#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. */ bios_mode = intel_bios_get_panel_mode(pScrn); if (bios_mode != NULL) { if (dev_priv->panel_fixed_mode != NULL) { if (dev_priv->debug_modes && - !xf86ModesEqual(dev_priv->panel_fixed_mode, bios_mode)) + !xf86ModesEqual(dev_priv->panel_fixed_mode, + bios_mode)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "BIOS panel mode data doesn't match probed data, " @@ -439,35 +458,3 @@ intel_lvds_init(struct drm_device *dev) #endif return; } - -#if 0 -/** - * intel_lvds_init - setup LVDS outputs on this device - * @dev: drm device - * - * Create the output, register the LVDS DDC bus, and try to figure out what - * modes we can display on the LVDS panel (if present). - */ -void intel_lvds_init(drm_device_t *dev) -{ - struct drm_output *output; - struct intel_output *intel_output; - int modes; - - output = drm_output_create(dev, &intel_lvds_output_funcs, "LVDS"); - if (!output) - return; - - intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL); - if (!intel_output) { - drm_output_destroy(output); - return; - } - - intel_output->type = INTEL_OUTPUT_LVDS; - output->driver_private = intel_output; - output->subpixel_order = SubPixelHorizontalRGB; - output->interlace_allowed = 0; - output->doublescan_allowed = 0; -} -#endif -- cgit v1.2.3 From 78598fdaa8b23a199880a63b79f17cfd7f14cb0f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 07:07:54 -0700 Subject: Various changes for in-kernel modesetting: - allow drm_buffer_object_create to be called w/o dev_mapping - fixup i915 init code to allocate memory, fb and set modes right - pass fb to drm_initial_config for setup - change some debug output to make it easier to spot - fixup lvds code to use DDC probing correctly --- linux-core/intel_lvds.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 90a26109..8ecb204c 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -164,6 +164,7 @@ 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 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) { @@ -173,6 +174,7 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, } } spin_lock(&dev->mode_config.config_lock); +#endif if (intel_crtc->pipe == 0) { printk(KERN_ERR "Can't support LVDS on pipe A\n"); @@ -199,7 +201,7 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, dev_priv->panel_fixed_mode->vsync_end; adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; -// xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); } /* @@ -272,11 +274,11 @@ static int intel_lvds_get_modes(struct drm_output *output) "failed.\n"); return 0; } - intel_i2c_destroy(intel_output->ddc_bus); ret = intel_ddc_get_modes(output); if (ret) return ret; + intel_i2c_destroy(intel_output->ddc_bus); /* Didn't get an EDID */ if (!output->monitor_info) { @@ -359,19 +361,31 @@ void intel_lvds_init(struct drm_device *dev) output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; + /* Set up the DDC bus. */ + intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return; + } + /* * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. */ intel_ddc_get_modes(output); + intel_i2c_destroy(intel_output->ddc_bus); list_for_each_entry(scan, &output->probed_modes, head) { if (scan->type & DRM_MODE_TYPE_PREFERRED) break; } - if (scan) + if (scan) { dev_priv->panel_fixed_mode = scan; + DRM_DEBUG("LVDS panel_fixed: %s\n", scan->name); + } +#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 @@ -395,7 +409,6 @@ void intel_lvds_init(struct drm_device *dev) } /* No BIOS poking yet... */ -#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. -- cgit v1.2.3 From cc7faa4de80a68d5a7a484046b9b42de961cdbef Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 07:21:24 -0700 Subject: fix modeset cleanup for LVDS and reenable it in i915. --- linux-core/intel_lvds.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 8ecb204c..ec693275 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -314,7 +314,8 @@ out: static void intel_lvds_destroy(struct drm_output *output) { - drm_output_destroy(output); + if (output->driver_private) + kfree(output->driver_private); } static const struct drm_output_funcs intel_lvds_output_funcs = { -- cgit v1.2.3 From 63d4d40463b04f1277470ccf5cc96dafd81e8687 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 11 Apr 2007 11:46:37 -0700 Subject: Fix i2c unregistration, cleanup panel_fixed_mode assignment. --- linux-core/intel_lvds.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index ec693275..e8670adc 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -164,7 +164,7 @@ 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 +#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) { @@ -274,11 +274,11 @@ static int intel_lvds_get_modes(struct drm_output *output) "failed.\n"); return 0; } - ret = intel_ddc_get_modes(output); + intel_i2c_destroy(intel_output->ddc_bus); + if (ret) return ret; - intel_i2c_destroy(intel_output->ddc_bus); /* Didn't get an EDID */ if (!output->monitor_info) { @@ -377,13 +377,11 @@ void intel_lvds_init(struct drm_device *dev) intel_ddc_get_modes(output); intel_i2c_destroy(intel_output->ddc_bus); list_for_each_entry(scan, &output->probed_modes, head) { - if (scan->type & DRM_MODE_TYPE_PREFERRED) + if (scan->type & DRM_MODE_TYPE_PREFERRED) { + dev_priv->panel_fixed_mode = + drm_mode_duplicate(dev, scan); break; - } - - if (scan) { - dev_priv->panel_fixed_mode = scan; - DRM_DEBUG("LVDS panel_fixed: %s\n", scan->name); + } } #if 0 -- cgit v1.2.3 From c2fce380c26d72f2d7971a4d08076da33c41f5ae Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 12 Apr 2007 08:57:58 -0700 Subject: Move i2c init back to where it belongs and add i2c unregistration in *_destroy. --- linux-core/intel_lvds.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index e8670adc..d2725e21 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -268,14 +268,7 @@ static int intel_lvds_get_modes(struct drm_output *output) struct edid *edid_info; int ret = 0; - intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return 0; - } ret = intel_ddc_get_modes(output); - intel_i2c_destroy(intel_output->ddc_bus); if (ret) return ret; @@ -312,8 +305,19 @@ out: return 0; } +/** + * intel_lvds_destroy - unregister and free LVDS structures + * @output: output to free + * + * Unregister the DDC bus for this output then free the driver private + * structure. + */ 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); } @@ -375,7 +379,7 @@ void intel_lvds_init(struct drm_device *dev) * preferred mode is the right one. */ intel_ddc_get_modes(output); - intel_i2c_destroy(intel_output->ddc_bus); + list_for_each_entry(scan, &output->probed_modes, head) { if (scan->type & DRM_MODE_TYPE_PREFERRED) { dev_priv->panel_fixed_mode = -- cgit v1.2.3 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_lvds.c | 71 +++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 32 deletions(-) (limited to 'linux-core/intel_lvds.c') 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 From a890d596fc22a3dca9d390f96f0f739cf90de5e1 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Fri, 13 Apr 2007 14:30:44 +1000 Subject: revert LVDS destroy - this oops on sysfs on sdvo init of i2c bus --- linux-core/intel_lvds.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 4020ec6e..db025417 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -476,8 +476,7 @@ 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); + DRM_DEBUG("No LVDS modes found, disabling.\n"); + // intel_lvds_destroy(output); + // drm_output_destroy(output); } -- cgit v1.2.3 From a45fa264f2b60185ae797f85d2084d57de49bbca Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 17 Apr 2007 22:27:46 +0200 Subject: Lvds now power up backlight on commit Now saves previous power level in prepare and sets that power level in commit, should power level be 0 it will set maximum level. --- linux-core/intel_lvds.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index db025417..8454bbcf 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -209,6 +209,30 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, return true; } +static void intel_lvds_prepare(struct drm_output *output) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); + dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); + + intel_lvds_set_power(dev, false); +} + +static void intel_lvds_commit( struct drm_output *output) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + if (dev_priv->backlight_duty_cycle == 0) + dev_priv->backlight_duty_cycle = + intel_lvds_get_max_backlight(dev); + + intel_lvds_set_power(dev, true); +} + static void intel_lvds_mode_set(struct drm_output *output, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -321,9 +345,9 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { .restore = intel_lvds_restore, .mode_valid = intel_lvds_mode_valid, .mode_fixup = intel_lvds_mode_fixup, - .prepare = intel_output_prepare, + .prepare = intel_lvds_prepare, .mode_set = intel_lvds_mode_set, - .commit = intel_output_commit, + .commit = intel_lvds_commit, .detect = intel_lvds_detect, .get_modes = intel_lvds_get_modes, .cleanup = intel_lvds_destroy -- cgit v1.2.3 From 4f0841a31cbed315a3e891557eadc55cab0dfd23 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 18:03:14 -0700 Subject: Just use drm_output_destroy to cleanup LVDS failures. It'll call our cleanup routine, which will take care of freeing our dev_priv and i2c ddc bus. --- linux-core/intel_lvds.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 8454bbcf..34ed6a9d 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -501,6 +501,5 @@ out: failed: DRM_DEBUG("No LVDS modes found, disabling.\n"); - // intel_lvds_destroy(output); - // drm_output_destroy(output); + drm_output_destroy(output); /* calls intel_lvds_destroy above */ } -- cgit v1.2.3 From eb892fb09dc2e5206f2461e8b258495c7cef904a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 20 Apr 2007 17:59:30 -0700 Subject: Add a monitor information structure separate from the EDID data for tracking monitor limits, etc. --- linux-core/intel_lvds.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 34ed6a9d..74b040ba 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -284,7 +284,6 @@ static int intel_lvds_get_modes(struct drm_output *output) { struct drm_device *dev = output->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct edid *edid_info; int ret = 0; ret = intel_ddc_get_modes(output); @@ -294,23 +293,19 @@ static int intel_lvds_get_modes(struct drm_output *output) /* Didn't get an EDID */ if (!output->monitor_info) { - struct detailed_data_monitor_range *edid_range; - edid_info = kzalloc(sizeof(*output->monitor_info), GFP_KERNEL); - if (!edid_info) + struct drm_display_info *dspinfo; + dspinfo = kzalloc(sizeof(*output->monitor_info), GFP_KERNEL); + if (!dspinfo) goto out; - edid_info->detailed_timings[0].data.other_data.type = - EDID_DETAIL_MONITOR_RANGE; - edid_range = &edid_info->detailed_timings[0].data.other_data.data.range; - /* Set wide sync ranges so we get all modes * handed to valid_mode for checking */ - edid_range->min_vfreq = 0; - edid_range->max_vfreq = 200; - edid_range->min_hfreq_khz = 0; - edid_range->max_hfreq_khz = 200; - output->monitor_info = edid_info; + dspinfo->min_vfreq = 0; + dspinfo->max_vfreq = 200; + dspinfo->min_hfreq = 0; + dspinfo->max_hfreq = 200; + output->monitor_info = dspinfo; } out: -- cgit v1.2.3 From 5ce8aaae7251e60c078eda0a21894aae0e1d7a45 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 17 May 2007 12:46:36 +0100 Subject: Large changes for fbdev support. Change from DIRECTCOLOR to TRUECOLOR, and enable support for PSEUDOCOLOR. DIRECTCOLOR support needs more work. Add the ability to change the mode on the fbdev device. Support depth 8, 15, 16 and 24 (and 32). Add a /dev/fbX device per CRTC, but there's some code which doesn't allocate the fbX device unless the output is actually enabled. Read the code on this as it impacts the fbcon map flags. Pick CRTC's based on the available outputs. More work could be done here to match modes, so cloning could be achieved on outputs. This fits more inline with what the X code does. --- linux-core/intel_lvds.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 74b040ba..942eb2ab 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -164,6 +164,13 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, struct intel_crtc *intel_crtc = output->crtc->driver_private; struct drm_output *tmp_output; + /* Should never happen!! */ + if (!IS_I965G(dev) && intel_crtc->pipe == 0) { + printk(KERN_ERR "Can't support LVDS on pipe A\n"); + return false; + } + + /* Should never happen!! */ 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 " @@ -172,11 +179,6 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, } } - if (intel_crtc->pipe == 0) { - printk(KERN_ERR "Can't support LVDS on pipe A\n"); - return false; - } - /* * If we have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, -- cgit v1.2.3 From 617cbeed2ae71c5560f597db49637df10edd8a52 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 27 Nov 2007 12:39:09 -0800 Subject: Don't use panel fitter if we're programming a native mode Fix from the DDX driver. --- linux-core/intel_lvds.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 4f15c13a..e3e4b38a 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -255,8 +255,13 @@ static void intel_lvds_mode_set(struct drm_output *output, * screen. Should be enabled before the pipe is enabled, according to * register description and PRM. */ - pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR); + if (mode->hdisplay != adjusted_mode->hdisplay || + mode->vdisplay != adjusted_mode->vdisplay) + pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | + HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | + HORIZ_INTERP_BILINEAR); + else + pfit_control = 0; if (!IS_I965G(dev)) { if (dev_priv->panel_wants_dither) -- cgit v1.2.3 From f99dea7db00dd46aa96eaed3a61dff9c956fd86f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 11 Dec 2007 15:56:48 +1000 Subject: modesetting: fixup property setting and add connector property --- linux-core/intel_lvds.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index e3e4b38a..94232b94 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -499,6 +499,7 @@ void intel_lvds_init(struct drm_device *dev) #endif out: + drm_output_attach_property(output, dev->mode_config.connector_type_property, ConnectorLVDS); return; failed: -- cgit v1.2.3 From b13dc383df85d75cb1ea422f4d13efc2a4a8a732 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 18 Dec 2007 17:41:20 +1100 Subject: remove output names --- linux-core/intel_lvds.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 94232b94..80f77af6 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -372,7 +372,8 @@ void intel_lvds_init(struct drm_device *dev) u32 lvds; int pipe; - output = drm_output_create(dev, &intel_lvds_output_funcs, "LVDS"); + output = drm_output_create(dev, &intel_lvds_output_funcs, + DRM_MODE_OUTPUT_LVDS); if (!output) return; -- cgit v1.2.3 From fa116081a919e716eb95fcfa421d93f10f6f0a4f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 9 Apr 2008 11:30:15 -0700 Subject: Fixup sysfs output registration Put off registering new outputs with sysfs until they're properly configured, or we may get duplicates if the type hasn't been set yet (as is the case with SDVO initialization). This also means moving de-registration into the cleanup function instead of output destroy, since the latter occurs during the normal course of setup when an output isn't found (and therefore not registered with sysfs yet. --- linux-core/intel_lvds.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 80f77af6..378ce457 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -500,6 +500,7 @@ void intel_lvds_init(struct drm_device *dev) #endif out: + drm_sysfs_output_add(output); drm_output_attach_property(output, dev->mode_config.connector_type_property, ConnectorLVDS); return; -- cgit v1.2.3 From 0a6e301e6de3421f116d1b5d8205ca4f442091e2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 10 Apr 2008 11:23:55 -0700 Subject: Keep display info in struct display_info Some fields had snuck into the drm_output structure. Put them back and fill in more stuff from the EDID block. --- linux-core/intel_lvds.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 378ce457..92a1d600 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -298,24 +298,15 @@ static int intel_lvds_get_modes(struct drm_output *output) if (ret) return ret; - /* Didn't get an EDID */ - if (!output->monitor_info) { - struct drm_display_info *dspinfo; - dspinfo = kzalloc(sizeof(*output->monitor_info), GFP_KERNEL); - if (!dspinfo) - goto out; - - /* Set wide sync ranges so we get all modes - * handed to valid_mode for checking - */ - dspinfo->min_vfreq = 0; - dspinfo->max_vfreq = 200; - dspinfo->min_hfreq = 0; - dspinfo->max_hfreq = 200; - output->monitor_info = dspinfo; - } + /* Didn't get an EDID, so + * Set wide sync ranges so we get all modes + * handed to valid_mode for checking + */ + output->display_info.min_vfreq = 0; + output->display_info.max_vfreq = 200; + output->display_info.min_hfreq = 0; + output->display_info.max_hfreq = 200; -out: if (dev_priv->panel_fixed_mode != NULL) { struct drm_display_mode *mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); @@ -385,7 +376,7 @@ void intel_lvds_init(struct drm_device *dev) intel_output->type = INTEL_OUTPUT_LVDS; output->driver_private = intel_output; - output->subpixel_order = SubPixelHorizontalRGB; + output->display_info.subpixel_order = SubPixelHorizontalRGB; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; -- cgit v1.2.3 From ee631e1b8604a176b9118396998ce5bfc6475dae Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 13 May 2008 14:44:17 -0700 Subject: i915: register definition & header file cleanup It would be nice if one day the DRM driver was the canonical source for register definitions and core macros. To that end, this patch cleans things up quite a bit, removing redundant definitions (some with different names referring to the same register) and generally tidying up the header file. --- linux-core/intel_lvds.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 92a1d600..1da95e18 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -106,10 +106,10 @@ static void intel_lvds_save(struct drm_output *output) struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->savePP_ON = I915_READ(LVDSPP_ON); - dev_priv->savePP_OFF = I915_READ(LVDSPP_OFF); + dev_priv->savePP_ON = I915_READ(PP_ON_DELAYS); + dev_priv->savePP_OFF = I915_READ(PP_OFF_DELAYS); dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); - dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE); + dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & BACKLIGHT_DUTY_CYCLE_MASK); @@ -128,9 +128,9 @@ static void intel_lvds_restore(struct drm_output *output) struct drm_i915_private *dev_priv = dev->dev_private; I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); - I915_WRITE(LVDSPP_ON, dev_priv->savePP_ON); - I915_WRITE(LVDSPP_OFF, dev_priv->savePP_OFF); - I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE); + I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON); + I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF); + I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); if (dev_priv->savePP_CONTROL & POWER_TARGET_ON) intel_lvds_set_power(dev, true); -- cgit v1.2.3 From 9fc4ea5c00dfb91ebff893fb5092e768155cc2e2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 23 May 2008 18:42:47 -0700 Subject: i915: do a better job of parsing VBIOS data Add code to get panel modes from the VBIOS if present and check whether certain outputs exist. Should make our display detection code a little more robust. --- linux-core/intel_lvds.c | 48 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 1da95e18..6b6d3162 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -380,6 +380,17 @@ void intel_lvds_init(struct drm_device *dev) output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; + + /* + * LVDS discovery: + * 1) check for EDID on DDC + * 2) check for VBT data + * 3) check to see if LVDS is already on + * if none of the above, no panel + * 4) make sure lid is open + * if closed, act like it's not there for now + */ + /* Set up the DDC bus. */ intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); if (!intel_output->ddc_bus) { @@ -402,6 +413,11 @@ void intel_lvds_init(struct drm_device *dev) } } + /* Failed to get EDID, what about VBT? */ + if (dev_priv->vbt_mode) + dev_priv->panel_fixed_mode = + drm_mode_duplicate(dev, dev_priv->vbt_mode); + /* * 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 @@ -424,38 +440,8 @@ void intel_lvds_init(struct drm_device *dev) 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. - */ - bios_mode = intel_bios_get_panel_mode(pScrn); - if (bios_mode != NULL) { - if (dev_priv->panel_fixed_mode != NULL) { - if (dev_priv->debug_modes && - !xf86ModesEqual(dev_priv->panel_fixed_mode, - bios_mode)) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "BIOS panel mode data doesn't match probed data, " - "continuing with probed.\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS mode:\n"); - xf86PrintModeline(pScrn->scrnIndex, bios_mode); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "probed mode:\n"); - xf86PrintModeline(pScrn->scrnIndex, dev_priv->panel_fixed_mode); - xfree(bios_mode->name); - xfree(bios_mode); - } - } else { - dev_priv->panel_fixed_mode = bios_mode; - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Couldn't detect panel mode. Disabling panel\n"); - goto disable_exit; - } - + /* FIXME: detect aopen & mac mini type stuff automatically? */ /* * Blacklist machines with BIOSes that list an LVDS panel without * actually having one. -- cgit v1.2.3 From df8cd54286fbae5903d8ede390ec4a11cb6c4b6c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 May 2008 14:02:14 +1000 Subject: modesetting: reorganise code into core and helper functions. This splits a lot of the core modesetting code out into a file of helper functions, that are only called from themselves and/or the driver. The driver gets called into more often or can call these functions from itself if it is a helper using driver. I've broken framebuffer resize doing this but I didn't like the API for that in any case. --- linux-core/intel_lvds.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 6b6d3162..f71dd436 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -332,18 +332,21 @@ static void intel_lvds_destroy(struct drm_output *output) kfree(output->driver_private); } -static const struct drm_output_funcs intel_lvds_output_funcs = { - .dpms = intel_lvds_dpms, - .save = intel_lvds_save, - .restore = intel_lvds_restore, - .mode_valid = intel_lvds_mode_valid, +static const struct drm_output_helper_funcs intel_lvds_helper_funcs = { .mode_fixup = intel_lvds_mode_fixup, .prepare = intel_lvds_prepare, .mode_set = intel_lvds_mode_set, .commit = intel_lvds_commit, +}; + +static const struct drm_output_funcs intel_lvds_output_funcs = { + .dpms = intel_lvds_dpms, + .save = intel_lvds_save, + .restore = intel_lvds_restore, .detect = intel_lvds_detect, .get_modes = intel_lvds_get_modes, - .cleanup = intel_lvds_destroy + .cleanup = intel_lvds_destroy, + .mode_valid = intel_lvds_mode_valid, }; /** @@ -375,6 +378,7 @@ void intel_lvds_init(struct drm_device *dev) } intel_output->type = INTEL_OUTPUT_LVDS; + drm_output_helper_add(output, &intel_lvds_helper_funcs); output->driver_private = intel_output; output->display_info.subpixel_order = SubPixelHorizontalRGB; output->interlace_allowed = FALSE; -- cgit v1.2.3 From 98c5cf7f6fc51f1a8f5f90b3895009cd38dd8f22 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 11:25:41 +1000 Subject: modesetting: reorganise out crtc/outputs are allocated. Use subclassing from the drivers to allocate the objects. This saves two objects being allocated for each crtc/output and generally makes exit paths cleaner. --- linux-core/intel_lvds.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index f71dd436..6781a47c 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -161,7 +161,7 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = output->crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc); struct drm_output *tmp_output; /* Should never happen!! */ @@ -241,7 +241,7 @@ static void intel_lvds_mode_set(struct drm_output *output, { struct drm_device *dev = output->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = output->crtc->driver_private; + struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc); u32 pfit_control; /* @@ -326,10 +326,11 @@ static int intel_lvds_get_modes(struct drm_output *output) */ static void intel_lvds_destroy(struct drm_output *output) { - struct intel_output *intel_output = output->driver_private; + struct intel_output *intel_output = to_intel_output(output); intel_i2c_destroy(intel_output->ddc_bus); - kfree(output->driver_private); + drm_output_cleanup(output); + kfree(output); } static const struct drm_output_helper_funcs intel_lvds_helper_funcs = { @@ -345,7 +346,7 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { .restore = intel_lvds_restore, .detect = intel_lvds_detect, .get_modes = intel_lvds_get_modes, - .cleanup = intel_lvds_destroy, + .destroy = intel_lvds_destroy, .mode_valid = intel_lvds_mode_valid, }; @@ -359,27 +360,25 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { void intel_lvds_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_output *output; struct intel_output *intel_output; + struct drm_output *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, - DRM_MODE_OUTPUT_LVDS); - if (!output) - return; - intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) { - drm_output_destroy(output); return; } + output = &intel_output->base; + drm_output_init(dev, &intel_output->base, &intel_lvds_output_funcs, + DRM_MODE_OUTPUT_LVDS); + intel_output->type = INTEL_OUTPUT_LVDS; + drm_output_helper_add(output, &intel_lvds_helper_funcs); - output->driver_private = intel_output; output->display_info.subpixel_order = SubPixelHorizontalRGB; output->interlace_allowed = FALSE; output->doublescan_allowed = FALSE; @@ -400,6 +399,7 @@ void intel_lvds_init(struct drm_device *dev) if (!intel_output->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); + intel_lvds_destroy(output); return; } @@ -487,5 +487,5 @@ out: failed: DRM_DEBUG("No LVDS modes found, disabling.\n"); - drm_output_destroy(output); /* calls intel_lvds_destroy above */ + intel_lvds_destroy(output); } -- cgit v1.2.3 From 9d38448ed33aaff324cc4bbe1e0878593e97d07d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 30 May 2008 15:03:12 +1000 Subject: modesetting: the great renaming. Okay we have crtc, encoder and connectors. No more outputs exposed beyond driver internals I've broken intel tv connector stuff. Really for TV we should have one TV connector, with a sub property for the type of signal been driven over it --- linux-core/intel_lvds.c | 127 ++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 57 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 6781a47c..019c45fe 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -89,9 +89,9 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) } } -static void intel_lvds_dpms(struct drm_output *output, int mode) +static void intel_lvds_dpms(struct drm_connector *connector, int mode) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; if (mode == DPMSModeOn) intel_lvds_set_power(dev, true); @@ -101,9 +101,9 @@ static void intel_lvds_dpms(struct drm_output *output, int mode) /* XXX: We never power down the LVDS pairs. */ } -static void intel_lvds_save(struct drm_output *output) +static void intel_lvds_save(struct drm_connector *connector) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; dev_priv->savePP_ON = I915_READ(PP_ON_DELAYS); @@ -122,9 +122,9 @@ static void intel_lvds_save(struct drm_output *output) intel_lvds_get_max_backlight(dev); } -static void intel_lvds_restore(struct drm_output *output) +static void intel_lvds_restore(struct drm_connector *connector) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); @@ -138,10 +138,10 @@ static void intel_lvds_restore(struct drm_output *output) intel_lvds_set_power(dev, false); } -static int intel_lvds_mode_valid(struct drm_output *output, +static int intel_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; @@ -155,14 +155,14 @@ static int intel_lvds_mode_valid(struct drm_output *output, return MODE_OK; } -static bool intel_lvds_mode_fixup(struct drm_output *output, +static bool intel_lvds_mode_fixup(struct drm_connector *connector, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc); - struct drm_output *tmp_output; + struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc); + struct drm_connector *tmp_connector; /* Should never happen!! */ if (!IS_I965G(dev) && intel_crtc->pipe == 0) { @@ -171,10 +171,10 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, } /* Should never happen!! */ - list_for_each_entry(tmp_output, &dev->mode_config.output_list, head) { - if (tmp_output != output && tmp_output->crtc == output->crtc) { + list_for_each_entry(tmp_connector, &dev->mode_config.connector_list, head) { + if (tmp_connector != connector && tmp_connector->crtc == connector->crtc) { printk(KERN_ERR "Can't enable LVDS and another " - "output on the same pipe\n"); + "connector on the same pipe\n"); return false; } } @@ -211,9 +211,9 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, return true; } -static void intel_lvds_prepare(struct drm_output *output) +static void intel_lvds_prepare(struct drm_connector *connector) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); @@ -223,9 +223,9 @@ static void intel_lvds_prepare(struct drm_output *output) intel_lvds_set_power(dev, false); } -static void intel_lvds_commit( struct drm_output *output) +static void intel_lvds_commit( struct drm_connector *connector) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; if (dev_priv->backlight_duty_cycle == 0) @@ -235,13 +235,13 @@ static void intel_lvds_commit( struct drm_output *output) intel_lvds_set_power(dev, true); } -static void intel_lvds_mode_set(struct drm_output *output, +static void intel_lvds_mode_set(struct drm_connector *connector, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc); + struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc); u32 pfit_control; /* @@ -276,24 +276,25 @@ static void intel_lvds_mode_set(struct drm_output *output, /** * Detect the LVDS connection. * - * This always returns OUTPUT_STATUS_CONNECTED. This output should only have + * This always returns CONNECTOR_STATUS_CONNECTED. This connector should only have * been set up if the LVDS was actually connected anyway. */ -static enum drm_output_status intel_lvds_detect(struct drm_output *output) +static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) { - return output_status_connected; + return connector_status_connected; } /** * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. */ -static int intel_lvds_get_modes(struct drm_output *output) +static int intel_lvds_get_modes(struct drm_connector *connector) { - struct drm_device *dev = output->dev; + struct drm_device *dev = connector->dev; + struct intel_output *intel_output = to_intel_output(connector); struct drm_i915_private *dev_priv = dev->dev_private; int ret = 0; - ret = intel_ddc_get_modes(output); + ret = intel_ddc_get_modes(intel_output); if (ret) return ret; @@ -302,15 +303,15 @@ static int intel_lvds_get_modes(struct drm_output *output) * Set wide sync ranges so we get all modes * handed to valid_mode for checking */ - output->display_info.min_vfreq = 0; - output->display_info.max_vfreq = 200; - output->display_info.min_hfreq = 0; - output->display_info.max_hfreq = 200; + connector->display_info.min_vfreq = 0; + connector->display_info.max_vfreq = 200; + connector->display_info.min_hfreq = 0; + connector->display_info.max_hfreq = 200; if (dev_priv->panel_fixed_mode != NULL) { struct drm_display_mode *mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); - drm_mode_probed_add(output, mode); + drm_mode_probed_add(connector, mode); return 1; } @@ -319,28 +320,28 @@ static int intel_lvds_get_modes(struct drm_output *output) /** * intel_lvds_destroy - unregister and free LVDS structures - * @output: output to free + * @connector: connector to free * - * Unregister the DDC bus for this output then free the driver private + * Unregister the DDC bus for this connector then free the driver private * structure. */ -static void intel_lvds_destroy(struct drm_output *output) +static void intel_lvds_destroy(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(output); + struct intel_output *intel_output = to_intel_output(connector); intel_i2c_destroy(intel_output->ddc_bus); - drm_output_cleanup(output); - kfree(output); + drm_connector_cleanup(connector); + kfree(connector); } -static const struct drm_output_helper_funcs intel_lvds_helper_funcs = { +static const struct drm_connector_helper_funcs intel_lvds_helper_funcs = { .mode_fixup = intel_lvds_mode_fixup, .prepare = intel_lvds_prepare, .mode_set = intel_lvds_mode_set, .commit = intel_lvds_commit, }; -static const struct drm_output_funcs intel_lvds_output_funcs = { +static const struct drm_connector_funcs intel_lvds_connector_funcs = { .dpms = intel_lvds_dpms, .save = intel_lvds_save, .restore = intel_lvds_restore, @@ -350,18 +351,28 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { .mode_valid = intel_lvds_mode_valid, }; + +static void intel_lvds_enc_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +static const struct drm_encoder_funcs intel_lvds_enc_funcs = { + .destroy = intel_lvds_enc_destroy, +}; + /** - * intel_lvds_init - setup LVDS outputs on this device + * intel_lvds_init - setup LVDS connectors on this device * @dev: drm device * - * Create the output, register the LVDS DDC bus, and try to figure out what + * Create the connector, register the LVDS DDC bus, and try to figure out what * modes we can display on the LVDS panel (if present). */ void intel_lvds_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_output *intel_output; - struct drm_output *output; + struct drm_connector *connector; struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_crtc *crtc; u32 lvds; @@ -372,16 +383,19 @@ void intel_lvds_init(struct drm_device *dev) return; } - output = &intel_output->base; - drm_output_init(dev, &intel_output->base, &intel_lvds_output_funcs, - DRM_MODE_OUTPUT_LVDS); + connector = &intel_output->base; + drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + + drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs, + DRM_MODE_ENCODER_LVDS); intel_output->type = INTEL_OUTPUT_LVDS; - drm_output_helper_add(output, &intel_lvds_helper_funcs); - output->display_info.subpixel_order = SubPixelHorizontalRGB; - output->interlace_allowed = FALSE; - output->doublescan_allowed = FALSE; + drm_connector_helper_add(connector, &intel_lvds_helper_funcs); + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->interlace_allowed = FALSE; + connector->doublescan_allowed = FALSE; /* @@ -399,7 +413,7 @@ void intel_lvds_init(struct drm_device *dev) if (!intel_output->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); - intel_lvds_destroy(output); + intel_lvds_destroy(connector); return; } @@ -407,9 +421,9 @@ void intel_lvds_init(struct drm_device *dev) * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. */ - intel_ddc_get_modes(output); + intel_ddc_get_modes(intel_output); - list_for_each_entry(scan, &output->probed_modes, head) { + list_for_each_entry(scan, &connector->probed_modes, head) { if (scan->type & DRM_MODE_TYPE_PREFERRED) { dev_priv->panel_fixed_mode = drm_mode_duplicate(dev, scan); @@ -481,11 +495,10 @@ void intel_lvds_init(struct drm_device *dev) #endif out: - drm_sysfs_output_add(output); - drm_output_attach_property(output, dev->mode_config.connector_type_property, ConnectorLVDS); + drm_sysfs_connector_add(connector); return; failed: DRM_DEBUG("No LVDS modes found, disabling.\n"); - intel_lvds_destroy(output); + intel_lvds_destroy(connector); } -- cgit v1.2.3 From e439e74776b215d70d8e34e8aa9cea22179dcbc6 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 10:05:54 +1000 Subject: drm/modesetting: another re-org of some internals. Move dpms into the helper functions. Move crtc into the encoder. Move disable unused functions into the helper. --- linux-core/intel_lvds.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 019c45fe..b83f3923 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -89,9 +89,9 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) } } -static void intel_lvds_dpms(struct drm_connector *connector, int mode) +static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; if (mode == DPMSModeOn) intel_lvds_set_power(dev, true); @@ -155,14 +155,14 @@ static int intel_lvds_mode_valid(struct drm_connector *connector, return MODE_OK; } -static bool intel_lvds_mode_fixup(struct drm_connector *connector, +static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc); - struct drm_connector *tmp_connector; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + struct drm_encoder *tmp_encoder; /* Should never happen!! */ if (!IS_I965G(dev) && intel_crtc->pipe == 0) { @@ -171,10 +171,10 @@ static bool intel_lvds_mode_fixup(struct drm_connector *connector, } /* Should never happen!! */ - list_for_each_entry(tmp_connector, &dev->mode_config.connector_list, head) { - if (tmp_connector != connector && tmp_connector->crtc == connector->crtc) { + list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { + if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { printk(KERN_ERR "Can't enable LVDS and another " - "connector on the same pipe\n"); + "encoder on the same pipe\n"); return false; } } @@ -211,9 +211,9 @@ static bool intel_lvds_mode_fixup(struct drm_connector *connector, return true; } -static void intel_lvds_prepare(struct drm_connector *connector) +static void intel_lvds_prepare(struct drm_encoder *encoder) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); @@ -223,9 +223,9 @@ static void intel_lvds_prepare(struct drm_connector *connector) intel_lvds_set_power(dev, false); } -static void intel_lvds_commit( struct drm_connector *connector) +static void intel_lvds_commit( struct drm_encoder *encoder) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; if (dev_priv->backlight_duty_cycle == 0) @@ -235,13 +235,13 @@ static void intel_lvds_commit( struct drm_connector *connector) intel_lvds_set_power(dev, true); } -static void intel_lvds_mode_set(struct drm_connector *connector, +static void intel_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = connector->dev; + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); u32 pfit_control; /* @@ -334,7 +334,8 @@ static void intel_lvds_destroy(struct drm_connector *connector) kfree(connector); } -static const struct drm_connector_helper_funcs intel_lvds_helper_funcs = { +static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { + .dpms = intel_lvds_dpms, .mode_fixup = intel_lvds_mode_fixup, .prepare = intel_lvds_prepare, .mode_set = intel_lvds_mode_set, @@ -342,7 +343,6 @@ static const struct drm_connector_helper_funcs intel_lvds_helper_funcs = { }; static const struct drm_connector_funcs intel_lvds_connector_funcs = { - .dpms = intel_lvds_dpms, .save = intel_lvds_save, .restore = intel_lvds_restore, .detect = intel_lvds_detect, @@ -373,6 +373,7 @@ void intel_lvds_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_output *intel_output; struct drm_connector *connector; + struct drm_encoder *encoder; struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_crtc *crtc; u32 lvds; @@ -384,6 +385,7 @@ void intel_lvds_init(struct drm_device *dev) } connector = &intel_output->base; + encoder = &intel_output->enc; drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs, DRM_MODE_CONNECTOR_LVDS); @@ -392,7 +394,7 @@ void intel_lvds_init(struct drm_device *dev) intel_output->type = INTEL_OUTPUT_LVDS; - drm_connector_helper_add(connector, &intel_lvds_helper_funcs); + drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = FALSE; connector->doublescan_allowed = FALSE; -- cgit v1.2.3 From 0dd000b578adec6ff101c957bce7dc9a32b76713 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 11:12:28 +1000 Subject: drm/modesetting: move some connector functions to helper. Migrated the output mode collection into the helper. --- linux-core/intel_lvds.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index b83f3923..cbe8b53d 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -342,13 +342,17 @@ static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { .commit = intel_lvds_commit, }; +static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { + .get_modes = intel_lvds_get_modes, + .mode_valid = intel_lvds_mode_valid, +}; + static const struct drm_connector_funcs intel_lvds_connector_funcs = { .save = intel_lvds_save, .restore = intel_lvds_restore, .detect = intel_lvds_detect, - .get_modes = intel_lvds_get_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .destroy = intel_lvds_destroy, - .mode_valid = intel_lvds_mode_valid, }; @@ -361,6 +365,8 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = { .destroy = intel_lvds_enc_destroy, }; + + /** * intel_lvds_init - setup LVDS connectors on this device * @dev: drm device @@ -395,6 +401,7 @@ void intel_lvds_init(struct drm_device *dev) intel_output->type = INTEL_OUTPUT_LVDS; drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); + drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = FALSE; connector->doublescan_allowed = FALSE; -- cgit v1.2.3 From 46c78a2223802b9105a87b7125fd4872ab69c4ca Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 11:44:35 +1000 Subject: drm/modesetting: add best encoder finding for modesetting This asks the driver to suggest the best encoder for the connector during the pick crtcs stage. Need to also do this during mode setting stages --- linux-core/intel_lvds.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index cbe8b53d..f2fe4612 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -345,6 +345,7 @@ static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { .get_modes = intel_lvds_get_modes, .mode_valid = intel_lvds_mode_valid, + .best_encoder = intel_best_encoder, }; static const struct drm_connector_funcs intel_lvds_connector_funcs = { @@ -398,6 +399,7 @@ void intel_lvds_init(struct drm_device *dev) drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); + drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); intel_output->type = INTEL_OUTPUT_LVDS; drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); -- cgit v1.2.3 From 58aca7485a4cd9fcccc6e4044325048abcc2f9c7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 4 Jun 2008 13:03:23 +1000 Subject: drm: remove sysfs in driver for now.. should probably be in helper --- linux-core/intel_lvds.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index f2fe4612..cf9294ee 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -330,6 +330,7 @@ static void intel_lvds_destroy(struct drm_connector *connector) struct intel_output *intel_output = to_intel_output(connector); intel_i2c_destroy(intel_output->ddc_bus); + drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); kfree(connector); } -- cgit v1.2.3 From e90716671d7a5dabf13c22a339f750dba77f438a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 4 Jun 2008 12:50:03 -0700 Subject: i915: use kzalloc to allocate intel_output for lvds Better to initialize all the struct fields to 0. Also more consistent with other output init routines. --- linux-core/intel_lvds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index cf9294ee..8d65c161 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -387,7 +387,7 @@ void intel_lvds_init(struct drm_device *dev) u32 lvds; int pipe; - intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL); + intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) { return; } -- cgit v1.2.3 From 03bf1fba67413f381d2a548fe08bd634a48fcc48 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 5 Jun 2008 15:58:43 -0700 Subject: sysfs registration/teardown fixups A check in drm_sysfs_connector_remove was supposed to allow it to be called even with unregistered objects, to make cleanup paths a little simpler. However, device_is_regsitered didn't always seem to return what we thought it would, so we'd sometimes end up leaving objects lying around rather than unregistering them. Fix this situation up by requiring devices to be registered before being removed. Any problems resulting from this change should be easier to track down than the alternative (which is leaving kobjects registered after unload). --- linux-core/intel_lvds.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 8d65c161..04e110e4 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -329,7 +329,8 @@ static void intel_lvds_destroy(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_output->ddc_bus) + intel_i2c_destroy(intel_output->ddc_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); kfree(connector); @@ -425,8 +426,7 @@ void intel_lvds_init(struct drm_device *dev) if (!intel_output->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); - intel_lvds_destroy(connector); - return; + goto failed; } /* @@ -470,19 +470,18 @@ void intel_lvds_init(struct drm_device *dev) if (!dev_priv->panel_fixed_mode) goto failed; -#if 0 /* FIXME: detect aopen & mac mini type stuff automatically? */ /* * Blacklist machines with BIOSes that list an LVDS panel without * actually having one. */ - if (dev_priv->PciInfo->chipType == PCI_CHIP_I945_GM) { + if (IS_I945GM(dev)) { /* aopen mini pc */ - if (dev_priv->PciInfo->subsysVendor == 0xa0a0) - goto disable_exit; + if (dev->pdev->subsystem_vendor == 0xa0a0) + goto failed; - if ((dev_priv->PciInfo->subsysVendor == 0x8086) && - (dev_priv->PciInfo->subsysCard == 0x7270)) { + if ((dev->pdev->subsystem_vendor == 0x8086) && + (dev->pdev->subsystem_device == 0x7270)) { /* It's a Mac Mini or Macbook Pro. * * Apple hardware is out to get us. The macbook pro @@ -494,23 +493,23 @@ void intel_lvds_init(struct drm_device *dev) */ 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; + dev_priv->panel_fixed_mode->hdisplay == 800 && + dev_priv->panel_fixed_mode->vdisplay == 600) { + DRM_DEBUG("Suspected Mac Mini, ignoring the LVDS\n"); + goto failed; } } } -#endif out: drm_sysfs_connector_add(connector); return; failed: - DRM_DEBUG("No LVDS modes found, disabling.\n"); - intel_lvds_destroy(connector); + DRM_DEBUG("No LVDS modes found, disabling.\n"); + if (intel_output->ddc_bus) + intel_i2c_destroy(intel_output->ddc_bus); + drm_connector_cleanup(connector); + kfree(connector); } -- cgit v1.2.3 From 6738e7b00bf05529303ed690873495db6d83337c Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 6 Jul 2008 11:08:49 +0200 Subject: modesetting-101: Rename DPMS modes to avoid compatibility issues with xorg definitions. --- linux-core/intel_lvds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 04e110e4..06b99867 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -93,7 +93,7 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; - if (mode == DPMSModeOn) + if (mode == DRM_MODE_DPMS_ON) intel_lvds_set_power(dev, true); else intel_lvds_set_power(dev, false); -- cgit v1.2.3 From 7fd8a5de63781f6faa053509c80e02e8f1cdbb69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 7 Jul 2008 11:56:59 -0400 Subject: Use lowercase bool constants. --- linux-core/intel_lvds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux-core/intel_lvds.c') diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 04e110e4..69d88497 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -407,8 +407,8 @@ void intel_lvds_init(struct drm_device *dev) drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = FALSE; - connector->doublescan_allowed = FALSE; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; /* -- cgit v1.2.3