From c93f54cf7de31d44b4036d0d1e291172b2bd5743 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 27 Jun 2013 19:47:19 +0200 Subject: drm/i915: pixel multiplier readout support for pch ports Now that we painstakingly track the shared pch dplls we can finally implement pixel mutliplier readout support for pch ports, too. v2: Undo the temporary hack to disable the sdvo pixel multiplier cross-checking. Cc: Imre Deak Cc: Jesse Barnes Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_sdvo.c') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 2628d562244..8415d6a610d 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1370,9 +1370,6 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, break; } - if(HAS_PCH_SPLIT(dev)) - return; /* no pixel multiplier readout support yet */ - WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n", pipe_config->pixel_multiplier, encoder_pixel_multiplier); -- cgit v1.2.3-70-g09d2 From 53b914084950e5766b40228c4e08706e28745fa5 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 12 Jul 2013 16:24:40 +0100 Subject: drm/i915: Don't attempt to read an unitialized stack value If intel_sdvo_get_value() fails here, val is unitialized and the cross check will compare the pipe config multiplier with a bogus value. Instead, only set encoder_pixel_multiplier when the sdvo command has been successful. The cross check will compare the pipe config value with 0 otherwise. v2: Do the cross check with the initial value of encoder_pixel_multiplier (0) if the sdvo command fails (and thus keep the warning) (Daniel Vetter) Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_sdvo.c') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 8415d6a610d..798df114cfd 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1357,17 +1357,19 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, } /* Cross check the port pixel multiplier with the sdvo encoder state. */ - intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, &val, 1); - switch (val) { - case SDVO_CLOCK_RATE_MULT_1X: - encoder_pixel_multiplier = 1; - break; - case SDVO_CLOCK_RATE_MULT_2X: - encoder_pixel_multiplier = 2; - break; - case SDVO_CLOCK_RATE_MULT_4X: - encoder_pixel_multiplier = 4; - break; + if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, + &val, 1)) { + switch (val) { + case SDVO_CLOCK_RATE_MULT_1X: + encoder_pixel_multiplier = 1; + break; + case SDVO_CLOCK_RATE_MULT_2X: + encoder_pixel_multiplier = 2; + break; + case SDVO_CLOCK_RATE_MULT_4X: + encoder_pixel_multiplier = 4; + break; + } } WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier, -- cgit v1.2.3-70-g09d2 From 164c8598450657d01fa75d6c997e95eb35672eef Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 20 Jul 2013 20:27:08 +0100 Subject: drm/i915: Add some debug breadcrumbs to connector detection Try to decypher detection failures is a little tricker at the moment as the only indicator of progress is when output_poll_execute() tells us the result after the connector->detect() has run. This patch adds a telltale to the start of each detect function so that we can track progress and associate activity more clearly with each connector. Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_crt.c | 4 ++++ drivers/gpu/drm/i915/intel_dp.c | 3 +++ drivers/gpu/drm/i915/intel_dvo.c | 2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 3 +++ drivers/gpu/drm/i915/intel_lvds.c | 3 +++ drivers/gpu/drm/i915/intel_sdvo.c | 3 +++ drivers/gpu/drm/i915/intel_tv.c | 4 ++++ 7 files changed, 22 insertions(+) (limited to 'drivers/gpu/drm/i915/intel_sdvo.c') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 3acec8c4816..0c0d4e8d768 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -613,6 +613,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) enum drm_connector_status status; struct intel_load_detect_pipe tmp; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", + connector->base.id, drm_get_connector_name(connector), + force); + if (I915_HAS_HOTPLUG(dev)) { /* We can not rely on the HPD pin always being correctly wired * up, for example many KVM do not pass it through, and so diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d391ce38ec2..1761877b72e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2815,6 +2815,9 @@ intel_dp_detect(struct drm_connector *connector, bool force) enum drm_connector_status status; struct edid *edid = NULL; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, drm_get_connector_name(connector)); + intel_dp->has_audio = false; if (HAS_PCH_SPLIT(dev)) diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index cbbc49dc03b..8b4ad27791f 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -332,6 +332,8 @@ static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector, bool force) { struct intel_dvo *intel_dvo = intel_attached_dvo(connector); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, drm_get_connector_name(connector)); return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 98df2a0c85b..af18da76c04 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -866,6 +866,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) struct edid *edid; enum drm_connector_status status = connector_status_disconnected; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, drm_get_connector_name(connector)); + intel_hdmi->has_hdmi_sink = false; intel_hdmi->has_audio = false; intel_hdmi->rgb_quant_range_selectable = false; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b0e1088b2c9..25ea4069614 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -339,6 +339,9 @@ intel_lvds_detect(struct drm_connector *connector, bool force) struct drm_device *dev = connector->dev; enum drm_connector_status status; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, drm_get_connector_name(connector)); + status = intel_panel_detect(dev); if (status != connector_status_unknown) return status; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 798df114cfd..c3b59b8593b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1696,6 +1696,9 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); enum drm_connector_status ret; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, drm_get_connector_name(connector)); + if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ATTACHED_DISPLAYS, &response, 2)) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 39debd80d19..b0b446f630f 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1305,6 +1305,10 @@ intel_tv_detect(struct drm_connector *connector, bool force) struct intel_tv *intel_tv = intel_attached_tv(connector); int type; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", + connector->base.id, drm_get_connector_name(connector), + force); + mode = reported_modes[0]; if (force) { -- cgit v1.2.3-70-g09d2 From 8aca63aae07681a0c9a2a0ebcca82ca5f7f6aa08 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 21 Jul 2013 21:37:01 +0200 Subject: drm/i915/sdvo: use intel_encoder for upcast helper It's what all callers (except for the destroy callback which is called from drm core) actually want. Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_sdvo.c') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c3b59b8593b..47423f31f82 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -202,15 +202,14 @@ struct intel_sdvo_connector { u32 cur_dot_crawl, max_dot_crawl; }; -static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder) +static struct intel_sdvo *to_sdvo(struct intel_encoder *encoder) { - return container_of(encoder, struct intel_sdvo, base.base); + return container_of(encoder, struct intel_sdvo, base); } static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) { - return container_of(intel_attached_encoder(connector), - struct intel_sdvo, base); + return to_sdvo(intel_attached_encoder(connector)); } static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) @@ -1084,7 +1083,7 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config) static bool intel_sdvo_compute_config(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config) { - struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); + struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; struct drm_display_mode *mode = &pipe_config->requested_mode; @@ -1154,7 +1153,7 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder) struct drm_display_mode *adjusted_mode = &intel_crtc->config.adjusted_mode; struct drm_display_mode *mode = &intel_crtc->config.requested_mode; - struct intel_sdvo *intel_sdvo = to_intel_sdvo(&intel_encoder->base); + struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder); u32 sdvox; struct intel_sdvo_in_out_map in_out; struct intel_sdvo_dtd input_dtd, output_dtd; @@ -1292,7 +1291,7 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); + struct intel_sdvo *intel_sdvo = to_sdvo(encoder); u16 active_outputs = 0; u32 tmp; @@ -1315,7 +1314,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); + struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_sdvo_dtd dtd; int encoder_pixel_multiplier = 0; u32 flags = 0, sdvox; @@ -1380,7 +1379,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, static void intel_disable_sdvo(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); + struct intel_sdvo *intel_sdvo = to_sdvo(encoder); u32 temp; intel_sdvo_set_active_outputs(intel_sdvo, 0); @@ -1422,7 +1421,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); + struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); u32 temp; bool input1, input2; @@ -1583,7 +1582,7 @@ static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo) static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) { - struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); + struct intel_sdvo *intel_sdvo = to_sdvo(encoder); intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &intel_sdvo->hotplug_active, 2); @@ -2190,7 +2189,7 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) { - struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); + struct intel_sdvo *intel_sdvo = to_sdvo(to_intel_encoder(encoder)); if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) drm_mode_destroy(encoder->dev, -- cgit v1.2.3-70-g09d2 From 15dcd3502160a46acf11e5cb5e80e9d90a6f9f60 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 6 Aug 2013 20:32:20 +0100 Subject: drm/i915/sdvo: Port the infoframe code to the shared infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Ville Syrjälä Signed-off-by: Damien Lespiau Signed-off-by: Paulo Zanoni Signed-off-by: Thierry Reding Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_sdvo.c') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 47423f31f82..02f220b4e4a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -963,30 +963,32 @@ static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, const struct drm_display_mode *adjusted_mode) { - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .ver = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; - struct intel_crtc *intel_crtc = to_intel_crtc(intel_sdvo->base.base.crtc); + uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)]; + struct drm_crtc *crtc = intel_sdvo->base.base.crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + union hdmi_infoframe frame; + int ret; + ssize_t len; + + ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, + adjusted_mode); + if (ret < 0) { + DRM_ERROR("couldn't fill AVI infoframe\n"); + return false; + } if (intel_sdvo->rgb_quant_range_selectable) { if (intel_crtc->config.limited_color_range) - avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED; + frame.avi.quantization_range = + HDMI_QUANTIZATION_RANGE_LIMITED; else - avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL; + frame.avi.quantization_range = + HDMI_QUANTIZATION_RANGE_FULL; } - avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode); - - intel_dip_infoframe_csum(&avi_if); - - /* sdvo spec says that the ecc is handled by the hw, and it looks like - * we must not send the ecc field, either. */ - memcpy(sdvo_data, &avi_if, 3); - sdvo_data[3] = avi_if.checksum; - memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); + len = hdmi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data)); + if (len < 0) + return false; return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, SDVO_HBUF_TX_VSYNC, -- cgit v1.2.3-70-g09d2 From 1ad87e72b54cf3b698c002f0a31ac34d6b407f0b Mon Sep 17 00:00:00 2001 From: Guillaume Clement Date: Sat, 10 Aug 2013 21:57:57 +0200 Subject: i915: Fix SDVO potentially turning off randomly Some Poulsbo cards seem to incorrectly report SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED instead of SDVO_CMD_STATUS_PENDING, which causes the display to be turned off. This could also happen to i915. Signed-off-by: Guillaume Clement Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/intel_sdvo.c') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 02f220b4e4a..317e058fb3c 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -538,7 +538,8 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, &status)) goto log_fail; - while (status == SDVO_CMD_STATUS_PENDING && --retry) { + while ((status == SDVO_CMD_STATUS_PENDING || + status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && --retry) { if (retry < 10) msleep(15); else -- cgit v1.2.3-70-g09d2