All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port)
@ 2012-10-26 21:05 Paulo Zanoni
  2012-10-26 21:05 ` [PATCH 1/9] drm/i915: simplify assignments inside intel_dp.c Paulo Zanoni
                   ` (8 more replies)
  0 siblings, 9 replies; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

Hi

Finally, the last piece of the Haswell DP enablement: after this series xrandr
should show your connected DP monitors and hopefully enable them.

The problem this series tries to solve is that both DP and HDMI share the same
registers for any given port. So you can't just "intel_hdmi_init(PORT_A)" and
then "intel_dp_init(PORT_A)", as this will totally confuse the HW state readout
code, among other things.

Older versions of these patches (and all the previous ones I sent in the last
weeks) were already used by quite a few people and even tested by QA a few
times.

The amount of lines changed by this series is quite big, but most of these
changes are small adjustments to make the code compile. Because of this, as our
tree changes (especially intel_hdmi.c and intel_dp.c) these patches may start
needing some adjustments. I wrote these patches on top of today's
drm-intel-next-queued + the 3 "edp panel scaling" patches from Jani/Yuly (since
I believe these will probably get merged before my series, so I won't have to
resend in this case).

After this series I still have 2 more series to send, one with Haswell VGA fixes
and the other with small Haswell bug fixes.

Thanks in advance for your reviews,
Paulo


Paulo Zanoni (9):
  drm/i915: simplify assignments inside intel_dp.c
  drm/i915: add intel_dp_to_dev and intel_hdmi_to_dev
  drm/i915: create intel_digital_port and use it
  drm/i915: split intel_hdmi_init into encoder and connector pieces
  drm/i915: split intel_dp_init into encoder and connector pieces
  drm/i915: reset intel_encoder->type when DP or HDMI is detected
  drm/i915: add port field to intel_digital_port
  drm/i915: add intel_ddi_connector_get_hw_state
  drm/i915: create the DDI encoder

 drivers/gpu/drm/i915/intel_ddi.c  | 204 +++++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_dp.c   | 275 +++++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_drv.h  |  54 ++++++--
 drivers/gpu/drm/i915/intel_hdmi.c | 133 +++++++++---------
 4 files changed, 420 insertions(+), 246 deletions(-)

-- 
1.7.11.4

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/9] drm/i915: simplify assignments inside intel_dp.c
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 11:32   ` Lespiau, Damien
  2012-10-26 21:05 ` [PATCH 2/9] drm/i915: add intel_dp_to_dev and intel_hdmi_to_dev Paulo Zanoni
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

 - Replace container_of with enc_to_intel_dp.
 - Walk through less structures when making assignments.
 - Rename some variables to keep our naming standards.

As a bonus, this will reduce the usage of "struct intel_dp", making
the future patch that introduces intel_digital_port smaller and easier
to review.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 41 +++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a1b9fc13..40e62a8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -76,8 +76,7 @@ static bool is_cpu_edp(struct intel_dp *intel_dp)
 
 static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
 {
-	return container_of(intel_attached_encoder(connector),
-			    struct intel_dp, base);
+	return enc_to_intel_dp(&intel_attached_encoder(connector)->base);
 }
 
 /**
@@ -105,7 +104,7 @@ void
 intel_edp_link_config(struct intel_encoder *intel_encoder,
 		       int *lane_num, int *link_bw)
 {
-	struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
 
 	*lane_num = intel_dp->lane_count;
 	*link_bw = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
@@ -115,7 +114,7 @@ int
 intel_edp_target_clock(struct intel_encoder *intel_encoder,
 		       struct drm_display_mode *mode)
 {
-	struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 
 	if (intel_connector->panel.fixed_mode)
@@ -771,7 +770,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		 struct drm_display_mode *adjusted_mode)
 {
 	struct drm_device *dev = crtc->dev;
-	struct intel_encoder *encoder;
+	struct intel_encoder *intel_encoder;
+	struct intel_dp *intel_dp;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int lane_count = 4;
@@ -782,11 +782,11 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 	/*
 	 * Find the lane count in the intel_encoder private
 	 */
-	for_each_encoder_on_crtc(dev, crtc, encoder) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
+		intel_dp = enc_to_intel_dp(&intel_encoder->base);
 
