Commit 27f8227b authored by Jesse Barnes's avatar Jesse Barnes Committed by Keith Packard

drm/i915: support 3 pipes on IVB+

Well almost anyway.  IVB has 3 planes, pipes, transcoders, and FDI
interfaces, but only 2 pipe PLLs.  So two of the pipes must use the same
pipe timings (e.g. 2 DP plus one other, or two HDMI with the same mode
and one other, etc.).
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Tested-By: default avatarEugeni Dodonov <eugeni.dodonov@intel.com>
Reviewed-By: default avatarEugeni Dodonov <eugeni.dodonov@intel.com>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent 4c609cb8
...@@ -2035,7 +2035,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -2035,7 +2035,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
spin_lock_init(&dev_priv->error_lock); spin_lock_init(&dev_priv->error_lock);
spin_lock_init(&dev_priv->rps_lock); spin_lock_init(&dev_priv->rps_lock);
if (IS_MOBILE(dev) || !IS_GEN2(dev)) if (IS_IVYBRIDGE(dev))
dev_priv->num_pipe = 3;
else if (IS_MOBILE(dev) || !IS_GEN2(dev))
dev_priv->num_pipe = 2; dev_priv->num_pipe = 2;
else else
dev_priv->num_pipe = 1; dev_priv->num_pipe = 1;
......
...@@ -674,8 +674,8 @@ typedef struct drm_i915_private { ...@@ -674,8 +674,8 @@ typedef struct drm_i915_private {
/* Panel fitter placement and size for Ironlake+ */ /* Panel fitter placement and size for Ironlake+ */
u32 pch_pf_pos, pch_pf_size; u32 pch_pf_pos, pch_pf_size;
struct drm_crtc *plane_to_crtc_mapping[2]; struct drm_crtc *plane_to_crtc_mapping[3];
struct drm_crtc *pipe_to_crtc_mapping[2]; struct drm_crtc *pipe_to_crtc_mapping[3];
wait_queue_head_t pending_flip_queue; wait_queue_head_t pending_flip_queue;
bool flip_pending_is_done; bool flip_pending_is_done;
......
...@@ -2092,6 +2092,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc, ...@@ -2092,6 +2092,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
switch (plane) { switch (plane) {
case 0: case 0:
case 1: case 1:
case 2:
break; break;
default: default:
DRM_ERROR("Can't update plane %d in SAREA\n", plane); DRM_ERROR("Can't update plane %d in SAREA\n", plane);
...@@ -2191,6 +2192,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -2191,6 +2192,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
case 0: case 0:
case 1: case 1:
break; break;
case 2:
if (IS_IVYBRIDGE(dev))
break;
/* fall through otherwise */
default: default:
DRM_ERROR("no plane for crtc\n"); DRM_ERROR("no plane for crtc\n");
return -EINVAL; return -EINVAL;
...@@ -2889,6 +2894,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) ...@@ -2889,6 +2894,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL);
else if (pipe == 1 && (temp & TRANSB_DPLL_ENABLE) == 0) else if (pipe == 1 && (temp & TRANSB_DPLL_ENABLE) == 0)
temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL);
else if (pipe == 2 && (temp & TRANSC_DPLL_ENABLE) == 0)
temp |= (TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL);
I915_WRITE(PCH_DPLL_SEL, temp); I915_WRITE(PCH_DPLL_SEL, temp);
} }
......
...@@ -2215,7 +2215,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) ...@@ -2215,7 +2215,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
ironlake_panel_vdd_work); ironlake_panel_vdd_work);
} }
intel_encoder->crtc_mask = (1 << 0) | (1 << 1); intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
connector->interlace_allowed = true; connector->interlace_allowed = true;
connector->doublescan_allowed = 0; connector->doublescan_allowed = 0;
......
...@@ -514,7 +514,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) ...@@ -514,7 +514,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
connector->polled = DRM_CONNECTOR_POLL_HPD; connector->polled = DRM_CONNECTOR_POLL_HPD;
connector->interlace_allowed = 0; connector->interlace_allowed = 0;
connector->doublescan_allowed = 0; connector->doublescan_allowed = 0;
intel_encoder->crtc_mask = (1 << 0) | (1 << 1); intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
/* Set up the DDC bus. */ /* Set up the DDC bus. */
if (sdvox_reg == SDVOB) { if (sdvox_reg == SDVOB) {
......
...@@ -888,9 +888,11 @@ bool intel_lvds_init(struct drm_device *dev) ...@@ -888,9 +888,11 @@ bool intel_lvds_init(struct drm_device *dev)
intel_encoder->type = INTEL_OUTPUT_LVDS; intel_encoder->type = INTEL_OUTPUT_LVDS;
intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
intel_encoder->crtc_mask = (1 << 1); if (HAS_PCH_SPLIT(dev))
if (INTEL_INFO(dev)->gen >= 5) intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->crtc_mask |= (1 << 0); else
intel_encoder->crtc_mask = (1 << 1);
drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->display_info.subpixel_order = SubPixelHorizontalRGB;
......
...@@ -2203,7 +2203,7 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) ...@@ -2203,7 +2203,7 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
bytes[0], bytes[1]); bytes[0], bytes[1]);
return false; return false;
} }
intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1); intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment