[Intel-gfx] [PATCH V2] drm/i915: Choose sharing pipe according to encoder

Ma, Ling ling.ma at intel.com
Mon Jul 27 11:44:09 CEST 2009


In KMS mode this patch can help us to avoid incorrectly sharing pipe.
For example it is not allowed to share one pipe between integrated
TV and VGA according to Bspec.
Any comments ?

Thanks
Ma Ling 

>-----Original Message-----
>From: Ma, Ling
>Sent: 2009年7月21日 16:55
>To: eric at anholt.net
>Cc: intel-gfx at lists.freedesktop.org; Ma, Ling
>Subject: [PATCH V2] drm/i915: Choose sharing pipe according to encoder
>
>Based on Bspec each encoder has different sharing pipe property,
>i.e. Integrated or SDVO TV both will occupy one pipe exlusively,
>and sdvo-non-tv and crt are allowed to share one. The patch moves
>sharing judgment into differnet output functions, and set right
>clone bit.
>
>Signed-off-by: Ma Ling <ling.ma at intel.com>
>---
>In this version, set crtc_mask for each output, and update dvo output.
>
> drivers/gpu/drm/i915/intel_crt.c     |    4 +++
> drivers/gpu/drm/i915/intel_display.c |   45
>+++-------------------------------
> drivers/gpu/drm/i915/intel_dp.c      |    8 ++++++
> drivers/gpu/drm/i915/intel_drv.h     |   20 +++++++++++++++
> drivers/gpu/drm/i915/intel_dvo.c     |    6 ++++
> drivers/gpu/drm/i915/intel_hdmi.c    |   18 +++++++++----
> drivers/gpu/drm/i915/intel_lvds.c    |    2 +
> drivers/gpu/drm/i915/intel_sdvo.c    |   13 ++++++++++
> drivers/gpu/drm/i915/intel_tv.c      |    2 +
> 9 files changed, 71 insertions(+), 47 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/intel_crt.c
>b/drivers/gpu/drm/i915/intel_crt.c
>index d6a1a6e..62d1a94 100644
>--- a/drivers/gpu/drm/i915/intel_crt.c
>+++ b/drivers/gpu/drm/i915/intel_crt.c
>@@ -533,6 +533,10 @@ void intel_crt_init(struct drm_device *dev)
> 	}
>
> 	intel_output->type = INTEL_OUTPUT_ANALOG;
>+	intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
>+				   (1 << INTEL_ANALOG_CLONE_BIT) |
>+				   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
>+	intel_output->crtc_mask = (1 << 0) | (1 << 1);
> 	connector->interlace_allowed = 0;
> 	connector->doublescan_allowed = 0;
>
>diff --git a/drivers/gpu/drm/i915/intel_display.c
>b/drivers/gpu/drm/i915/intel_display.c
>index 3fa0d63..81978f2 100644
>--- a/drivers/gpu/drm/i915/intel_display.c
>+++ b/drivers/gpu/drm/i915/intel_display.c
>@@ -2967,7 +2967,7 @@ static int intel_connector_clones(struct drm_device *dev,
>int type_mask)
>
>         list_for_each_entry(connector, &dev->mode_config.connector_list,
>head) {
> 		struct intel_output *intel_output = to_intel_output(connector);
>-		if (type_mask & (1 << intel_output->type))
>+		if (type_mask & intel_output->clone_mask)
> 			index_mask |= (1 << entry);
> 		entry++;
> 	}
>@@ -3039,47 +3039,10 @@ static void intel_setup_outputs(struct drm_device *dev)
> 	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
>{
> 		struct intel_output *intel_output = to_intel_output(connector);
> 		struct drm_encoder *encoder = &intel_output->enc;
>-		int crtc_mask = 0, clone_mask = 0;
>
>-		/* valid crtcs */
>-		switch(intel_output->type) {
>-		case INTEL_OUTPUT_HDMI:
>-			crtc_mask = ((1 << 0)|
>-				     (1 << 1));
>-			clone_mask = ((1 << INTEL_OUTPUT_HDMI));
>-			break;
>-		case INTEL_OUTPUT_DVO:
>-		case INTEL_OUTPUT_SDVO:
>-			crtc_mask = ((1 << 0)|
>-				     (1 << 1));
>-			clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
>-				      (1 << INTEL_OUTPUT_DVO) |
>-				      (1 << INTEL_OUTPUT_SDVO));
>-			break;
>-		case INTEL_OUTPUT_ANALOG:
>-			crtc_mask = ((1 << 0)|
>-				     (1 << 1));
>-			clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
>-				      (1 << INTEL_OUTPUT_DVO) |
>-				      (1 << INTEL_OUTPUT_SDVO));
>-			break;
>-		case INTEL_OUTPUT_LVDS:
>-			crtc_mask = (1 << 1);
>-			clone_mask = (1 << INTEL_OUTPUT_LVDS);
>-			break;
>-		case INTEL_OUTPUT_TVOUT:
>-			crtc_mask = ((1 << 0) |
>-				     (1 << 1));
>-			clone_mask = (1 << INTEL_OUTPUT_TVOUT);
>-			break;
>-		case INTEL_OUTPUT_DISPLAYPORT:
>-			crtc_mask = ((1 << 0) |
>-				     (1 << 1));
>-			clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
>-			break;
>-		}
>-		encoder->possible_crtcs = crtc_mask;
>-		encoder->possible_clones = intel_connector_clones(dev, clone_mask);
>+		encoder->possible_crtcs = intel_output->crtc_mask;
>+		encoder->possible_clones = intel_connector_clones(dev,
>+						intel_output->clone_mask);
> 	}
> }
>
>diff --git a/drivers/gpu/drm/i915/intel_dp.c
>b/drivers/gpu/drm/i915/intel_dp.c
>index 6770ae8..03d6f99 100644
>--- a/drivers/gpu/drm/i915/intel_dp.c
>+++ b/drivers/gpu/drm/i915/intel_dp.c
>@@ -1121,6 +1121,14 @@ intel_dp_init(struct drm_device *dev, int output_reg)
>
> 	intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
>
>+	if (output_reg == DP_B)
>+		intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
>+	else if (output_reg == DP_C)
>+		intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
>+	else if (output_reg == DP_D)
>+		intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
>+
>+	intel_output->crtc_mask = (1 << 0) | (1 << 1);
> 	connector->interlace_allowed = true;
> 	connector->doublescan_allowed = 0;
>
>diff --git a/drivers/gpu/drm/i915/intel_drv.h
>b/drivers/gpu/drm/i915/intel_drv.h
>index 004541c..3ffc1ff 100644
>--- a/drivers/gpu/drm/i915/intel_drv.h
>+++ b/drivers/gpu/drm/i915/intel_drv.h
>@@ -56,6 +56,24 @@
> #define INTEL_OUTPUT_HDMI 6
> #define INTEL_OUTPUT_DISPLAYPORT 7
>
>+/* Intel Pipe Clone Bit */
>+#define INTEL_HDMIB_CLONE_BIT 1
>+#define INTEL_HDMIC_CLONE_BIT 2
>+#define INTEL_HDMID_CLONE_BIT 3
>+#define INTEL_HDMIE_CLONE_BIT 4
>+#define INTEL_HDMIF_CLONE_BIT 5
>+#define INTEL_SDVO_NON_TV_CLONE_BIT 6
>+#define INTEL_SDVO_TV_CLONE_BIT 7
>+#define INTEL_SDVO_LVDS_CLONE_BIT 8
>+#define INTEL_ANALOG_CLONE_BIT 9
>+#define INTEL_TV_CLONE_BIT 10
>+#define INTEL_DP_B_CLONE_BIT 11
>+#define INTEL_DP_C_CLONE_BIT 12
>+#define INTEL_DP_D_CLONE_BIT 13
>+#define INTEL_LVDS_CLONE_BIT 14
>+#define INTEL_DVO_TMDS_CLONE_BIT 15
>+#define INTEL_DVO_LVDS_CLONE_BIT 15
>+
> #define INTEL_DVO_CHIP_NONE 0
> #define INTEL_DVO_CHIP_LVDS 1
> #define INTEL_DVO_CHIP_TMDS 2
>@@ -85,6 +103,8 @@ struct intel_output {
> 	bool needs_tv_clock;
> 	void *dev_priv;
> 	void (*hot_plug)(struct intel_output *);
>+	int crtc_mask;
>+	int clone_mask;
> };
>
> struct intel_crtc {
>diff --git a/drivers/gpu/drm/i915/intel_dvo.c
>b/drivers/gpu/drm/i915/intel_dvo.c
>index 13bff20..a4d2606 100644
>--- a/drivers/gpu/drm/i915/intel_dvo.c
>+++ b/drivers/gpu/drm/i915/intel_dvo.c
>@@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev)
> 			continue;
>
> 		intel_output->type = INTEL_OUTPUT_DVO;
>+		intel_output->crtc_mask = (1 << 0) | (1 << 1);
> 		switch (dvo->type) {
> 		case INTEL_DVO_CHIP_TMDS:
>+			intel_output->clone_mask =
>+				(1 << INTEL_DVO_TMDS_CLONE_BIT) |
>+				(1 << INTEL_ANALOG_CLONE_BIT);
> 			drm_connector_init(dev, connector,
> 					   &intel_dvo_connector_funcs,
> 					   DRM_MODE_CONNECTOR_DVII);
> 			encoder_type = DRM_MODE_ENCODER_TMDS;
> 			break;
> 		case INTEL_DVO_CHIP_LVDS:
>+			intel_output->clone_mask =
>+				(1 << INTEL_DVO_LVDS_CLONE_BIT);
> 			drm_connector_init(dev, connector,
> 					   &intel_dvo_connector_funcs,
> 					   DRM_MODE_CONNECTOR_LVDS);
>diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
>b/drivers/gpu/drm/i915/intel_hdmi.c
>index 9e30daa..e1ec162 100644
>--- a/drivers/gpu/drm/i915/intel_hdmi.c
>+++ b/drivers/gpu/drm/i915/intel_hdmi.c
>@@ -286,22 +286,28 @@ void intel_hdmi_init(struct drm_device *dev, int
>sdvox_reg)
>
> 	connector->interlace_allowed = 0;
> 	connector->doublescan_allowed = 0;
>+	intel_output->crtc_mask = (1 << 0) | (1 << 1);
>
> 	/* Set up the DDC bus. */
>-	if (sdvox_reg == SDVOB)
>+	if (sdvox_reg == SDVOB) {
>+		intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
> 		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
>-	else if (sdvox_reg == SDVOC)
>+	} else if (sdvox_reg == SDVOC) {
>+		intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
> 		intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
>-	else if (sdvox_reg == HDMIB)
>+	} else if (sdvox_reg == HDMIB) {
>+		intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
> 		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
> 								"HDMIB");
>-	else if (sdvox_reg == HDMIC)
>+	} else if (sdvox_reg == HDMIC) {
>+		intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
> 		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
> 								"HDMIC");
>-	else if (sdvox_reg == HDMID)
>+	} else if (sdvox_reg == HDMID) {
>+		intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
> 		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
> 								"HDMID");
>-
>+	}
> 	if (!intel_output->ddc_bus)
> 		goto err_connector;
>
>diff --git a/drivers/gpu/drm/i915/intel_lvds.c
>b/drivers/gpu/drm/i915/intel_lvds.c
>index 43c7d9a..7099ffb 100644
>--- a/drivers/gpu/drm/i915/intel_lvds.c
>+++ b/drivers/gpu/drm/i915/intel_lvds.c
>@@ -912,6 +912,8 @@ void intel_lvds_init(struct drm_device *dev)
> 	drm_mode_connector_attach_encoder(&intel_output->base,
>&intel_output->enc);
> 	intel_output->type = INTEL_OUTPUT_LVDS;
>
>+	intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
>+	intel_output->crtc_mask = (1 << 1);
> 	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;
>diff --git a/drivers/gpu/drm/i915/intel_sdvo.c
>b/drivers/gpu/drm/i915/intel_sdvo.c
>index 4f0c309..0a7388c 100644
>--- a/drivers/gpu/drm/i915/intel_sdvo.c
>+++ b/drivers/gpu/drm/i915/intel_sdvo.c
>@@ -1948,6 +1948,8 @@ bool intel_sdvo_init(struct drm_device *dev, int
>output_device)
> 						   SDVO_COLORIMETRY_RGB256);
> 			connector_type = DRM_MODE_CONNECTOR_HDMIA;
> 		}
>+		intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
>+					   (1 << INTEL_ANALOG_CLONE_BIT);
> 	}
> 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
> 	{
>@@ -1956,18 +1958,23 @@ bool intel_sdvo_init(struct drm_device *dev, int
>output_device)
> 		connector_type = DRM_MODE_CONNECTOR_SVIDEO;
> 		sdvo_priv->is_tv = true;
> 		intel_output->needs_tv_clock = true;
>+		intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
> 	}
> 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
> 	{
> 		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
> 		encoder_type = DRM_MODE_ENCODER_DAC;
> 		connector_type = DRM_MODE_CONNECTOR_VGA;
>+		intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
>+					   (1 << INTEL_ANALOG_CLONE_BIT);
> 	}
> 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
> 	{
> 		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
> 		encoder_type = DRM_MODE_ENCODER_DAC;
> 		connector_type = DRM_MODE_CONNECTOR_VGA;
>+		intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
>+					   (1 << INTEL_ANALOG_CLONE_BIT);
> 	}
> 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0)
> 	{
>@@ -1975,6 +1982,9 @@ bool intel_sdvo_init(struct drm_device *dev, int
>output_device)
> 		encoder_type = DRM_MODE_ENCODER_LVDS;
> 		connector_type = DRM_MODE_CONNECTOR_LVDS;
> 		sdvo_priv->is_lvds = true;
>+		intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
>+					   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
>+
> 	}
> 	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1)
> 	{
>@@ -1982,6 +1992,8 @@ bool intel_sdvo_init(struct drm_device *dev, int
>output_device)
> 		encoder_type = DRM_MODE_ENCODER_LVDS;
> 		connector_type = DRM_MODE_CONNECTOR_LVDS;
> 		sdvo_priv->is_lvds = true;
>+		intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
>+					   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
> 	}
> 	else
> 	{
>@@ -1998,6 +2010,7 @@ bool intel_sdvo_init(struct drm_device *dev, int
>output_device)
> 		goto err_i2c;
> 	}
>
>+	intel_output->crtc_mask = (1 << 0) | (1 << 1);
> 	connector = &intel_output->base;
> 	drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
> 			   connector_type);
>diff --git a/drivers/gpu/drm/i915/intel_tv.c
>b/drivers/gpu/drm/i915/intel_tv.c
>index a43c98e..8ba37f6 100644
>--- a/drivers/gpu/drm/i915/intel_tv.c
>+++ b/drivers/gpu/drm/i915/intel_tv.c
>@@ -1696,6 +1696,7 @@ intel_tv_init(struct drm_device *dev)
> 	if (!intel_output) {
> 		return;
> 	}
>+
> 	connector = &intel_output->base;
>
> 	drm_connector_init(dev, connector, &intel_tv_connector_funcs,
>@@ -1707,6 +1708,7 @@ intel_tv_init(struct drm_device *dev)
> 	drm_mode_connector_attach_encoder(&intel_output->base,
>&intel_output->enc);
> 	tv_priv = (struct intel_tv_priv *)(intel_output + 1);
> 	intel_output->type = INTEL_OUTPUT_TVOUT;
>+	intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
> 	intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
> 	intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
> 	intel_output->dev_priv = tv_priv;
>--
>1.5.4.4



More information about the Intel-gfx mailing list