-		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
-		    intel_dp->base.type == INTEL_OUTPUT_EDP)
+		if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		    intel_encoder->type == INTEL_OUTPUT_EDP)
 		{
 			lane_count = intel_dp->lane_count;
 			break;
@@ -848,7 +848,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-	struct drm_crtc *crtc = intel_dp->base.base.crtc;
+	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
 	/*
@@ -2277,7 +2277,7 @@ static enum drm_connector_status
 intel_dp_detect(struct drm_connector *connector, bool force)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = connector->dev;
 	enum drm_connector_status status;
 	struct edid *edid = NULL;
 
@@ -2315,7 +2315,7 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
 	struct intel_connector *intel_connector = to_intel_connector(connector);
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = connector->dev;
 	int ret;
 
 	/* We should parse the EDID data and find out if it has an audio sink
@@ -2491,7 +2491,7 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
 static void
 intel_dp_hot_plug(struct intel_encoder *intel_encoder)
 {
-	struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
 
 	intel_dp_check_link_status(intel_dp);
 }
@@ -2501,13 +2501,14 @@ int
 intel_trans_dp_port_sel(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
-	struct intel_encoder *encoder;
+	struct intel_encoder *intel_encoder;
+	struct intel_dp *intel_dp;
 
-	for_each_encoder_on_crtc(dev, crtc, encoder) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
+		intel_dp = enc_to_intel_dp(&intel_encoder->base);
 
-		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
-		    intel_dp->base.type == INTEL_OUTPUT_EDP)
+		if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		    intel_encoder->type == INTEL_OUTPUT_EDP)
 			return intel_dp->output_reg;
 	}
 
@@ -2801,8 +2802,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 		} else {
 			/* if this fails, presume the device is a ghost */
 			DRM_INFO("failed to retrieve link info, disabling eDP\n");
-			intel_dp_encoder_destroy(&intel_dp->base.base);
-			intel_dp_destroy(&intel_connector->base);
+			intel_dp_encoder_destroy(&intel_encoder->base);
+			intel_dp_destroy(connector);
 			return;
 		}
 
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/9] drm/i915: add intel_dp_to_dev and intel_hdmi_to_dev
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
  2012-10-26 21:05 ` [PATCH 1/9] drm/i915: simplify assignments inside intel_dp.c Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 11:37   ` Lespiau, Damien
  2012-10-26 21:05 ` [PATCH 3/9] drm/i915: create intel_digital_port and use it Paulo Zanoni
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

When we add struct intel_digital_port, there will be no direct way of
going from intel_{dp,hdmi} to drm_device: we will need to call
container_of().

This patch adds functions to go from intel_{dp,hdmi} to drm_device.
The main goal here is to greatly reduce the size of the next patch,
where we will change the implementation of the functions we just
added here (among other things).

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c   | 48 ++++++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_hdmi.c |  9 ++++++--
 2 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 40e62a8..96f8574 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -74,6 +74,11 @@ static bool is_cpu_edp(struct intel_dp *intel_dp)
 	return is_edp(intel_dp) && !is_pch_edp(intel_dp);
 }
 
+static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
+{
+	return intel_dp->base.base.dev;
+}
+
 static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
 {
 	return enc_to_intel_dp(&intel_attached_encoder(connector)->base);
@@ -291,7 +296,7 @@ intel_hrawclk(struct drm_device *dev)
 
 static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	return (I915_READ(PCH_PP_STATUS) & PP_ON) != 0;
@@ -299,7 +304,7 @@ static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
 
 static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	return (I915_READ(PCH_PP_CONTROL) & EDP_FORCE_VDD) != 0;
@@ -308,7 +313,7 @@ static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
 static void
 intel_dp_check_edp(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	if (!is_edp(intel_dp))
@@ -327,7 +332,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 		uint8_t *recv, int recv_size)
 {
 	uint32_t output_reg = intel_dp->output_reg;
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t ch_ctl = output_reg + 0x10;
 	uint32_t ch_data = ch_ctl + 4;
@@ -955,7 +960,7 @@ static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
 				       u32 mask,
 				       u32 value)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
@@ -1004,7 +1009,7 @@ static  u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv)
 
 void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
@@ -1043,7 +1048,7 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
 
 static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
@@ -1065,7 +1070,7 @@ static void ironlake_panel_vdd_work(struct work_struct *__work)
 {
 	struct intel_dp *intel_dp = container_of(to_delayed_work(__work),
 						 struct intel_dp, panel_vdd_work);
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 
 	mutex_lock(&dev->mode_config.mutex);
 	ironlake_panel_vdd_off_sync(intel_dp);
@@ -1097,7 +1102,7 @@ void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
 
 void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
@@ -1139,7 +1144,7 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp)
 
 void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
@@ -1164,7 +1169,7 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 
 void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int pipe = to_intel_crtc(intel_dp->base.base.crtc)->pipe;
 	u32 pp;
@@ -1190,7 +1195,7 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
 
 void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 pp;
 
@@ -1209,7 +1214,7 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
 
 static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_crtc *crtc = intel_dp->base.base.crtc;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
@@ -1234,7 +1239,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
 
 static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_crtc *crtc = intel_dp->base.base.crtc;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
@@ -1445,7 +1450,7 @@ static char	*link_train_names[] = {
 static uint8_t
 intel_dp_voltage_max(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 
 	if (IS_GEN7(dev) && is_cpu_edp(intel_dp))
 		return DP_TRAIN_VOLTAGE_SWING_800;
@@ -1458,7 +1463,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp)
 static uint8_t
 intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 
 	if (IS_HASWELL(dev)) {
 		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
@@ -1664,7 +1669,7 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 			uint32_t dp_reg_value,
 			uint8_t dp_train_pat)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret;
 	uint32_t temp;
@@ -1861,7 +1866,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 void
 intel_dp_complete_link_train(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	bool channel_eq = false;
 	int tries, cr_tries;
 	uint32_t DP = intel_dp->DP;
@@ -1940,7 +1945,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 static void
 intel_dp_link_down(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t DP = intel_dp->DP;
 
@@ -2182,11 +2187,12 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
 static enum drm_connector_status
 ironlake_dp_detect(struct intel_dp *intel_dp)
 {
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	enum drm_connector_status status;
 
 	/* Can't disconnect eDP, but you can close the lid... */
 	if (is_edp(intel_dp)) {
-		status = intel_panel_detect(intel_dp->base.base.dev);
+		status = intel_panel_detect(dev);
 		if (status == connector_status_unknown)
 			status = connector_status_connected;
 		return status;
@@ -2198,7 +2204,7 @@ ironlake_dp_detect(struct intel_dp *intel_dp)
 static enum drm_connector_status
 g4x_dp_detect(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp->base.base.dev;
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t bit;
 
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index ab1e34b..e2215a4 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -36,10 +36,15 @@
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
 
+static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
+{
+	return intel_hdmi->base.base.dev;
+}
+
 static void
 assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi)
 {
-	struct drm_device *dev = intel_hdmi->base.base.dev;
+	struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t enabled_bits;
 
@@ -763,7 +768,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 
 static bool g4x_hdmi_connected(struct intel_hdmi *intel_hdmi)
 {
-	struct drm_device *dev = intel_hdmi->base.base.dev;
+	struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t bit;
 
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/9] drm/i915: create intel_digital_port and use it
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
  2012-10-26 21:05 ` [PATCH 1/9] drm/i915: simplify assignments inside intel_dp.c Paulo Zanoni
  2012-10-26 21:05 ` [PATCH 2/9] drm/i915: add intel_dp_to_dev and intel_hdmi_to_dev Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 11:44   ` Lespiau, Damien
  2012-10-26 21:05 ` [PATCH 4/9] drm/i915: split intel_hdmi_init into encoder and connector pieces Paulo Zanoni
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

The goal is to have one single encoder capable of controlling both DP
and HDMI outputs. This patch just adds the initial infrastructure, no
functional changes.

Previously, both intel_dp and intel_hdmi were intel_encoders. Now,
these 2 structs do not have intel_encoder as members anymore. The new
struct intel_digital_port has intel_encoder as a member, and it also
includes intel_dp and intel_hdmi as members. In other words: see the
changes inside intel_drv.h: it's the most important change, everything
else is only to make it compile and work.

For now, each intel_digital_port is still only able to control one of
HDMI or DP, but not both together.

In the future we should also try to merge the common fields from
intel_dp and intel_hdmi (e.g., port).

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c   | 59 ++++++++++++++++++++++++---------------
 drivers/gpu/drm/i915/intel_drv.h  | 30 ++++++++++++++++++--
 drivers/gpu/drm/i915/intel_hdmi.c | 25 ++++++++++-------
 3 files changed, 78 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 96f8574..b97e791 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -47,7 +47,9 @@
  */
 static bool is_edp(struct intel_dp *intel_dp)
 {
-	return intel_dp->base.type == INTEL_OUTPUT_EDP;
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+
+	return intel_dig_port->base.type == INTEL_OUTPUT_EDP;
 }
 
 /**
@@ -76,7 +78,9 @@ static bool is_cpu_edp(struct intel_dp *intel_dp)
 
 static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
 {
-	return intel_dp->base.base.dev;
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+
+	return intel_dig_port->base.base.dev;
 }
 
 static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
@@ -1169,9 +1173,10 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 
 void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port= dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	int pipe = to_intel_crtc(intel_dp->base.base.crtc)->pipe;
+	int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
 	u32 pp;
 
 	if (!is_edp(intel_dp))
@@ -1214,8 +1219,9 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp)
 
 static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_crtc *crtc = intel_dp->base.base.crtc;
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
+	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
 
@@ -1239,8 +1245,9 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
 
 static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
-	struct drm_crtc *crtc = intel_dp->base.base.crtc;
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
+	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
 
@@ -1772,7 +1779,7 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 void
 intel_dp_start_link_train(struct intel_dp *intel_dp)
 {
-	struct drm_encoder *encoder = &intel_dp->base.base;
+	struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
 	struct drm_device *dev = encoder->dev;
 	int i;
 	uint8_t voltage;
@@ -1945,7 +1952,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 static void
 intel_dp_link_down(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t DP = intel_dp->DP;
 
@@ -1985,7 +1993,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
 
 	if (HAS_PCH_IBX(dev) &&
 	    I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
-		struct drm_crtc *crtc = intel_dp->base.base.crtc;
+		struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
 
 		/* Hardware workaround: leaving our transcoder select
 		 * set to transcoder B while it's off will prevent the
@@ -2101,13 +2109,14 @@ intel_dp_handle_test_request(struct intel_dp *intel_dp)
 static void
 intel_dp_check_link_status(struct intel_dp *intel_dp)
 {
+	struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
 	u8 sink_irq_vector;
 	u8 link_status[DP_LINK_STATUS_SIZE];
 
-	if (!intel_dp->base.connectors_active)
+	if (!intel_encoder->connectors_active)
 		return;
 
-	if (WARN_ON(!intel_dp->base.base.crtc))
+	if (WARN_ON(!intel_encoder->base.crtc))
 		return;
 
 	/* Try to read receiver status if the link appears to be up */
@@ -2138,7 +2147,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
 
 	if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
 		DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
-			      drm_get_encoder_name(&intel_dp->base.base));
+			      drm_get_encoder_name(&intel_encoder->base));
 		intel_dp_start_link_train(intel_dp);
 		intel_dp_complete_link_train(intel_dp);
 	}
@@ -2367,7 +2376,8 @@ intel_dp_set_property(struct drm_connector *connector,
 {
 	struct drm_i915_private *dev_priv = connector->dev->dev_private;
 	struct intel_connector *intel_connector = to_intel_connector(connector);
-	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
 	int ret;
 
 	ret = drm_connector_property_set_value(connector, property, val);
@@ -2422,8 +2432,8 @@ intel_dp_set_property(struct drm_connector *connector,
 	return -EINVAL;
 
 done:
-	if (intel_dp->base.base.crtc) {
-		struct drm_crtc *crtc = intel_dp->base.base.crtc;
+	if (intel_encoder->base.crtc) {
+		struct drm_crtc *crtc = intel_encoder->base.crtc;
 		intel_set_mode(crtc, &crtc->mode,
 			       crtc->x, crtc->y, crtc->fb);
 	}
@@ -2453,7 +2463,8 @@ intel_dp_destroy(struct drm_connector *connector)
 
 static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
 {
-	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
 
 	i2c_del_adapter(&intel_dp->adapter);
 	drm_encoder_cleanup(encoder);
@@ -2461,7 +2472,7 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
 		cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
 		ironlake_panel_vdd_off_sync(intel_dp);
 	}
-	kfree(intel_dp);
+	kfree(intel_dig_port);
 }
 
 static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
@@ -2679,14 +2690,16 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 	struct intel_dp *intel_dp;
 	struct intel_encoder *intel_encoder;
 	struct intel_connector *intel_connector;
+	struct intel_digital_port *intel_dig_port;
 	struct drm_display_mode *fixed_mode = NULL;
 	const char *name = NULL;
 	int type;
 
-	intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL);
-	if (!intel_dp)
+	intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
+	if (!intel_dig_port)
 		return;
 
+	intel_dp = &intel_dig_port->dp;
 	intel_dp->output_reg = output_reg;
 	intel_dp->port = port;
 	/* Preserve the current hw state. */
@@ -2694,10 +2707,10 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 
 	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
 	if (!intel_connector) {
-		kfree(intel_dp);
+		kfree(intel_dig_port);
 		return;
 	}
-	intel_encoder = &intel_dp->base;
+	intel_encoder = &intel_dig_port->base;
 	intel_dp->attached_connector = intel_connector;
 
 	if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8839ed5..73964df 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -331,7 +331,6 @@ struct dip_infoframe {
 } __attribute__((packed));
 
 struct intel_hdmi {
-	struct intel_encoder base;
 	u32 sdvox_reg;
 	int ddc_bus;
 	int ddi_port;
@@ -349,7 +348,6 @@ struct intel_hdmi {
 #define DP_LINK_CONFIGURATION_SIZE	9
 
 struct intel_dp {
-	struct intel_encoder base;
 	uint32_t output_reg;
 	uint32_t DP;
 	uint8_t  link_configuration[DP_LINK_CONFIGURATION_SIZE];
@@ -375,6 +373,12 @@ struct intel_dp {
 	struct intel_connector *attached_connector;
 };
 
+struct intel_digital_port {
+	struct intel_encoder base;
+	struct intel_dp dp;
+	struct intel_hdmi hdmi;
+};
+
 static inline struct drm_crtc *
 intel_get_crtc_for_pipe(struct drm_device *dev, int pipe)
 {
@@ -502,7 +506,27 @@ static inline struct intel_encoder *intel_attached_encoder(struct drm_connector
 
 static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
 {
-	return container_of(encoder, struct intel_dp, base.base);
+	struct intel_digital_port *intel_dig_port =
+		container_of(encoder, struct intel_digital_port, base.base);
+	return &intel_dig_port->dp;
+}
+
+static inline struct intel_digital_port *
+enc_to_dig_port(struct drm_encoder *encoder)
+{
+	return container_of(encoder, struct intel_digital_port, base.base);
+}
+
+static inline struct intel_digital_port *
+dp_to_dig_port(struct intel_dp *intel_dp)
+{
+	return container_of(intel_dp, struct intel_digital_port, dp);
+}
+
+static inline struct intel_digital_port *
+hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
+{
+	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
 }
 
 extern void intel_connector_attach_encoder(struct intel_connector *connector,
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index e2215a4..982e7a5 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -38,7 +38,7 @@
 
 static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
 {
-	return intel_hdmi->base.base.dev;
+	return hdmi_to_dig_port(intel_hdmi)->base.base.dev;
 }
 
 static void
@@ -56,13 +56,14 @@ assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi)
 
 struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
 {
-	return container_of(encoder, struct intel_hdmi, base.base);
+	struct intel_digital_port *intel_dig_port =
+		container_of(encoder, struct intel_digital_port, base.base);
+	return &intel_dig_port->hdmi;
 }
 
 static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector)
 {
-	return container_of(intel_attached_encoder(connector),
-			    struct intel_hdmi, base);
+	return enc_to_intel_hdmi(&intel_attached_encoder(connector)->base);
 }
 
 void intel_dip_infoframe_csum(struct dip_infoframe *frame)
@@ -864,6 +865,8 @@ intel_hdmi_set_property(struct drm_connector *connector,
 			uint64_t val)
 {
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	struct intel_digital_port *intel_dig_port =
+		hdmi_to_dig_port(intel_hdmi);
 	struct drm_i915_private *dev_priv = connector->dev->dev_private;
 	int ret;
 
@@ -903,8 +906,8 @@ intel_hdmi_set_property(struct drm_connector *connector,
 	return -EINVAL;
 
 done:
-	if (intel_hdmi->base.base.crtc) {
-		struct drm_crtc *crtc = intel_hdmi->base.base.crtc;
+	if (intel_dig_port->base.base.crtc) {
+		struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
 		intel_set_mode(crtc, &crtc->mode,
 			       crtc->x, crtc->y, crtc->fb);
 	}
@@ -962,19 +965,21 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
 	struct drm_connector *connector;
 	struct intel_encoder *intel_encoder;
 	struct intel_connector *intel_connector;
+	struct intel_digital_port *intel_dig_port;
 	struct intel_hdmi *intel_hdmi;
 
-	intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL);
-	if (!intel_hdmi)
+	intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
+	if (!intel_dig_port)
 		return;
 
 	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
 	if (!intel_connector) {
-		kfree(intel_hdmi);
+		kfree(intel_dig_port);
 		return;
 	}
 
-	intel_encoder = &intel_hdmi->base;
+	intel_hdmi = &intel_dig_port->hdmi;
+	intel_encoder = &intel_dig_port->base;
 	drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
 			 DRM_MODE_ENCODER_TMDS);
 
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/9] drm/i915: split intel_hdmi_init into encoder and connector pieces
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
                   ` (2 preceding siblings ...)
  2012-10-26 21:05 ` [PATCH 3/9] drm/i915: create intel_digital_port and use it Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 11:57   ` Lespiau, Damien
  2012-10-26 21:05 ` [PATCH 5/9] drm/i915: split intel_dp_init " Paulo Zanoni
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

We want to split the HDMI connector and encoder initialization because
in the future the DDI code will have its own "encoder init" function,
but it will still call intel_hdmi_init_connector. The DDI encoder will
actually have two connectors attached to it: HDMI and DP.

The best way to look at this patch is to imagine that we're renaming
intel_hdmi_init to intel_hdmi_init_connector and removing the
encoder-specific pieces and placing them into intel_hdmi_init.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c | 96 +++++++++++++++++++++------------------
 1 file changed, 53 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 982e7a5..be949f1 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -959,45 +959,24 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
 	intel_attach_broadcast_rgb_property(connector);
 }
 
-void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
+static void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+				      struct intel_connector *intel_connector)
 {
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_connector *connector;
-	struct intel_encoder *intel_encoder;
-	struct intel_connector *intel_connector;
-	struct intel_digital_port *intel_dig_port;
-	struct intel_hdmi *intel_hdmi;
-
-	intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
-	if (!intel_dig_port)
-		return;
-
-	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
-	if (!intel_connector) {
-		kfree(intel_dig_port);
-		return;
-	}
-
-	intel_hdmi = &intel_dig_port->hdmi;
-	intel_encoder = &intel_dig_port->base;
-	drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
-			 DRM_MODE_ENCODER_TMDS);
+	enum port port = intel_hdmi->ddi_port;
 
-	connector = &intel_connector->base;
 	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
 	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
 
-	intel_encoder->type = INTEL_OUTPUT_HDMI;
-
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
 	connector->interlace_allowed = 1;
 	connector->doublescan_allowed = 0;
-	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
-
-	intel_encoder->cloneable = false;
 
-	intel_hdmi->ddi_port = port;
 	switch (port) {
 	case PORT_B:
 		intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
@@ -1017,8 +996,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
 		BUG();
 	}
 
-	intel_hdmi->sdvox_reg = sdvox_reg;
-
 	if (!HAS_PCH_SPLIT(dev)) {
 		intel_hdmi->write_infoframe = g4x_write_infoframe;
 		intel_hdmi->set_infoframes = g4x_set_infoframes;
@@ -1036,6 +1013,45 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
 		intel_hdmi->set_infoframes = cpt_set_infoframes;
 	}
 
+	intel_connector->get_hw_state = intel_connector_get_hw_state;
+
+	intel_hdmi_add_properties(intel_hdmi, connector);
+
+	intel_connector_attach_encoder(intel_connector, intel_encoder);
+	drm_sysfs_connector_add(connector);
+
+	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
+	 * 0xd.  Failure to do so will result in spurious interrupts being
+	 * generated on the port when a cable is not attached.
+	 */
+	if (IS_G4X(dev) && !IS_GM45(dev)) {
+		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
+		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
+	}
+}
+
+void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
+{
+	struct intel_digital_port *intel_dig_port;
+	struct intel_encoder *intel_encoder;
+	struct drm_encoder *encoder;
+	struct intel_connector *intel_connector;
+
+	intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
+	if (!intel_dig_port)
+		return;
+
+	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
+	if (!intel_connector) {
+		kfree(intel_dig_port);
+		return;
+	}
+
+	intel_encoder = &intel_dig_port->base;
+	encoder = &intel_encoder->base;
+
+	drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
+			 DRM_MODE_ENCODER_TMDS);
 	if (IS_HASWELL(dev)) {
 		intel_encoder->pre_enable = intel_ddi_pre_enable;
 		intel_encoder->enable = intel_enable_ddi;
@@ -1051,20 +1067,14 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
 		drm_encoder_helper_add(&intel_encoder->base,
 				       &intel_hdmi_helper_funcs);
 	}
-	intel_connector->get_hw_state = intel_connector_get_hw_state;
 
+	intel_encoder->type = INTEL_OUTPUT_HDMI;
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+	intel_encoder->cloneable = false;
 
-	intel_hdmi_add_properties(intel_hdmi, connector);
+	intel_dig_port->hdmi.ddi_port = port;
+	intel_dig_port->hdmi.sdvox_reg = sdvox_reg;
+	intel_dig_port->dp.output_reg = 0;
 
-	intel_connector_attach_encoder(intel_connector, intel_encoder);
-	drm_sysfs_connector_add(connector);
-
-	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
-	 * 0xd.  Failure to do so will result in spurious interrupts being
-	 * generated on the port when a cable is not attached.
-	 */
-	if (IS_G4X(dev) && !IS_GM45(dev)) {
-		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
-		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
-	}
+	intel_hdmi_init_connector(intel_dig_port, intel_connector);
 }
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 5/9] drm/i915: split intel_dp_init into encoder and connector pieces
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
                   ` (3 preceding siblings ...)
  2012-10-26 21:05 ` [PATCH 4/9] drm/i915: split intel_hdmi_init into encoder and connector pieces Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 12:07   ` Lespiau, Damien
  2012-10-26 21:05 ` [PATCH 6/9] drm/i915: reset intel_encoder->type when DP or HDMI is detected Paulo Zanoni
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

Same reason as the previous HDMI commit: the DDI code will have its
own encoder init function but still use the DP and HDMI connectors.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 125 ++++++++++++++++++++++------------------
 1 file changed, 68 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index b97e791..fcc15a2 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2682,38 +2682,25 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
 		      I915_READ(PCH_PP_DIVISOR));
 }
 
-void
-intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
+static void
+intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
+			struct intel_connector *intel_connector)
 {
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_connector *connector;
-	struct intel_dp *intel_dp;
-	struct intel_encoder *intel_encoder;
-	struct intel_connector *intel_connector;
-	struct intel_digital_port *intel_dig_port;
 	struct drm_display_mode *fixed_mode = NULL;
+	enum port port = intel_dp->port;
 	const char *name = NULL;
 	int type;
 
-	intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
-	if (!intel_dig_port)
-		return;
-
-	intel_dp = &intel_dig_port->dp;
-	intel_dp->output_reg = output_reg;
-	intel_dp->port = port;
 	/* Preserve the current hw state. */
 	intel_dp->DP = I915_READ(intel_dp->output_reg);
-
-	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
-	if (!intel_connector) {
-		kfree(intel_dig_port);
-		return;
-	}
-	intel_encoder = &intel_dig_port->base;
 	intel_dp->attached_connector = intel_connector;
 
-	if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D)
+	if (HAS_PCH_SPLIT(dev) && port == PORT_D)
 		if (intel_dpd_is_edp(dev))
 			intel_dp->is_pch_edp = true;
 
@@ -2721,10 +2708,10 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 	 * FIXME : We need to initialize built-in panels before external panels.
 	 * For X0, DP_C is fixed as eDP. Revisit this as part of VLV eDP cleanup
 	 */
-	if (IS_VALLEYVIEW(dev) && output_reg == DP_C) {
+	if (IS_VALLEYVIEW(dev) && port == PORT_C) {
 		type = DRM_MODE_CONNECTOR_eDP;
 		intel_encoder->type = INTEL_OUTPUT_EDP;
-	} else if (output_reg == DP_A || is_pch_edp(intel_dp)) {
+	} else if (port == PORT_A || is_pch_edp(intel_dp)) {
 		type = DRM_MODE_CONNECTOR_eDP;
 		intel_encoder->type = INTEL_OUTPUT_EDP;
 	} else {
@@ -2732,48 +2719,19 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 	}
 
-	connector = &intel_connector->base;
 	drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
 	drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
 
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	intel_encoder->cloneable = false;
-
-	INIT_DELAYED_WORK(&intel_dp->panel_vdd_work,
-			  ironlake_panel_vdd_work);
-
-	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
-
 	connector->interlace_allowed = true;
 	connector->doublescan_allowed = 0;
 
-	drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
-			 DRM_MODE_ENCODER_TMDS);
-
-	if (IS_HASWELL(dev))
-		drm_encoder_helper_add(&intel_encoder->base,
-				       &intel_dp_helper_funcs_hsw);
-	else
-		drm_encoder_helper_add(&intel_encoder->base,
-				       &intel_dp_helper_funcs);
+	INIT_DELAYED_WORK(&intel_dp->panel_vdd_work,
+			  ironlake_panel_vdd_work);
 
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_sysfs_connector_add(connector);
 
-	if (IS_HASWELL(dev)) {
-		intel_encoder->enable = intel_enable_ddi;
-		intel_encoder->pre_enable = intel_ddi_pre_enable;
-		intel_encoder->disable = intel_disable_ddi;
-		intel_encoder->post_disable = intel_ddi_post_disable;
-		intel_encoder->get_hw_state = intel_ddi_get_hw_state;
-	} else {
-		intel_encoder->enable = intel_enable_dp;
-		intel_encoder->pre_enable = intel_pre_enable_dp;
-		intel_encoder->disable = intel_disable_dp;
-		intel_encoder->post_disable = intel_post_disable_dp;
-		intel_encoder->get_hw_state = intel_dp_get_hw_state;
-	}
 	intel_connector->get_hw_state = intel_connector_get_hw_state;
 
 	/* Set up the DDC bus. */
@@ -2859,8 +2817,6 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 		ironlake_edp_panel_vdd_off(intel_dp, false);
 	}
 
-	intel_encoder->hot_plug = intel_dp_hot_plug;
-
 	if (is_edp(intel_dp)) {
 		intel_panel_init(&intel_connector->panel, fixed_mode);
 		intel_panel_setup_backlight(connector);
@@ -2877,3 +2833,58 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
 	}
 }
+
+void
+intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
+{
+	struct intel_digital_port *intel_dig_port;
+	struct intel_encoder *intel_encoder;
+	struct drm_encoder *encoder;
+	struct intel_connector *intel_connector;
+
+	intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
+	if (!intel_dig_port)
+		return;
+
+	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
+	if (!intel_connector) {
+		kfree(intel_dig_port);
+		return;
+	}
+
+	intel_encoder = &intel_dig_port->base;
+	encoder = &intel_encoder->base;
+
+	drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+
+	if (IS_HASWELL(dev)) {
+		drm_encoder_helper_add(&intel_encoder->base,
+				       &intel_dp_helper_funcs_hsw);
+
+		intel_encoder->enable = intel_enable_ddi;
+		intel_encoder->pre_enable = intel_ddi_pre_enable;
+		intel_encoder->disable = intel_disable_ddi;
+		intel_encoder->post_disable = intel_ddi_post_disable;
+		intel_encoder->get_hw_state = intel_ddi_get_hw_state;
+	} else {
+		drm_encoder_helper_add(&intel_encoder->base,
+				       &intel_dp_helper_funcs);
+
+		intel_encoder->enable = intel_enable_dp;
+		intel_encoder->pre_enable = intel_pre_enable_dp;
+		intel_encoder->disable = intel_disable_dp;
+		intel_encoder->post_disable = intel_post_disable_dp;
+		intel_encoder->get_hw_state = intel_dp_get_hw_state;
+	}
+
+	intel_dig_port->dp.port = port;
+	intel_dig_port->dp.output_reg = output_reg;
+	intel_dig_port->hdmi.sdvox_reg = 0;
+
+	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+	intel_encoder->cloneable = false;
+	intel_encoder->hot_plug = intel_dp_hot_plug;
+
+	intel_dp_init_connector(intel_dig_port, intel_connector);
+}
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 6/9] drm/i915: reset intel_encoder->type when DP or HDMI is detected
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
                   ` (4 preceding siblings ...)
  2012-10-26 21:05 ` [PATCH 5/9] drm/i915: split intel_dp_init " Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 12:13   ` Damien Lespiau
  2012-10-26 21:05 ` [PATCH 7/9] drm/i915: add port field to intel_digital_port Paulo Zanoni
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

When intel_hdmi_detect detects a monitor, set intel_encoder->type with
INTEL_OUTPUT_HDMI. Same for DP.

This should not break the current code because these variables never
change. This will be used after we create the DDI encoder because it
will have both DP and HDMI connectors.

We won't support eDP+HDMI on the same port, so if an encoder is eDP we
should expect it to always remain eDP and never change.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c   | 4 ++++
 drivers/gpu/drm/i915/intel_hdmi.c | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index fcc15a2..5476c4a 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2292,6 +2292,8 @@ static enum drm_connector_status
 intel_dp_detect(struct drm_connector *connector, bool force)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
 	struct drm_device *dev = connector->dev;
 	enum drm_connector_status status;
 	struct edid *edid = NULL;
@@ -2323,6 +2325,8 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 		}
 	}
 
+	if (intel_encoder->type != INTEL_OUTPUT_EDP)
+		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 	return connector_status_connected;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index be949f1..c0aadc1 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -792,6 +792,9 @@ static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+	struct intel_digital_port *intel_dig_port =
+		hdmi_to_dig_port(intel_hdmi);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
 	struct drm_i915_private *dev_priv = connector->dev->dev_private;
 	struct edid *edid;
 	enum drm_connector_status status = connector_status_disconnected;
@@ -820,6 +823,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 		if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
 			intel_hdmi->has_audio =
 				(intel_hdmi->force_audio == HDMI_AUDIO_ON);
+		intel_encoder->type = INTEL_OUTPUT_HDMI;
 	}
 
 	return status;
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 7/9] drm/i915: add port field to intel_digital_port
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
                   ` (5 preceding siblings ...)
  2012-10-26 21:05 ` [PATCH 6/9] drm/i915: reset intel_encoder->type when DP or HDMI is detected Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 12:17   ` Damien Lespiau
  2012-10-26 21:05 ` [PATCH 8/9] drm/i915: add intel_ddi_connector_get_hw_state Paulo Zanoni
  2012-10-26 21:05 ` [PATCH 9/9] drm/i915: create the DDI encoder Paulo Zanoni
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

