From 4f56d12ebb28fceac4c6e60c8993fbfc122e1399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 21 Oct 2013 10:52:06 +0300 Subject: [PATCH 1/6] drm/i915: Add support for pipe_bpp readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On CTG+ read out the pipe bpp setting from hardware and fill it into pipe config. Also check it appropriately. v2: Don't do the pipe_bpp extraction inside the PCH only code block on ILK+. Avoid the PIPECONF read as we already have read it for the PIPECONF_EANBLE check. Note: This is already in drm-intel-next-queued as commit 42571aefafb1d330ef84eb29418832f72e7dfb4c Author: Ville Syrjälä Date: Fri Sep 6 23:29:00 2013 +0300 drm/i915: Add support for pipe_bpp readout but is needed for the following bugfix. Signed-off-by: Ville Syrjälä Reviewed-by: Jani Nikula Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 17 +++++++++++++ drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 63de2701b974..beb7f65cd01f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1268,6 +1268,23 @@ static void intel_ddi_get_config(struct intel_encoder *encoder, flags |= DRM_MODE_FLAG_NVSYNC; pipe_config->adjusted_mode.flags |= flags; + + switch (temp & TRANS_DDI_BPC_MASK) { + case TRANS_DDI_BPC_6: + pipe_config->pipe_bpp = 18; + break; + case TRANS_DDI_BPC_8: + pipe_config->pipe_bpp = 24; + break; + case TRANS_DDI_BPC_10: + pipe_config->pipe_bpp = 30; + break; + case TRANS_DDI_BPC_12: + pipe_config->pipe_bpp = 36; + break; + default: + break; + } } static void intel_ddi_destroy(struct drm_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 581fb4b2f766..725f0bea1e4c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4983,6 +4983,22 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, if (!(tmp & PIPECONF_ENABLE)) return false; + if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) { + switch (tmp & PIPECONF_BPC_MASK) { + case PIPECONF_6BPC: + pipe_config->pipe_bpp = 18; + break; + case PIPECONF_8BPC: + pipe_config->pipe_bpp = 24; + break; + case PIPECONF_10BPC: + pipe_config->pipe_bpp = 30; + break; + default: + break; + } + } + intel_get_pipe_timings(crtc, pipe_config); i9xx_get_pfit_config(crtc, pipe_config); @@ -5881,6 +5897,23 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, if (!(tmp & PIPECONF_ENABLE)) return false; + switch (tmp & PIPECONF_BPC_MASK) { + case PIPECONF_6BPC: + pipe_config->pipe_bpp = 18; + break; + case PIPECONF_8BPC: + pipe_config->pipe_bpp = 24; + break; + case PIPECONF_10BPC: + pipe_config->pipe_bpp = 30; + break; + case PIPECONF_12BPC: + pipe_config->pipe_bpp = 36; + break; + default: + break; + } + if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { struct intel_shared_dpll *pll; @@ -8612,6 +8645,9 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_X(dpll_hw_state.fp0); PIPE_CONF_CHECK_X(dpll_hw_state.fp1); + if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) + PIPE_CONF_CHECK_I(pipe_bpp); + #undef PIPE_CONF_CHECK_X #undef PIPE_CONF_CHECK_I #undef PIPE_CONF_CHECK_FLAGS From 7195a50b5c7e00cc3312934fd022c3006b533d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 24 Sep 2013 14:24:05 +0300 Subject: [PATCH 2/6] drm/i915: Add HSW CRT output readout support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call intel_ddi_get_config() to get the pipe_bpp settings from DDI. The sync polarity settings from DDI are irrelevant for CRT output, so override them with data from the ADPA register. Note: This is already merged in drm-intel-next-queued as commit 6801c18c0a43386bb44712cbc028a7e05adb9f0d Author: Ville Syrjälä Date: Tue Sep 24 14:24:05 2013 +0300 drm/i915: Add HSW CRT output readout support but is required for the following edp bpp bugfix. v2: Extract intel_crt_get_flags() Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=69691 Tested-by: Qingshuai Tian Signed-off-by: Ville Syrjälä Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_crt.c | 30 ++++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_ddi.c | 4 ++-- drivers/gpu/drm/i915/intel_drv.h | 2 ++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index ea9022ef15d5..db59bb9fbe23 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -83,8 +83,7 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, return true; } -static void intel_crt_get_config(struct intel_encoder *encoder, - struct intel_crtc_config *pipe_config) +static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crt *crt = intel_encoder_to_crt(encoder); @@ -102,7 +101,27 @@ static void intel_crt_get_config(struct intel_encoder *encoder, else flags |= DRM_MODE_FLAG_NVSYNC; - pipe_config->adjusted_mode.flags |= flags; + return flags; +} + +static void intel_crt_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + struct drm_device *dev = encoder->base.dev; + + pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder); +} + +static void hsw_crt_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + intel_ddi_get_config(encoder, pipe_config); + + pipe_config->adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC | + DRM_MODE_FLAG_NHSYNC | + DRM_MODE_FLAG_PVSYNC | + DRM_MODE_FLAG_NVSYNC); + pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder); } /* Note: The caller is required to filter out dpms modes not supported by the @@ -799,7 +818,10 @@ void intel_crt_init(struct drm_device *dev) crt->base.mode_set = intel_crt_mode_set; crt->base.disable = intel_disable_crt; crt->base.enable = intel_enable_crt; - crt->base.get_config = intel_crt_get_config; + if (IS_HASWELL(dev)) + crt->base.get_config = hsw_crt_get_config; + else + crt->base.get_config = intel_crt_get_config; if (I915_HAS_HOTPLUG(dev)) crt->base.hpd_pin = HPD_CRT; if (HAS_DDI(dev)) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index beb7f65cd01f..b53fff84a7d5 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1249,8 +1249,8 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder) intel_dp_check_link_status(intel_dp); } -static void intel_ddi_get_config(struct intel_encoder *encoder, - struct intel_crtc_config *pipe_config) +void intel_ddi_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9b7b68fd5d47..7f2b384ac939 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -765,6 +765,8 @@ extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder); extern bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector); extern void intel_ddi_fdi_disable(struct drm_crtc *crtc); +extern void intel_ddi_get_config(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config); extern void intel_display_handle_reset(struct drm_device *dev); extern bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, From c6cd2ee2d59111a07cd9199564c9bdcb2d11e5cf Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 21 Oct 2013 10:52:07 +0300 Subject: [PATCH 3/6] drm/i915/dp: workaround BIOS eDP bpp clamping issue This isn't a real fix to the problem, but rather a stopgap measure while trying to find a proper solution. There are several laptops out there that fail to light up the eDP panel in UEFI boot mode. They seem to be mostly IVB machines, including but apparently not limited to Dell XPS 13, Asus TX300, Asus UX31A, Asus UX32VD, Acer Aspire S7. They seem to work in CSM or legacy boot. The difference between UEFI and CSM is that the BIOS provides a different VBT to the kernel. The UEFI VBT typically specifies 18 bpp and 1.62 GHz link for eDP, while CSM VBT has 24 bpp and 2.7 GHz link. We end up clamping to 18 bpp in UEFI mode, which we can fit in the 1.62 Ghz link, and for reasons yet unknown fail to light up the panel. Dithering from 24 to 18 bpp itself seems to work; if we use 18 bpp with 2.7 GHz link, the eDP panel lights up. So essentially this is a link speed issue, and *not* a bpp clamping issue. The bug raised its head since commit 657445fe8660100ad174600ebfa61536392b7624 Author: Daniel Vetter Date: Sat May 4 10:09:18 2013 +0200 Revert "drm/i915: revert eDP bpp clamping code changes" which started clamping bpp *before* computing the link requirements, and thus affecting the required bandwidth. Clamping after the computations kept the link at 2.7 GHz. Even though the BIOS tells us to use 18 bpp through the VBT, it happily boots up at 24 bpp and 2.7 GHz itself! Use this information to selectively ignore the VBT provided value. We can't ignore the VBT eDP bpp altogether, as there are other laptops that do require the clamping to be used due to EDID reporting higher bpp than the panel can support. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=59841 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67950 Tested-by: Ulf Winkelvos Tested-by: jkp CC: stable@vger.kernel.org Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2c555f91bfae..1a431377d83b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1401,6 +1401,26 @@ static void intel_dp_get_config(struct intel_encoder *encoder, else pipe_config->port_clock = 270000; } + + if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp && + pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) { + /* + * This is a big fat ugly hack. + * + * Some machines in UEFI boot mode provide us a VBT that has 18 + * bpp and 1.62 GHz link bandwidth for eDP, which for reasons + * unknown we fail to light up. Yet the same BIOS boots up with + * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as + * max, not what it tells us to use. + * + * Note: This will still be broken if the eDP panel is not lit + * up by the BIOS, and thus we can't get the mode at module + * load. + */ + DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", + pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp); + dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; + } } static bool is_edp_psr(struct intel_dp *intel_dp) From 645378d85ee524e429aa4cf52806047b56cdc596 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Sun, 27 Oct 2013 16:13:42 +0000 Subject: [PATCH 4/6] drm/i915: No LVDS hardware on Intel D410PT and D425KT The Intel D410PT(LW) and D425KT Mini-ITX desktop boards both show up as having LVDS but the hardware is not populated. This patch adds them to the list of such systems. Patch is against 3.11.4 v2: Patch revised to match the D425KT exactly as the D425KTW does have LVDS. According to Intel's documentation, the D410PTL and D410PLTW don't. Signed-off-by: Rob Pearce Cc: stable@vger.kernel.org [danvet: Pimp commit message to my liking and add cc: stable.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lvds.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 831a5c021c4b..b8af94a5be39 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -698,6 +698,22 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"), }, }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Intel D410PT", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Intel"), + DMI_MATCH(DMI_BOARD_NAME, "D410PT"), + }, + }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Intel D425KT", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Intel"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "D425KT"), + }, + }, { .callback = intel_no_lvds_dmi_callback, .ident = "Intel D510MO", From 1fbc0d789d12fec313c91912fc11733fdfbab863 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 29 Oct 2013 12:04:08 +0100 Subject: [PATCH 5/6] drm/i915: Fix the PPT fdi lane bifurcate state handling on ivb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Originally I've thought that this is leftover hw state dirt from the BIOS. But after way too much helpless flailing around on my part I've noticed that the actual bug is when we change the state of an already active pipe. For example when we change the fdi lines from 2 to 3 without switching off outputs in-between we'll never see the crucial on->off transition in the ->modeset_global_resources hook the current logic relies on. Patch version 2 got this right by instead also checking whether the pipe is indeed active. But that in turn broke things when pipes have been turned off through dpms since the bifurcate enabling is done in the ->crtc_mode_set callback. To address this issues discussed with Ville in the patch review move the setting of the bifurcate bit into the ->crtc_enable hook. That way we won't wreak havoc with this state when userspace puts all other outputs into dpms off state. This also moves us forward with our overall goal to unify the modeset and dpms on paths (which we need to have to allow runtime pm in the dpms off state). Unfortunately this requires us to move the bifurcate helpers around a bit. Also update the commit message, I've misanalyzed the bug rather badly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70507 Tested-by: Jan-Michael Brummer Cc: stable@vger.kernel.org Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 95 ++++++++++++++-------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 725f0bea1e4c..d78d33f9337d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2327,9 +2327,10 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc) FDI_FE_ERRC_ENABLE); } -static bool pipe_has_enabled_pch(struct intel_crtc *intel_crtc) +static bool pipe_has_enabled_pch(struct intel_crtc *crtc) { - return intel_crtc->base.enabled && intel_crtc->config.has_pch_encoder; + return crtc->base.enabled && crtc->active && + crtc->config.has_pch_encoder; } static void ivb_modeset_global_resources(struct drm_device *dev) @@ -2979,6 +2980,48 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc, I915_READ(VSYNCSHIFT(cpu_transcoder))); } +static void cpt_enable_fdi_bc_bifurcation(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t temp; + + temp = I915_READ(SOUTH_CHICKEN1); + if (temp & FDI_BC_BIFURCATION_SELECT) + return; + + WARN_ON(I915_READ(FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE); + WARN_ON(I915_READ(FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE); + + temp |= FDI_BC_BIFURCATION_SELECT; + DRM_DEBUG_KMS("enabling fdi C rx\n"); + I915_WRITE(SOUTH_CHICKEN1, temp); + POSTING_READ(SOUTH_CHICKEN1); +} + +static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc) +{ + struct drm_device *dev = intel_crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + switch (intel_crtc->pipe) { + case PIPE_A: + break; + case PIPE_B: + if (intel_crtc->config.fdi_lanes > 2) + WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT); + else + cpt_enable_fdi_bc_bifurcation(dev); + + break; + case PIPE_C: + cpt_enable_fdi_bc_bifurcation(dev); + + break; + default: + BUG(); + } +} + /* * Enable PCH resources required for PCH ports: * - PCH PLLs @@ -2997,6 +3040,9 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) assert_pch_transcoder_disabled(dev_priv, pipe); + if (IS_IVYBRIDGE(dev)) + ivybridge_update_fdi_bc_bifurcation(intel_crtc); + /* Write the TU size bits before fdi link training, so that error * detection works. */ I915_WRITE(FDI_RX_TUSIZE1(pipe), @@ -5592,48 +5638,6 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc, return true; } -static void cpt_enable_fdi_bc_bifurcation(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t temp; - - temp = I915_READ(SOUTH_CHICKEN1); - if (temp & FDI_BC_BIFURCATION_SELECT) - return; - - WARN_ON(I915_READ(FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE); - WARN_ON(I915_READ(FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE); - - temp |= FDI_BC_BIFURCATION_SELECT; - DRM_DEBUG_KMS("enabling fdi C rx\n"); - I915_WRITE(SOUTH_CHICKEN1, temp); - POSTING_READ(SOUTH_CHICKEN1); -} - -static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc) -{ - struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - switch (intel_crtc->pipe) { - case PIPE_A: - break; - case PIPE_B: - if (intel_crtc->config.fdi_lanes > 2) - WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT); - else - cpt_enable_fdi_bc_bifurcation(dev); - - break; - case PIPE_C: - cpt_enable_fdi_bc_bifurcation(dev); - - break; - default: - BUG(); - } -} - int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp) { /* @@ -5827,9 +5831,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, &intel_crtc->config.fdi_m_n); } - if (IS_IVYBRIDGE(dev)) - ivybridge_update_fdi_bc_bifurcation(intel_crtc); - ironlake_set_pipeconf(crtc); /* Set up the display plane register */ From 3d3b78c06c827bfc072a11056d7eb70aeb90e449 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 28 Oct 2013 10:55:49 +0100 Subject: [PATCH 6/6] drm: allow DRM_IOCTL_VERSION on render-nodes DRM_IOCTL_VERSION is a reliable way to get the driver-name and version information. It's not related to the interface-version (SET_VERSION ioctl) so we can safely enable it on render-nodes. Note that gbm uses udev-BUSID to load the correct mesa driver. However, the VERSION ioctl should be the more reliable way to do this (in case we add new DRM-bus drivers which have no BUSID or similar). Signed-off-by: David Herrmann Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 05ad9ba0a67e..fe58d0833a11 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -61,7 +61,7 @@ static int drm_version(struct drm_device *dev, void *data, /** Ioctl table */ static const struct drm_ioctl_desc drm_ioctls[] = { - DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),