diff options
author | Clint Taylor <clinton.a.taylor@intel.com> | 2018-07-10 16:02:05 -0400 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2018-07-25 17:52:17 -0400 |
commit | 0ca9488193e61ec5f31a631d8147f74525629e8a (patch) | |
tree | 3166b754ad1fd1807cbb709b5f7c20d611eb6868 | |
parent | d72e90f33aa4709ebecc5005562f52335e106a60 (diff) |
drm/i915/glk: Add Quirk for GLK NUC HDMI port issues.
On GLK NUC platforms the HDMI retiming buffer needs additional disabled
time to correctly sync to a faster incoming signal.
When measured on a scope the highspeed lines of the HDMI clock turn off
for ~400uS during a normal resolution change. The HDMI retimer on the
GLK NUC appears to require at least a full frame of quiet time before a
new faster clock can be correctly sync'd. Wait 100ms due to msleep
inaccuracies while waiting for a completed frame. Add a quirk to the
driver for GLK boards that use ITE66317 HDMI retimers.
V2: Add more devices to the quirk list
V3: Delay increased to 100ms, check to confirm crtc type is HDMI.
V4: crtc type check extended to include _DDI and whitespace fixes
v5: Fix white spaces, remove the macro for delay. Revert the crtc type
check introduced in v4.
Cc: Imre Deak <imre.deak@intel.com>
Cc: <stable@vger.kernel.org> # v4.14+
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105887
Signed-off-by: Clint Taylor <clinton.a.taylor@intel.com>
Tested-by: Daniel Scheller <d.scheller.oss@gmail.com>
Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180710200205.1478-1-radhakrishna.sripada@intel.com
(cherry picked from commit 90c3e2198777aaa355b6994a31a79c636c8d4306)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 |
4 files changed, 33 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 52f3b91d14fd..71e1aa54f774 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -652,6 +652,7 @@ enum intel_sbi_destination { | |||
652 | #define QUIRK_BACKLIGHT_PRESENT (1<<3) | 652 | #define QUIRK_BACKLIGHT_PRESENT (1<<3) |
653 | #define QUIRK_PIN_SWIZZLED_PAGES (1<<5) | 653 | #define QUIRK_PIN_SWIZZLED_PAGES (1<<5) |
654 | #define QUIRK_INCREASE_T12_DELAY (1<<6) | 654 | #define QUIRK_INCREASE_T12_DELAY (1<<6) |
655 | #define QUIRK_INCREASE_DDI_DISABLED_TIME (1<<7) | ||
655 | 656 | ||
656 | struct intel_fbdev; | 657 | struct intel_fbdev; |
657 | struct intel_fbc_work; | 658 | struct intel_fbc_work; |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index f4a8598a2d39..fed26d6e4e27 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -1782,15 +1782,24 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state) | |||
1782 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); | 1782 | I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp); |
1783 | } | 1783 | } |
1784 | 1784 | ||
1785 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, | 1785 | void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state) |
1786 | enum transcoder cpu_transcoder) | ||
1787 | { | 1786 | { |
1787 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); | ||
1788 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); | ||
1789 | enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; | ||
1788 | i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); | 1790 | i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); |
1789 | uint32_t val = I915_READ(reg); | 1791 | uint32_t val = I915_READ(reg); |
1790 | 1792 | ||
1791 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC); | 1793 | val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC); |
1792 | val |= TRANS_DDI_PORT_NONE; | 1794 | val |= TRANS_DDI_PORT_NONE; |
1793 | I915_WRITE(reg, val); | 1795 | I915_WRITE(reg, val); |
1796 | |||
1797 | if (dev_priv->quirks & QUIRK_INCREASE_DDI_DISABLED_TIME && | ||
1798 | intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { | ||
1799 | DRM_DEBUG_KMS("Quirk Increase DDI disabled time\n"); | ||
1800 | /* Quirk time at 100ms for reliable operation */ | ||
1801 | msleep(100); | ||
1802 | } | ||
1794 | } | 1803 | } |
1795 | 1804 | ||
1796 | int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, | 1805 | int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2cc6faa1daa8..dec0d60921bf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -5809,7 +5809,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state, | |||
5809 | intel_ddi_set_vc_payload_alloc(intel_crtc->config, false); | 5809 | intel_ddi_set_vc_payload_alloc(intel_crtc->config, false); |
5810 | 5810 | ||
5811 | if (!transcoder_is_dsi(cpu_transcoder)) | 5811 | if (!transcoder_is_dsi(cpu_transcoder)) |
5812 | intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); | 5812 | intel_ddi_disable_transcoder_func(old_crtc_state); |
5813 | 5813 | ||
5814 | if (INTEL_GEN(dev_priv) >= 9) | 5814 | if (INTEL_GEN(dev_priv) >= 9) |
5815 | skylake_scaler_disable(intel_crtc); | 5815 | skylake_scaler_disable(intel_crtc); |
@@ -14646,6 +14646,18 @@ static void quirk_increase_t12_delay(struct drm_device *dev) | |||
14646 | DRM_INFO("Applying T12 delay quirk\n"); | 14646 | DRM_INFO("Applying T12 delay quirk\n"); |
14647 | } | 14647 | } |
14648 | 14648 | ||
14649 | /* | ||
14650 | * GeminiLake NUC HDMI outputs require additional off time | ||
14651 | * this allows the onboard retimer to correctly sync to signal | ||
14652 | */ | ||
14653 | static void quirk_increase_ddi_disabled_time(struct drm_device *dev) | ||
14654 | { | ||
14655 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
14656 | |||
14657 | dev_priv->quirks |= QUIRK_INCREASE_DDI_DISABLED_TIME; | ||
14658 | DRM_INFO("Applying Increase DDI Disabled quirk\n"); | ||
14659 | } | ||
14660 | |||
14649 | struct intel_quirk { | 14661 | struct intel_quirk { |
14650 | int device; | 14662 | int device; |
14651 | int subsystem_vendor; | 14663 | int subsystem_vendor; |
@@ -14732,6 +14744,13 @@ static struct intel_quirk intel_quirks[] = { | |||
14732 | 14744 | ||
14733 | /* Toshiba Satellite P50-C-18C */ | 14745 | /* Toshiba Satellite P50-C-18C */ |
14734 | { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay }, | 14746 | { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay }, |
14747 | |||
14748 | /* GeminiLake NUC */ | ||
14749 | { 0x3185, 0x8086, 0x2072, quirk_increase_ddi_disabled_time }, | ||
14750 | { 0x3184, 0x8086, 0x2072, quirk_increase_ddi_disabled_time }, | ||
14751 | /* ASRock ITX*/ | ||
14752 | { 0x3185, 0x1849, 0x2212, quirk_increase_ddi_disabled_time }, | ||
14753 | { 0x3184, 0x1849, 0x2212, quirk_increase_ddi_disabled_time }, | ||
14735 | }; | 14754 | }; |
14736 | 14755 | ||
14737 | static void intel_init_quirks(struct drm_device *dev) | 14756 | static void intel_init_quirks(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0361130500a6..b8eefbffc77d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -1388,8 +1388,7 @@ void hsw_fdi_link_train(struct intel_crtc *crtc, | |||
1388 | void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port); | 1388 | void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port); |
1389 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); | 1389 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); |
1390 | void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state); | 1390 | void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state); |
1391 | void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, | 1391 | void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state); |
1392 | enum transcoder cpu_transcoder); | ||
1393 | void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state); | 1392 | void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state); |
1394 | void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state); | 1393 | void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state); |
1395 | struct intel_encoder * | 1394 | struct intel_encoder * |