Both "intel_dp" and "intel_hdmi" structs had a "port" field, which
always had the same value. It makes more sense to move this to
intel_digital_port, so we can know the port independently of the
connector type.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c  | 23 ++++++++++-------------
 drivers/gpu/drm/i915/intel_dp.c   | 21 ++++++++++++---------
 drivers/gpu/drm/i915/intel_drv.h  |  3 +--
 drivers/gpu/drm/i915/intel_hdmi.c |  4 ++--
 4 files changed, 25 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 408d6b0..a8eda96 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -63,13 +63,11 @@ static enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
 	struct drm_encoder *encoder = &intel_encoder->base;
 	int type = intel_encoder->type;
 
-	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-		return intel_dp->port;
-
-	} else if (type == INTEL_OUTPUT_HDMI) {
-		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
-		return intel_hdmi->ddi_port;
+	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP ||
+	    type == INTEL_OUTPUT_HDMI) {
+		struct intel_digital_port *intel_dig_port =
+			enc_to_dig_port(encoder);
+		return intel_dig_port->port;
 
 	} else if (type == INTEL_OUTPUT_ANALOG) {
 		return PORT_E;
@@ -925,11 +923,13 @@ void intel_ddi_enable_pipe_func(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
 	enum pipe pipe = intel_crtc->pipe;
 	enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
+	enum port port = intel_ddi_get_encoder_port(intel_encoder);
 	int type = intel_encoder->type;
 	uint32_t temp;
 
 	/* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
 	temp = TRANS_DDI_FUNC_ENABLE;
+	temp |= TRANS_DDI_SELECT_PORT(port);
 
 	switch (intel_crtc->bpp) {
 	case 18:
@@ -979,18 +979,14 @@ void intel_ddi_enable_pipe_func(struct drm_crtc *crtc)
 		else
 			temp |= TRANS_DDI_MODE_SELECT_DVI;
 
-		temp |= TRANS_DDI_SELECT_PORT(intel_hdmi->ddi_port);
-
 	} else if (type == INTEL_OUTPUT_ANALOG) {
 		temp |= TRANS_DDI_MODE_SELECT_FDI;
-		temp |= TRANS_DDI_SELECT_PORT(PORT_E);
 
 	} else if (type == INTEL_OUTPUT_DISPLAYPORT ||
 		   type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
 		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
-		temp |= TRANS_DDI_SELECT_PORT(intel_dp->port);
 
 		switch (intel_dp->lane_count) {
 		case 1:
@@ -1297,9 +1293,10 @@ void intel_ddi_pll_init(struct drm_device *dev)
 
 void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
 {
-	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
 	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
-	enum port port = intel_dp->port;
+	enum port port = intel_dig_port->port;
 	bool wait;
 	uint32_t val;
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5476c4a..b89d935 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -336,7 +336,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 		uint8_t *recv, int recv_size)
 {
 	uint32_t output_reg = intel_dp->output_reg;
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t ch_ctl = output_reg + 0x10;
 	uint32_t ch_data = ch_ctl + 4;
@@ -347,7 +348,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 	int try, precharge;
 
 	if (IS_HASWELL(dev)) {
-		switch (intel_dp->port) {
+		switch (intel_dig_port->port) {
 		case PORT_A:
 			ch_ctl = DPA_AUX_CH_CTL;
 			ch_data = DPA_AUX_CH_DATA1;
@@ -1676,13 +1677,15 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 			uint32_t dp_reg_value,
 			uint8_t dp_train_pat)
 {
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = intel_dig_port->port;
 	int ret;
 	uint32_t temp;
 
 	if (IS_HASWELL(dev)) {
-		temp = I915_READ(DP_TP_CTL(intel_dp->port));
+		temp = I915_READ(DP_TP_CTL(port));
 
 		if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
 			temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
@@ -1693,9 +1696,9 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 		switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
 		case DP_TRAINING_PATTERN_DISABLE:
 			temp |= DP_TP_CTL_LINK_TRAIN_IDLE;
-			I915_WRITE(DP_TP_CTL(intel_dp->port), temp);
+			I915_WRITE(DP_TP_CTL(port), temp);
 
-			if (wait_for((I915_READ(DP_TP_STATUS(intel_dp->port)) &
+			if (wait_for((I915_READ(DP_TP_STATUS(port)) &
 				      DP_TP_STATUS_IDLE_DONE), 1))
 				DRM_ERROR("Timed out waiting for DP idle patterns\n");
 
@@ -1713,7 +1716,7 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
 			temp |= DP_TP_CTL_LINK_TRAIN_PAT3;
 			break;
 		}
-		I915_WRITE(DP_TP_CTL(intel_dp->port), temp);
+		I915_WRITE(DP_TP_CTL(port), temp);
 
 	} else if (HAS_PCH_CPT(dev) &&
 		   (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
@@ -2696,7 +2699,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *fixed_mode = NULL;
-	enum port port = intel_dp->port;
+	enum port port = intel_dig_port->port;
 	const char *name = NULL;
 	int type;
 
@@ -2882,7 +2885,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 		intel_encoder->get_hw_state = intel_dp_get_hw_state;
 	}
 
-	intel_dig_port->dp.port = port;
+	intel_dig_port->port = port;
 	intel_dig_port->dp.output_reg = output_reg;
 	intel_dig_port->hdmi.sdvox_reg = 0;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 73964df..42f16c7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -333,7 +333,6 @@ struct dip_infoframe {
 struct intel_hdmi {
 	u32 sdvox_reg;
 	int ddc_bus;
-	int ddi_port;
 	uint32_t color_range;
 	bool has_hdmi_sink;
 	bool has_audio;
@@ -353,7 +352,6 @@ struct intel_dp {
 	uint8_t  link_configuration[DP_LINK_CONFIGURATION_SIZE];
 	bool has_audio;
 	enum hdmi_force_audio force_audio;
-	enum port port;
 	uint32_t color_range;
 	uint8_t link_bw;
 	uint8_t lane_count;
@@ -375,6 +373,7 @@ struct intel_dp {
 
 struct intel_digital_port {
 	struct intel_encoder base;
+	enum port port;
 	struct intel_dp dp;
 	struct intel_hdmi hdmi;
 };
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index c0aadc1..3c42caa 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -971,7 +971,7 @@ static void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 	struct intel_encoder *intel_encoder = &intel_dig_port->base;
 	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum port port = intel_hdmi->ddi_port;
+	enum port port = intel_dig_port->port;
 
 	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
 			   DRM_MODE_CONNECTOR_HDMIA);
@@ -1076,7 +1076,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
 	intel_encoder->cloneable = false;
 
-	intel_dig_port->hdmi.ddi_port = port;
+	intel_dig_port->port = port;
 	intel_dig_port->hdmi.sdvox_reg = sdvox_reg;
 	intel_dig_port->dp.output_reg = 0;
 
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 8/9] drm/i915: add intel_ddi_connector_get_hw_state
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
                   ` (6 preceding siblings ...)
  2012-10-26 21:05 ` [PATCH 7/9] drm/i915: add port field to intel_digital_port Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 12:33   ` Damien Lespiau
  2012-10-26 21:05 ` [PATCH 9/9] drm/i915: create the DDI encoder Paulo Zanoni
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

We need this since now on DDI we will have 2 connectors on each
encoder.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c  | 40 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_dp.c   |  6 +++++-
 drivers/gpu/drm/i915/intel_drv.h  |  1 +
 drivers/gpu/drm/i915/intel_hdmi.c |  5 ++++-
 4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index a8eda96..58a529d 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1023,6 +1023,46 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
 	I915_WRITE(reg, val);
 }
 
+bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
+{
+	struct drm_device *dev = intel_connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *intel_encoder = intel_connector->encoder;
+	int type = intel_connector->base.connector_type;
+	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+	enum pipe pipe = 0;
+	enum transcoder cpu_transcoder;
+	uint32_t tmp;
+
+	if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
+		return false;
+
+	if (port == PORT_A)
+		cpu_transcoder = TRANSCODER_EDP;
+	else
+		cpu_transcoder = pipe;
+
+	tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+
+	switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
+	case TRANS_DDI_MODE_SELECT_HDMI:
+	case TRANS_DDI_MODE_SELECT_DVI:
+		return (type == DRM_MODE_CONNECTOR_HDMIA);
+
+	case TRANS_DDI_MODE_SELECT_DP_SST:
+		if (type == DRM_MODE_CONNECTOR_eDP)
+			return true;
+	case TRANS_DDI_MODE_SELECT_DP_MST:
+		return (type == DRM_MODE_CONNECTOR_DisplayPort);
+
+	case TRANS_DDI_MODE_SELECT_FDI:
+		return (type == DRM_MODE_CONNECTOR_VGA);
+
+	default:
+		return false;
+	}
+}
+
 bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
 			    enum pipe *pipe)
 {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index b89d935..66bff2d 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2739,7 +2739,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
 	drm_sysfs_connector_add(connector);
 
-	intel_connector->get_hw_state = intel_connector_get_hw_state;
+	if (IS_HASWELL(dev))
+		intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
+	else
+		intel_connector->get_hw_state = intel_connector_get_hw_state;
+
 
 	/* Set up the DDC bus. */
 	switch (port) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 42f16c7..0a527729 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -652,5 +652,6 @@ extern void intel_ddi_post_disable(struct intel_encoder *intel_encoder);
 extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
 extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
 extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
+bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
 
 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 3c42caa..79d15b3 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1017,7 +1017,10 @@ static void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 		intel_hdmi->set_infoframes = cpt_set_infoframes;
 	}
 
-	intel_connector->get_hw_state = intel_connector_get_hw_state;
+	if (IS_HASWELL(dev))
+		intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
+	else
+		intel_connector->get_hw_state = intel_connector_get_hw_state;
 
 	intel_hdmi_add_properties(intel_hdmi, connector);
 
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 9/9] drm/i915: create the DDI encoder
  2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
                   ` (7 preceding siblings ...)
  2012-10-26 21:05 ` [PATCH 8/9] drm/i915: add intel_ddi_connector_get_hw_state Paulo Zanoni
