@@ -283,6 +283,12 @@ typedef struct drm_i915_private {
/* Register state */
bool modeset_on_lid;
+ /*
+ * record the pipe used by LVDS.
+ * 0 means the pipe A.
+ * 1 means the PIPE B
+ */
+ int lvds_pipe;
u8 saveLBB;
u32 saveDSPACNTR;
u32 saveDSPBCNTR;
@@ -3183,7 +3183,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
lvds_reg = PCH_LVDS;
lvds = I915_READ(lvds_reg);
- lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
+ lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
+ /* select the correct pipe for LVDS */
+ if (dev_priv->lvds_pipe)
+ lvds |= LVDS_PIPEB_SELECT;
/* set the corresponsding LVDS_BORDER bit */
lvds |= dev_priv->lvds_border_bits;
/* Set the B0-B3 data pairs corresponding to whether we're going to
@@ -1069,6 +1069,23 @@ void intel_lvds_init(struct drm_device *dev)
intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
intel_output->crtc_mask = (1 << 1);
+ /*
+ * By default we will use the pipe B for LVDS. But we can also use
+ * pipe A for integrated LVDS on the 965/g4x/Ironlake platform.
+ * If the BIOS select the pipe A for LVDS, we can also use pipe A
+ * for LVDS. In such case we will change the crtc mask for LVDS.
+ */
+ dev_priv->lvds_pipe = 1;
+ if (IS_I965G(dev)) {
+ if (IS_IGDNG(dev))
+ lvds = I915_READ(PCH_LVDS);
+ else
+ lvds = I915_READ(LVDS);
+ if ((lvds & LVDS_PORT_EN) && !(lvds & LVDS_PIPEB_SELECT)) {
+ dev_priv->lvds_pipe = 0;
+ intel_output->crtc_mask = (1 << 0);
+ }
+ }
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;