51,6 → 51,7 |
|
bool is_dual_link; |
u32 reg; |
u32 a3_power; |
|
struct intel_lvds_connector *attached_connector; |
}; |
71,8 → 72,13 |
struct drm_device *dev = encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
enum intel_display_power_domain power_domain; |
u32 tmp; |
|
power_domain = intel_display_port_power_domain(encoder); |
if (!intel_display_power_enabled(dev_priv, power_domain)) |
return false; |
|
tmp = I915_READ(lvds_encoder->reg); |
|
if (!(tmp & LVDS_PORT_EN)) |
126,10 → 132,6 |
pipe_config->adjusted_mode.crtc_clock = dotclock; |
} |
|
/* The LVDS pin pair needs to be on before the DPLLs are enabled. |
* This is an exception to the general rule that mode_set doesn't turn |
* things on. |
*/ |
static void intel_pre_enable_lvds(struct intel_encoder *encoder) |
{ |
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
176,8 → 178,11 |
|
/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) |
* appropriately here, but we need to look more thoroughly into how |
* panels behave in the two modes. |
* panels behave in the two modes. For now, let's just maintain the |
* value we got from the BIOS. |
*/ |
temp &= ~LVDS_A3_POWER_MASK; |
temp |= lvds_encoder->a3_power; |
|
/* Set the dithering flag on LVDS as needed, note that there is no |
* special lvds dither control bit on pch-split platforms, dithering is |
275,7 → 280,6 |
struct intel_crtc_config *pipe_config) |
{ |
struct drm_device *dev = intel_encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_lvds_encoder *lvds_encoder = |
to_lvds_encoder(&intel_encoder->base); |
struct intel_connector *intel_connector = |
290,8 → 294,7 |
return false; |
} |
|
if ((I915_READ(lvds_encoder->reg) & LVDS_A3_POWER_MASK) == |
LVDS_A3_POWER_UP) |
if (lvds_encoder->a3_power == LVDS_A3_POWER_UP) |
lvds_bpp = 8*3; |
else |
lvds_bpp = 6*3; |
331,15 → 334,6 |
return true; |
} |
|
static void intel_lvds_mode_set(struct intel_encoder *encoder) |
{ |
/* |
* We don't do anything here, the LVDS port is fully set up in the pre |
* enable hook - the ordering constraints for enabling the lvds port vs. |
* enabling the display pll are too strict. |
*/ |
} |
|
/** |
* Detect the LVDS connection. |
* |
354,7 → 348,7 |
enum drm_connector_status status; |
|
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
connector->base.id, drm_get_connector_name(connector)); |
connector->base.id, connector->name); |
|
status = intel_panel_detect(dev); |
if (status != connector_status_unknown) |
848,8 → 842,8 |
struct drm_i915_private *dev_priv = dev->dev_private; |
|
/* use the module option value if specified */ |
if (i915_lvds_channel_mode > 0) |
return i915_lvds_channel_mode == 2; |
if (i915.lvds_channel_mode > 0) |
return i915.lvds_channel_mode == 2; |
|
// if (dmi_check_system(intel_dual_link_lvds)) |
// return true; |
899,6 → 893,7 |
struct drm_encoder *encoder; |
struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
struct drm_display_mode *fixed_mode = NULL; |
struct drm_display_mode *downclock_mode = NULL; |
struct edid *edid; |
struct drm_crtc *crtc; |
u32 lvds; |
952,16 → 947,16 |
intel_encoder->enable = intel_enable_lvds; |
intel_encoder->pre_enable = intel_pre_enable_lvds; |
intel_encoder->compute_config = intel_lvds_compute_config; |
intel_encoder->mode_set = intel_lvds_mode_set; |
intel_encoder->disable = intel_disable_lvds; |
intel_encoder->get_hw_state = intel_lvds_get_hw_state; |
intel_encoder->get_config = intel_lvds_get_config; |
intel_connector->get_hw_state = intel_connector_get_hw_state; |
intel_connector->unregister = intel_connector_unregister; |
|
intel_connector_attach_encoder(intel_connector, intel_encoder); |
intel_encoder->type = INTEL_OUTPUT_LVDS; |
|
intel_encoder->cloneable = false; |
intel_encoder->cloneable = 0; |
if (HAS_PCH_SPLIT(dev)) |
intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
else if (IS_GEN4(dev)) |
1000,6 → 995,7 |
* Attempt to get the fixed panel mode from DDC. Assume that the |
* preferred mode is the right one. |
*/ |
mutex_lock(&dev->mode_config.mutex); |
edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, pin)); |
if (edid) { |
if (drm_add_edid_modes(connector, edid)) { |
1032,15 → 1028,14 |
|
fixed_mode = drm_mode_duplicate(dev, scan); |
if (fixed_mode) { |
intel_connector->panel.downclock_mode = |
downclock_mode = |
intel_find_panel_downclock(dev, |
fixed_mode, connector); |
if (intel_connector->panel.downclock_mode != |
NULL && i915_lvds_downclock) { |
if (downclock_mode != NULL && |
i915.lvds_downclock) { |
/* We found the downclock for LVDS. */ |
dev_priv->lvds_downclock_avail = true; |
dev_priv->lvds_downclock = |
intel_connector->panel. |
downclock_mode->clock; |
DRM_DEBUG_KMS("LVDS downclock is found" |
" in EDID. Normal clock %dKhz, " |
1094,10 → 1089,15 |
goto failed; |
|
out: |
mutex_unlock(&dev->mode_config.mutex); |
|
lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); |
DRM_DEBUG_KMS("detected %s-link lvds configuration\n", |
lvds_encoder->is_dual_link ? "dual" : "single"); |
|
lvds_encoder->a3_power = I915_READ(lvds_encoder->reg) & |
LVDS_A3_POWER_MASK; |
|
/* |
* Unlock registers and just |
* leave them unlocked |
1109,24 → 1109,19 |
I915_WRITE(PP_CONTROL, |
I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); |
} |
// dev_priv->lid_notifier.notifier_call = intel_lid_notify; |
// if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { |
// DRM_DEBUG_KMS("lid notifier registration failed\n"); |
// dev_priv->lid_notifier.notifier_call = NULL; |
// } |
drm_sysfs_connector_add(connector); |
drm_connector_register(connector); |
|
intel_panel_init(&intel_connector->panel, fixed_mode); |
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); |
intel_panel_setup_backlight(connector); |
|
return; |
|
failed: |
mutex_unlock(&dev->mode_config.mutex); |
|
DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); |
drm_connector_cleanup(connector); |
drm_encoder_cleanup(encoder); |
if (fixed_mode) |
drm_mode_destroy(dev, fixed_mode); |
kfree(lvds_encoder); |
kfree(lvds_connector); |
return; |