@ 2012-10-26 21:05 ` Paulo Zanoni
  2012-10-30 12:51   ` Damien Lespiau
  8 siblings, 1 reply; 20+ messages in thread
From: Paulo Zanoni @ 2012-10-26 21:05 UTC (permalink / raw)
  To: intel-gfx; +Cc: Paulo Zanoni

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

Now intel_ddi_init is just like intel_hdmi_init and intel_dp_init: it
inits the encoder and then calls the proper init_connector functions.
Notice that for non-eDP ports we call both HDMI and DP connector init,
so we have 2 connectors attached to each DDI encoder.

After this change, intel_hdmi_init and intel_dp_init are only called
by Ivy Bridge and earlier, while hardware containing DDI outputs
should call intel_ddi_init.

Also added/removed quite a few "static" keywords due to the fact that
some function pointers were moved from intel_dp.c and intel_hdmi.c to
intel_ddi.c.

DP finally works on Haswell now! \o/

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c  | 143 ++++++++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_dp.c   |  45 ++++--------
 drivers/gpu/drm/i915/intel_drv.h  |  20 ++++--
 drivers/gpu/drm/i915/intel_hdmi.c |  36 +++-------
 4 files changed, 144 insertions(+), 100 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 58a529d..67bd6ba 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -64,7 +64,7 @@ static enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
 	int type = intel_encoder->type;
 
 	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP ||
-	    type == INTEL_OUTPUT_HDMI) {
+	    type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) {
 		struct intel_digital_port *intel_dig_port =
 			enc_to_dig_port(encoder);
 		return intel_dig_port->port;
@@ -227,35 +227,6 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	DRM_DEBUG_KMS("FDI train done.\n");
 }
 
-/* For DDI connections, it is possible to support different outputs over the
- * same DDI port, such as HDMI or DP or even VGA via FDI. So we don't know by
- * the time the output is detected what exactly is on the other end of it. This
- * function aims at providing support for this detection and proper output
- * configuration.
- */
-void intel_ddi_init(struct drm_device *dev, enum port port)
-{
-	/* For now, we don't do any proper output detection and assume that we
-	 * handle HDMI only */
-
-	switch(port){
-	case PORT_A:
-		DRM_DEBUG_DRIVER("Found digital output on DDI port A\n");
-		intel_dp_init(dev, DDI_BUF_CTL_A, PORT_A);
-		break;
-	/* Assume that the  ports B, C and D are working in HDMI mode for now */
-	case PORT_B:
-	case PORT_C:
-	case PORT_D:
-		intel_hdmi_init(dev, DDI_BUF_CTL(port), port);
-		break;
-	default:
-		DRM_DEBUG_DRIVER("No handlers defined for port %d, skipping DDI initialization\n",
-				port);
-		break;
-	}
-}
-
 /* WRPLL clock dividers */
 struct wrpll_tmds_clock {
 	u32 clock;
@@ -642,9 +613,9 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
 	{298000,	2,	21,	19},
 };
 
-void intel_ddi_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
+static void intel_ddi_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
 {
 	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -1192,7 +1163,7 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
 			   TRANS_CLK_SEL_DISABLED);
 }
 
-void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
+static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_crtc *crtc = encoder->crtc;
@@ -1234,7 +1205,7 @@ static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
 	DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
 }
 
-void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
+static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
@@ -1267,7 +1238,7 @@ void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
 	I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
 }
 
-void intel_enable_ddi(struct intel_encoder *intel_encoder)
+static void intel_enable_ddi(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_device *dev = encoder->dev;
@@ -1288,7 +1259,7 @@ void intel_enable_ddi(struct intel_encoder *intel_encoder)
 	}
 }
 
-void intel_disable_ddi(struct intel_encoder *intel_encoder)
+static void intel_disable_ddi(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
 	int type = intel_encoder->type;
@@ -1371,3 +1342,101 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
 
 	udelay(600);
 }
+
+static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
+	int type = intel_encoder->type;
+
+	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP)
+		intel_dp_check_link_status(intel_dp);
+}
+
+static void intel_ddi_destroy(struct drm_encoder *encoder)
+{
+	/* HDMI has nothing special to destroy, so we can go with this. */
+	intel_dp_encoder_destroy(encoder);
+}
+
+static bool intel_ddi_mode_fixup(struct drm_encoder *encoder,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode)
+{
+	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
+	int type = intel_encoder->type;
+
+	WARN(type == INTEL_OUTPUT_UNKNOWN, "mode_fixup() on unknown output!\n");
+
+	if (type == INTEL_OUTPUT_HDMI)
+		return intel_hdmi_mode_fixup(encoder, mode, adjusted_mode);
+	else
+		return intel_dp_mode_fixup(encoder, mode, adjusted_mode);
+}
+
+static const struct drm_encoder_funcs intel_ddi_funcs = {
+	.destroy = intel_ddi_destroy,
+};
+
+static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = {
+	.mode_fixup = intel_ddi_mode_fixup,
+	.mode_set = intel_ddi_mode_set,
+	.disable = intel_encoder_noop,
+};
+
+void intel_ddi_init(struct drm_device *dev, enum port port)
+{
+	struct intel_digital_port *intel_dig_port;
+	struct intel_encoder *intel_encoder;
+	struct drm_encoder *encoder;
+	struct intel_connector *hdmi_connector = NULL;
+	struct intel_connector *dp_connector = NULL;
+
+	intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
+	if (!intel_dig_port)
+		return;
+
+	dp_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
+	if (!dp_connector) {
+		kfree(intel_dig_port);
+		return;
+	}
+
+	if (port != PORT_A) {
+		hdmi_connector = kzalloc(sizeof(struct intel_connector),
+					 GFP_KERNEL);
+		if (!hdmi_connector) {
+			kfree(dp_connector);
+			kfree(intel_dig_port);
+			return;
+		}
+	}
+
+	intel_encoder = &intel_dig_port->base;
+	encoder = &intel_encoder->base;
+
+	drm_encoder_init(dev, encoder, &intel_ddi_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+	drm_encoder_helper_add(encoder, &intel_ddi_helper_funcs);
+
+	intel_encoder->enable = intel_enable_ddi;
+	intel_encoder->pre_enable = intel_ddi_pre_enable;
+	intel_encoder->disable = intel_disable_ddi;
+	intel_encoder->post_disable = intel_ddi_post_disable;
+	intel_encoder->get_hw_state = intel_ddi_get_hw_state;
+
+	intel_dig_port->port = port;
+	if (hdmi_connector)
+		intel_dig_port->hdmi.sdvox_reg = DDI_BUF_CTL(port);
+	else
+		intel_dig_port->hdmi.sdvox_reg = 0;
+	intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
+
+	intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
+	intel_encoder->crtc_mask =  (1 << 0) | (1 << 1) | (1 << 2);
+	intel_encoder->cloneable = false;
+	intel_encoder->hot_plug = intel_ddi_hot_plug;
+
+	if (hdmi_connector)
+		intel_hdmi_init_connector(intel_dig_port, hdmi_connector);
+	intel_dp_init_connector(intel_dig_port, dp_connector);
+}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 66bff2d..ff5c332 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -685,7 +685,7 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
 	return ret;
 }
 
-static bool
+bool
 intel_dp_mode_fixup(struct drm_encoder *encoder,
 		    const struct drm_display_mode *mode,
 		    struct drm_display_mode *adjusted_mode)
@@ -2109,7 +2109,7 @@ intel_dp_handle_test_request(struct intel_dp *intel_dp)
  *  4. Check link status on receipt of hot-plug interrupt
  */
 
-static void
+void
 intel_dp_check_link_status(struct intel_dp *intel_dp)
 {
 	struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
@@ -2468,7 +2468,7 @@ intel_dp_destroy(struct drm_connector *connector)
 	kfree(connector);
 }
 
-static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
+void intel_dp_encoder_destroy(struct drm_encoder *encoder)
 {
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
@@ -2488,12 +2488,6 @@ static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
 	.disable = intel_encoder_noop,
 };
 
-static const struct drm_encoder_helper_funcs intel_dp_helper_funcs_hsw = {
-	.mode_fixup = intel_dp_mode_fixup,
-	.mode_set = intel_ddi_mode_set,
-	.disable = intel_encoder_noop,
-};
-
 static const struct drm_connector_funcs intel_dp_connector_funcs = {
 	.dpms = intel_connector_dpms,
 	.detect = intel_dp_detect,
@@ -2689,7 +2683,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
 		      I915_READ(PCH_PP_DIVISOR));
 }
 
-static void
+void
 intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			struct intel_connector *intel_connector)
 {
@@ -2722,8 +2716,11 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 		type = DRM_MODE_CONNECTOR_eDP;
 		intel_encoder->type = INTEL_OUTPUT_EDP;
 	} else {
+		/* The intel_encoder->type value may be INTEL_OUTPUT_UNKNOWN for
+		 * DDI or INTEL_OUTPUT_DISPLAYPORT for the older gens, so don't
+		 * rewrite it.
+		 */
 		type = DRM_MODE_CONNECTOR_DisplayPort;
-		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 	}
 
 	drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
@@ -2868,31 +2865,19 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 
 	drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
 			 DRM_MODE_ENCODER_TMDS);
+	drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs);
 
-	if (IS_HASWELL(dev)) {
-		drm_encoder_helper_add(&intel_encoder->base,
-				       &intel_dp_helper_funcs_hsw);
-
-		intel_encoder->enable = intel_enable_ddi;
-		intel_encoder->pre_enable = intel_ddi_pre_enable;
-		intel_encoder->disable = intel_disable_ddi;
-		intel_encoder->post_disable = intel_ddi_post_disable;
-		intel_encoder->get_hw_state = intel_ddi_get_hw_state;
-	} else {
-		drm_encoder_helper_add(&intel_encoder->base,
-				       &intel_dp_helper_funcs);
-
-		intel_encoder->enable = intel_enable_dp;
-		intel_encoder->pre_enable = intel_pre_enable_dp;
-		intel_encoder->disable = intel_disable_dp;
-		intel_encoder->post_disable = intel_post_disable_dp;
-		intel_encoder->get_hw_state = intel_dp_get_hw_state;
-	}
+	intel_encoder->enable = intel_enable_dp;
+	intel_encoder->pre_enable = intel_pre_enable_dp;
+	intel_encoder->disable = intel_disable_dp;
+	intel_encoder->post_disable = intel_post_disable_dp;
+	intel_encoder->get_hw_state = intel_dp_get_hw_state;
 
 	intel_dig_port->port = port;
 	intel_dig_port->dp.output_reg = output_reg;
 	intel_dig_port->hdmi.sdvox_reg = 0;
 
+	intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
 	intel_encoder->cloneable = false;
 	intel_encoder->hot_plug = intel_dp_hot_plug;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0a527729..4561f0c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -94,6 +94,7 @@
 #define INTEL_OUTPUT_HDMI 6
 #define INTEL_OUTPUT_DISPLAYPORT 7
 #define INTEL_OUTPUT_EDP 8
+#define INTEL_OUTPUT_UNKNOWN 9
 
 #define INTEL_DVO_CHIP_NONE 0
 #define INTEL_DVO_CHIP_LVDS 1
@@ -421,7 +422,12 @@ extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector)
 extern void intel_crt_init(struct drm_device *dev);
 extern void intel_hdmi_init(struct drm_device *dev,
 			    int sdvox_reg, enum port port);
+extern void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+				      struct intel_connector *intel_connector);
 extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
+extern bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
+				  const struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode);
 extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
 extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
 			    bool is_sdvob);
@@ -434,6 +440,8 @@ extern void intel_mark_fb_idle(struct drm_i915_gem_object *obj);
 extern bool intel_lvds_init(struct drm_device *dev);
 extern void intel_dp_init(struct drm_device *dev, int output_reg,
 			  enum port port);
+extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
+				    struct intel_connector *intel_connector);
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		 struct drm_display_mode *adjusted_mode);
@@ -441,6 +449,11 @@ extern void intel_dp_init_link_config(struct intel_dp *intel_dp);
 extern void intel_dp_start_link_train(struct intel_dp *intel_dp);
 extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
 extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
+extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
+extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
+extern bool intel_dp_mode_fixup(struct drm_encoder *encoder,
+				const struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode);
 extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
 extern void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
@@ -631,13 +644,8 @@ extern void intel_disable_gt_powersave(struct drm_device *dev);
 extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv);
 extern void ironlake_teardown_rc6(struct drm_device *dev);
 
-extern void intel_enable_ddi(struct intel_encoder *intel_encoder);
-extern void intel_disable_ddi(struct intel_encoder *intel_encoder);
 extern bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
 				   enum pipe *pipe);
-extern void intel_ddi_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode);
 extern int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv);
 extern void intel_ddi_pll_init(struct drm_device *dev);
 extern void intel_ddi_enable_pipe_func(struct drm_crtc *crtc);
@@ -647,8 +655,6 @@ extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
 extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
 extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
 extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock);
-extern void intel_ddi_pre_enable(struct intel_encoder *intel_encoder);
-extern void intel_ddi_post_disable(struct intel_encoder *intel_encoder);
 extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
 extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
 extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 79d15b3..1dcfd5b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -760,9 +760,9 @@ static int intel_hdmi_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
-				  const struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
+bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
+			   const struct drm_display_mode *mode,
+			   struct drm_display_mode *adjusted_mode)
 {
 	return true;
 }
@@ -926,12 +926,6 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
 	kfree(connector);
 }
 
-static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs_hsw = {
-	.mode_fixup = intel_hdmi_mode_fixup,
-	.mode_set = intel_ddi_mode_set,
-	.disable = intel_encoder_noop,
-};
-
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
 	.mode_fixup = intel_hdmi_mode_fixup,
 	.mode_set = intel_hdmi_mode_set,
@@ -963,8 +957,8 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
 	intel_attach_broadcast_rgb_property(connector);
 }
 
-static void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
-				      struct intel_connector *intel_connector)
+void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+			       struct intel_connector *intel_connector)
 {
 	struct drm_connector *connector = &intel_connector->base;
 	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
@@ -1059,21 +1053,11 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
 
 	drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
 			 DRM_MODE_ENCODER_TMDS);
-	if (IS_HASWELL(dev)) {
-		intel_encoder->pre_enable = intel_ddi_pre_enable;
-		intel_encoder->enable = intel_enable_ddi;
-		intel_encoder->disable = intel_disable_ddi;
-		intel_encoder->post_disable = intel_ddi_post_disable;
-		intel_encoder->get_hw_state = intel_ddi_get_hw_state;
-		drm_encoder_helper_add(&intel_encoder->base,
-				       &intel_hdmi_helper_funcs_hsw);
-	} else {
-		intel_encoder->enable = intel_enable_hdmi;
-		intel_encoder->disable = intel_disable_hdmi;
-		intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
-		drm_encoder_helper_add(&intel_encoder->base,
-				       &intel_hdmi_helper_funcs);
-	}
+	drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
+
+	intel_encoder->enable = intel_enable_hdmi;
+	intel_encoder->disable = intel_disable_hdmi;
+	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
 
 	intel_encoder->type = INTEL_OUTPUT_HDMI;
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/9] drm/i915: simplify assignments inside intel_dp.c
  2012-10-26 21:05 ` [PATCH 1/9] drm/i915: simplify assignments inside intel_dp.c Paulo Zanoni
@ 2012-10-30 11:32   ` Lespiau, Damien
  0 siblings, 0 replies; 20+ messages in thread
From: Lespiau, Damien @ 2012-10-30 11:32 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
>  - Replace container_of with enc_to_intel_dp.
>  - Walk through less structures when making assignments.
>  - Rename some variables to keep our naming standards.
>
> As a bonus, this will reduce the usage of "struct intel_dp", making
> the future patch that introduces intel_digital_port smaller and easier
> to review.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Reviewed-by: Damien Lespiau <damien.lespiau@gmail.com>

-- 
Damien

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/9] drm/i915: add intel_dp_to_dev and intel_hdmi_to_dev
  2012-10-26 21:05 ` [PATCH 2/9] drm/i915: add intel_dp_to_dev and intel_hdmi_to_dev Paulo Zanoni
@ 2012-10-30 11:37   ` Lespiau, Damien
  0 siblings, 0 replies; 20+ messages in thread
From: Lespiau, Damien @ 2012-10-30 11:37 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> When we add struct intel_digital_port, there will be no direct way of
> going from intel_{dp,hdmi} to drm_device: we will need to call
> container_of().
>
> This patch adds functions to go from intel_{dp,hdmi} to drm_device.
> The main goal here is to greatly reduce the size of the next patch,
> where we will change the implementation of the functions we just
> added here (among other things).
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

-- 
Damien

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/9] drm/i915: create intel_digital_port and use it
  2012-10-26 21:05 ` [PATCH 3/9] drm/i915: create intel_digital_port and use it Paulo Zanoni
@ 2012-10-30 11:44   ` Lespiau, Damien
  0 siblings, 0 replies; 20+ messages in thread
From: Lespiau, Damien @ 2012-10-30 11:44 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> The goal is to have one single encoder capable of controlling both DP
> and HDMI outputs. This patch just adds the initial infrastructure, no
> functional changes.
>
> Previously, both intel_dp and intel_hdmi were intel_encoders. Now,
> these 2 structs do not have intel_encoder as members anymore. The new
> struct intel_digital_port has intel_encoder as a member, and it also
> includes intel_dp and intel_hdmi as members. In other words: see the
> changes inside intel_drv.h: it's the most important change, everything
> else is only to make it compile and work.
>
> For now, each intel_digital_port is still only able to control one of
> HDMI or DP, but not both together.
>
> In the future we should also try to merge the common fields from
> intel_dp and intel_hdmi (e.g., port).
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

> +       struct intel_digital_port *intel_dig_port= dp_to_dig_port(intel_dp);

missing a ' ' befefore the '='.

-- 
Damien

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 4/9] drm/i915: split intel_hdmi_init into encoder and connector pieces
  2012-10-26 21:05 ` [PATCH 4/9] drm/i915: split intel_hdmi_init into encoder and connector pieces Paulo Zanoni
@ 2012-10-30 11:57   ` Lespiau, Damien
  0 siblings, 0 replies; 20+ messages in thread
From: Lespiau, Damien @ 2012-10-30 11:57 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> We want to split the HDMI connector and encoder initialization because
> in the future the DDI code will have its own "encoder init" function,
> but it will still call intel_hdmi_init_connector. The DDI encoder will
> actually have two connectors attached to it: HDMI and DP.
>
> The best way to look at this patch is to imagine that we're renaming
> intel_hdmi_init to intel_hdmi_init_connector and removing the
> encoder-specific pieces and placing them into intel_hdmi_init.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

-- 
Damien

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 5/9] drm/i915: split intel_dp_init into encoder and connector pieces
  2012-10-26 21:05 ` [PATCH 5/9] drm/i915: split intel_dp_init " Paulo Zanoni
@ 2012-10-30 12:07   ` Lespiau, Damien
  0 siblings, 0 replies; 20+ messages in thread
From: Lespiau, Damien @ 2012-10-30 12:07 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Same reason as the previous HDMI commit: the DDI code will have its
> own encoder init function but still use the DP and HDMI connectors.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

> +intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
...
> +       intel_dig_port->hdmi.sdvox_reg = 0;

That one does not seem necessary, esp. in dp_init() and seems to have
been added. Other than that:

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

-- 
Damien

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 6/9] drm/i915: reset intel_encoder->type when DP or HDMI is detected
  2012-10-26 21:05 ` [PATCH 6/9] drm/i915: reset intel_encoder->type when DP or HDMI is detected Paulo Zanoni
@ 2012-10-30 12:13   ` Damien Lespiau
  0 siblings, 0 replies; 20+ messages in thread
From: Damien Lespiau @ 2012-10-30 12:13 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> When intel_hdmi_detect detects a monitor, set intel_encoder->type with
> INTEL_OUTPUT_HDMI. Same for DP.
>
> This should not break the current code because these variables never
> change. This will be used after we create the DDI encoder because it
> will have both DP and HDMI connectors.
>
> We won't support eDP+HDMI on the same port, so if an encoder is eDP we
> should expect it to always remain eDP and never change.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

-- 
Damien

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 7/9] drm/i915: add port field to intel_digital_port
  2012-10-26 21:05 ` [PATCH 7/9] drm/i915: add port field to intel_digital_port Paulo Zanoni
@ 2012-10-30 12:17   ` Damien Lespiau
  0 siblings, 0 replies; 20+ messages in thread
From: Damien Lespiau @ 2012-10-30 12:17 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Both "intel_dp" and "intel_hdmi" structs had a "port" field, which
> always had the same value. It makes more sense to move this to
> intel_digital_port, so we can know the port independently of the
> connector type.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

-- 
Damien

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 8/9] drm/i915: add intel_ddi_connector_get_hw_state
  2012-10-26 21:05 ` [PATCH 8/9] drm/i915: add intel_ddi_connector_get_hw_state Paulo Zanoni
@ 2012-10-30 12:33   ` Damien Lespiau
  0 siblings, 0 replies; 20+ messages in thread
From: Damien Lespiau @ 2012-10-30 12:33 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> We need this since now on DDI we will have 2 connectors on each
> encoder.
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

-- 
Damien

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 9/9] drm/i915: create the DDI encoder
  2012-10-26 21:05 ` [PATCH 9/9] drm/i915: create the DDI encoder Paulo Zanoni
@ 2012-10-30 12:51   ` Damien Lespiau
  2012-10-30 21:36     ` Daniel Vetter
  0 siblings, 1 reply; 20+ messages in thread
From: Damien Lespiau @ 2012-10-30 12:51 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx, Paulo Zanoni

On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Now intel_ddi_init is just like intel_hdmi_init and intel_dp_init: it
> inits the encoder and then calls the proper init_connector functions.
> Notice that for non-eDP ports we call both HDMI and DP connector init,
> so we have 2 connectors attached to each DDI encoder.
>
> After this change, intel_hdmi_init and intel_dp_init are only called
> by Ivy Bridge and earlier, while hardware containing DDI outputs
> should call intel_ddi_init.
>
> Also added/removed quite a few "static" keywords due to the fact that
> some function pointers were moved from intel_dp.c and intel_hdmi.c to
> intel_ddi.c.
>
> DP finally works on Haswell now! \o/
>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

-- 
Damie

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 9/9] drm/i915: create the DDI encoder
  2012-10-30 12:51   ` Damien Lespiau
@ 2012-10-30 21:36     ` Daniel Vetter
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Vetter @ 2012-10-30 21:36 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx, Paulo Zanoni

On Tue, Oct 30, 2012 at 12:51:11PM +0000, Damien Lespiau wrote:
> On Fri, Oct 26, 2012 at 10:05 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> > From: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >
> > Now intel_ddi_init is just like intel_hdmi_init and intel_dp_init: it
> > inits the encoder and then calls the proper init_connector functions.
> > Notice that for non-eDP ports we call both HDMI and DP connector init,
> > so we have 2 connectors attached to each DDI encoder.
> >
> > After this change, intel_hdmi_init and intel_dp_init are only called
> > by Ivy Bridge and earlier, while hardware containing DDI outputs
> > should call intel_ddi_init.
> >
> > Also added/removed quite a few "static" keywords due to the fact that
> > some function pointers were moved from intel_dp.c and intel_hdmi.c to
> > intel_ddi.c.
> >
> > DP finally works on Haswell now! \o/
> >
> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> 
> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>

All merged to dinq, thanks for patches and review. There was a strange
patch conflict on the last one (I couldn't figure out what actually
conflicted), please check whether I haven't broken anything.

Yours, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2012-10-30 21:35 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-26 21:05 [PATCH 0/9] Haswell DDI encoder (DP + HDMI on the same port) Paulo Zanoni
2012-10-26 21:05 ` [PATCH 1/9] drm/i915: simplify assignments inside intel_dp.c Paulo Zanoni
2012-10-30 11:32   ` Lespiau, Damien
2012-10-26 21:05 ` [PATCH 2/9] drm/i915: add intel_dp_to_dev and intel_hdmi_to_dev Paulo Zanoni
2012-10-30 11:37   ` Lespiau, Damien
2012-10-26 21:05 ` [PATCH 3/9] drm/i915: create intel_digital_port and use it Paulo Zanoni
2012-10-30 11:44   ` Lespiau, Damien
2012-10-26 21:05 ` [PATCH 4/9] drm/i915: split intel_hdmi_init into encoder and connector pieces Paulo Zanoni
2012-10-30 11:57   ` Lespiau, Damien
2012-10-26 21:05 ` [PATCH 5/9] drm/i915: split intel_dp_init " Paulo Zanoni
2012-10-30 12:07   ` Lespiau, Damien
2012-10-26 21:05 ` [PATCH 6/9] drm/i915: reset intel_encoder->type when DP or HDMI is detected Paulo Zanoni
2012-10-30 12:13   ` Damien Lespiau
2012-10-26 21:05 ` [PATCH 7/9] drm/i915: add port field to intel_digital_port Paulo Zanoni
2012-10-30 12:17   ` Damien Lespiau
2012-10-26 21:05 ` [PATCH 8/9] drm/i915: add intel_ddi_connector_get_hw_state Paulo Zanoni
2012-10-30 12:33   ` Damien Lespiau
2012-10-26 21:05 ` [PATCH 9/9] drm/i915: create the DDI encoder Paulo Zanoni
2012-10-30 12:51   ` Damien Lespiau
2012-10-30 21:36     ` Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.