[Intel-gfx] [PATCH] i915/gem: Force HW tracking to exit PSR
Instead of calling i915_gem_object_invalidate_frontbuffer(), call i915_gem_object_flush_frontbuffer() which will eventually call psr_force_hw_tracking_exit(). This will force HW tracking to exit PSR instead of disabling and re-enabling. On Gen9 Intel chromebooks, while playing around with Squid software, after drawing line, line delay was observed.Also can see flash, garbage and even shaking display sometimes. With this fix, issues reported were resolved on Gen9 and Gen11 Intel chromebooks. Tested the patch on non-PSR, PSR1 and PSR2 panels, no issue observed. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index 7f76fc68f498..810fc2381743 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -461,6 +461,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_gem_set_domain *args = data; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; u32 read_domains = args->read_domains; u32 write_domain = args->write_domain; @@ -552,8 +553,13 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, i915_gem_object_unlock(obj); - if (write_domain) - i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); + if (write_domain) { + if (dev_priv->psr.active) + i915_gem_object_flush_frontbuffer(obj, ORIGIN_DIRTYFB); + else + i915_gem_object_invalidate_frontbuffer(obj, + ORIGIN_CPU); + } out_unpin: i915_gem_object_unpin_pages(obj); -- 2.27.0-rc2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] i915/gem: Force HW tracking to exit PSR
Instead of calling i915_gem_object_invalidate_frontbuffer(), call i915_gem_object_flush_frontbuffer() which will eventually call psr_force_hw_tracking_exit(). This will force HW tracking to exit PSR instead of disabling and re-enabling. On Gen9 Intel chromebooks, while playing around with Squid software, after drawing line, line delay was observed.Also can see flash, garbage and even shaking display sometimes. With this fix, issues reported were resolved on Gen9 and Gen11 Intel chromebooks. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index 7f76fc68f498..fb1daddde286 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -553,7 +553,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, i915_gem_object_unlock(obj); if (write_domain) - i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); + i915_gem_object_flush_frontbuffer(obj, ORIGIN_DIRTYFB); out_unpin: i915_gem_object_unpin_pages(obj); -- 2.27.0-rc2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Add DPCD quirk for AUO PSR2 panel
Currently on AUO PSR2 panel on Gen9 chromebook, we are observing below issues: (i) The display will show garbage after pressing sign out icon in log in screen when wallpaper is one of Solid colors & PSR2 is enabled (ii) The characters of display is not clear when switch OS mode to dev mode. Before this patch, on this panel, we set idle frame count to 6 that is number of idle frames before entering PSR2 deep sleep and the number of frames to enter into Selective update we set to 1. On this AUO panel, we suspect there is some DP synchronization latency needed, due to which we are facing the above issues. With current TCON of the AUO panel, DPCD reg DP_SYNCHRONIZATION_LATENCY_IN_SINK (0x2009) offset is giving a value of 0x0. This patch sets idle frame count to 9 and frame count for selective update to 9, after which we are not seeing the above mentioned issues. Ideally this value needs to be corrected in TCON of the panel since this value comes from DPCD reg 0x2009 offset and i915 driver uses it. Working with AUO panel vendor to get this fixed in the panel TCON. In the meantime fixing this as DPCD quirk in the kernel. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/drm_dp_helper.c | 3 +++ drivers/gpu/drm/i915/display/intel_psr.c | 6 ++ include/drm/drm_dp_helper.h | 9 + 3 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 2c7870aef469..96eaeef814d3 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -1155,6 +1155,9 @@ struct dpcd_quirk { { OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_NO_PSR) }, /* CH7511 seems to leave SINK_COUNT zeroed */ { OUI(0x00, 0x00, 0x00), DEVICE_ID('C', 'H', '7', '5', '1', '1'), false, BIT(DP_DPCD_QUIRK_NO_SINK_COUNT) }, + /* AUO PSR2 panels need some more DP synchronization latency */ + { OUI(0x00, 0x1c, 0xf8), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_SYNCHRONIZATION_LATENCY) }, + }; #undef OUI diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 16e9ff47d519..1023b08ad093 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -296,6 +296,12 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) dev_priv->psr.sink_sync_latency = intel_dp_get_sink_sync_latency(intel_dp); + if (drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_SYNCHRONIZATION_LATENCY)) { + DRM_DEBUG_KMS("AUO PSR2 panel need more synchronization latency\n"); + if (dev_priv->psr.sink_sync_latency == 0) + dev_priv->psr.sink_sync_latency = 8; + } + dev_priv->psr.dp = intel_dp; if (INTEL_GEN(dev_priv) >= 9 && diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 8f8f3632e697..6018b79f2d61 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1522,6 +1522,15 @@ enum drm_dp_quirk { * The driver should ignore SINK_COUNT during detection. */ DP_DPCD_QUIRK_NO_SINK_COUNT, + /** +* @DP_DPCD_QUIRK_SYNCHRONIZATION_LATENCY +* +* The Helios AUO PSR2 panel requires more number of frames on PSR exit, +* to synchronize to the Source device-provided timing. Currently DPCD +* 0x2009 offset in TCON has the value of 0. Increasing this value to 8 +* till this gets fixed in TCON of the panel. +*/ + DP_DPCD_QUIRK_SYNCHRONIZATION_LATENCY, }; /** -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] [v2] drm/i915: Do not mark as sink as not reliable to PSR runtime errors
In case of CRC mismatch, panel generates IRQ_HD and PSR2 gets disabled by i915 driver. Due to this, PSR2 will only be enabled back only if system is rebooted or cold boot. So, in cases of suspend resume stress test and S0ix stress test, when we encounter this CRC issue on a particular iteration, once PSR2 is disabled,it remains disabled throughout all the cycling iterations until the system is rebooted. Keeping this in mind, many times users do not reboot their system and they just keep lid off/on or suspend/resume. In these scenarios in case of CRC issue, panel will become non-PSR2 which will eventually drain out battery. In order to fix this behavior, did not set the "sink_not_reliable" flag to be true, so that intel_psr_compute_config() can pass in case of a normal modeset which will lead to enabling PSR2 again in next iteration of suspend/resume or S0ix cycle(without reboot). Tested this patch and works fine on Gen9 Intel chromebook, PSR2 was enabled back in next iteration, no other sideeffects observed. v2: * Change the commit header indicating fix for PSR runtime erros(Jose, Souza) * Allow sink_not_reliable to be set for other errors except CRC error (Jose, Souza) Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/display/intel_psr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 16e9ff47d519..1037b716c1c0 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1484,7 +1484,9 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp) if (status == DP_PSR_SINK_INTERNAL_ERROR || (error_status & errors)) { intel_psr_disable_locked(intel_dp); - psr->sink_not_reliable = true; + if ((error_status & DP_PSR_RFB_STORAGE_ERROR) || + (error_status & DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR)) + psr->sink_not_reliable = true; } if (status == DP_PSR_SINK_INTERNAL_ERROR && !error_status) -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Enable PSR2 in next iteration of suspend-resume/S0ix cycling
In case of CRC mismatch, panel generates IRQ_HD and PSR2 gets disabled by i915 driver. Due to this, PSR2 will only be enabled back only if system is rebooted or cold boot. So, in cases of suspend resume stress test and S0ix stress test, when we encounter this CRC issue on a particular iteration, once PSR2 is disabled,it remains disabled throughout all the cycling iterations until the system is rebooted. Keeping this in mind, many times users do not reboot their system and they just keep lid off/on or suspend/resume. In these scenarios in case of CRC issue, panel will become non-PSR2 which will eventually drain out battery. In order to fix this behavior, did not set the "sink_not_reliable" flag to be true, so that intel_psr_compute_config() can pass in case of a normal modeset which will lead to enabling PSR2 again in next iteration of suspend/resume or S0ix cycle(without reboot). Tested this patch and works fine on Gen9 Intel chromebook, PSR2 was enabled back in next iteration, no other sideeffects observed. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/display/intel_psr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index c1d133362b76..8465d0fc2214 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1420,10 +1420,9 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp) if (val & ~errors) DRM_ERROR("PSR_ERROR_STATUS unhandled errors %x\n", val & ~errors); - if (val & errors) { + if (val & errors) intel_psr_disable_locked(intel_dp); - psr->sink_not_reliable = true; - } + /* clear status register */ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_ERROR_STATUS, val); exit: -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Fix S0ix/S3 suspend stress issue
During S0ix/S3 suspend stress test on Cometlake chromebook, after few iterations we are seeing failure wrt PSR link CRC Error and stress test stops. This S0ix test is failing only when there is a CRC mismatch. In case of CRC mismatch, panel generates IRQ_HD and whenever there is CRC mismatch, we are disabling PSR2 in driver. By not disabling PSR2 in driver and only by writing 1 to clear sticky bit 0 in DPCD 0x2006 in panel,issue goes away. Completed 2500 S0ix/S3 test cycles on multiple CML chromebooks. As per EDP spec for CRC mismatch, nothing has been mentioned explicitly for Source device, only by writing 1 to clear sticky bit 0 in DPCD 0x2006 in sink is mentioned. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/display/intel_psr.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index b3c7eef53bf3..502e29dbbea9 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1325,15 +1325,11 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp) if (val & DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR) DRM_DEBUG_KMS("PSR VSC SDP uncorrectable error, disabling PSR\n"); if (val & DP_PSR_LINK_CRC_ERROR) - DRM_ERROR("PSR Link CRC error, disabling PSR\n"); + DRM_DEBUG_KMS("PSR Link CRC error, clearing PSR error status DPCD\n"); if (val & ~errors) DRM_ERROR("PSR_ERROR_STATUS unhandled errors %x\n", val & ~errors); - if (val & errors) { - intel_psr_disable_locked(intel_dp); - psr->sink_not_reliable = true; - } /* clear status register */ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_ERROR_STATUS, val); exit: -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Fix corruption lines on the screen on Gen9 chromebooks
On Gen9 chromebooks, we are seeing the screen shows several large blue horizontal stripes over the top. Also, corruption happens when we switch from a chrome browser tab to VT2 mode(by pressing Ctrl+Alt+F2) and then back to chrome tab. As per the display workaround #1200, FBC needs wait for vblank before enabling and before disabling FBC. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/display/intel_fbc.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 16ed44bfd734..dd224b82bf02 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1097,6 +1097,8 @@ void intel_fbc_enable(struct intel_crtc *crtc, if (fbc->crtc == crtc) { WARN_ON(!crtc_state->enable_fbc); WARN_ON(fbc->active); + if (IS_GEN(dev_priv, 9)) + intel_wait_for_vblank(dev_priv, crtc->pipe); } goto out; } @@ -1137,8 +1139,11 @@ void intel_fbc_disable(struct intel_crtc *crtc) return; mutex_lock(&fbc->lock); - if (fbc->crtc == crtc) + if (fbc->crtc == crtc) { __intel_fbc_disable(dev_priv); + if (IS_GEN(dev_priv, 9)) + intel_wait_for_vblank(dev_priv, crtc->pipe); + } mutex_unlock(&fbc->lock); } -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Fix corruption lines on the screen on Gen9 chromebooks
On Gen9 chromebooks, we are seeing the screen shows several large blue horizontal stripes over the top. Also, corruption happens when we switch from a chrome browser tab to VT2 mode(by pressing Ctrl+Alt+F2) and then back to chrome tab. As per the display workaround #1200, FBC needs wait for vblank before enabling and before disabling FBC. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/display/intel_fbc.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 16ed44bfd734..71f2568ea5a3 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1097,6 +1097,8 @@ void intel_fbc_enable(struct intel_crtc *crtc, if (fbc->crtc == crtc) { WARN_ON(!crtc_state->enable_fbc); WARN_ON(fbc->active); + if (IS_GEN9(dev_priv)) + intel_wait_for_vblank(dev_priv, crtc->pipe); } goto out; } @@ -1137,8 +1139,11 @@ void intel_fbc_disable(struct intel_crtc *crtc) return; mutex_lock(&fbc->lock); - if (fbc->crtc == crtc) + if (fbc->crtc == crtc) { __intel_fbc_disable(dev_priv); + if (IS_GEN9(dev_priv)) + intel_wait_for_vblank(dev_priv, crtc->pipe); + } mutex_unlock(&fbc->lock); } -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Fix corruption lines on the screen on Gen9 chromebooks
On Gen9 chromebooks, we are seeing the screen shows several large blue horizontal stripes over the top. Also, corruption happens when we switch from a chrome browser tab to VT2 mode(by pressing Ctrl+Alt+F2) and then back to chrome tab. As per the display workaround #1200, FBC needs wait for vblank before enabling and before disabling FBC. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/display/intel_fbc.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 16ed44bfd734..71f2568ea5a3 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1097,6 +1097,8 @@ void intel_fbc_enable(struct intel_crtc *crtc, if (fbc->crtc == crtc) { WARN_ON(!crtc_state->enable_fbc); WARN_ON(fbc->active); + if (IS_GEN9(dev_priv)) + intel_wait_for_vblank(dev_priv, crtc->pipe); } goto out; } @@ -1137,8 +1139,11 @@ void intel_fbc_disable(struct intel_crtc *crtc) return; mutex_lock(&fbc->lock); - if (fbc->crtc == crtc) + if (fbc->crtc == crtc) { __intel_fbc_disable(dev_priv); + if (IS_GEN9(dev_priv)) + intel_wait_for_vblank(dev_priv, crtc->pipe); + } mutex_unlock(&fbc->lock); } -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/audio: Fix audio detection issue on GLK
On Geminilake, sometimes audio card is not getting detected after reboot. This is a spurious issue happening on Geminilake. HW codec and HD audio controller link was going out of sync for which there was a fix in i915 driver but was not getting invoked for GLK. Extending this fix to GLK as well. Tested by Du,Wenkai on GLK board. Bspec: 21829 v2: Instead of checking GEN9_BC, BXT and GLK macros, use IS_GEN9 macro (Jani N) Signed-off-by: Gaurav K Singh Reviewed-by: Abhay Kumar --- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 656f6c931341..3ea566f99450 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, struct drm_i915_private *dev_priv = kdev_to_i915(kdev); u32 tmp; - if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv)) + if (!IS_GEN9(dev_priv)) return; i915_audio_component_get_power(kdev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/audio: Fix audio detection issue on GLK
On Geminilake, sometimes audio card is not getting detected after reboot. This is a spurious issue happening on Geminilake. HW codec and HD audio controller link was going out of sync for which there was a fix in i915 driver but was not getting invoked for GLK. Extending this fix to GLK as well. Tested by Du,Wenkai on GLK board. Bspec: 21829 v2: Instead of checking GEN9_BC, BXT and GLK macros, use IS_GEN9 macro Signed-off-by: Gaurav K Singh Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 656f6c931341..3ea566f99450 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, struct drm_i915_private *dev_priv = kdev_to_i915(kdev); u32 tmp; - if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv)) + if (!IS_GEN9(dev_priv)) return; i915_audio_component_get_power(kdev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/audio: Fix audio detection issue on GLK
On Geminilake, sometimes audio card is not getting detected after reboot. This is a spurious issue happening on Geminilake. HW codec and HD audio controller link was going out of sync for which there was a fix in i915 driver but was not getting invoked for GLK. Extending this fix to GLK as well. Tested by Du,Wenkai on GLK board. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 656f6c931341..73b1e0b96f88 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -729,7 +729,8 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, struct drm_i915_private *dev_priv = kdev_to_i915(kdev); u32 tmp; - if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv)) + if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv) && + !IS_GEMINILAKE(dev_priv)) return; i915_audio_component_get_power(kdev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/audio: Fix audio issue on BXT
On Apollolake, with stress test warm reboot, audio card was not getting enumerated after reboot. This was a spurious issue happening on Apollolake. HW codec and HD audio controller link was going out of sync for which there was a fix in i915 driver but was not getting invoked for BXT. Extending this fix to BXT as well. Tested on apollolake chromebook by stress test warm reboot with 2500 iterations. Bspec: 21829 Signed-off-by: Gaurav K Singh Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 709d6ca68074..656f6c931341 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, struct drm_i915_private *dev_priv = kdev_to_i915(kdev); u32 tmp; - if (!IS_GEN9_BC(dev_priv)) + if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv)) return; i915_audio_component_get_power(kdev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Fix audio issue on BXT
On Apollolake, with stress test warm reboot, audio card was not getting enumerated after reboot. This was a spurious issue happening on Apollolake. HW codec and HD audio controller link was going out of sync for which there was a fix in i915 driver but was not getting invoked for BXT. Extending this fix to BXT as well. Tested on apollolake chromebook by stress test warm reboot with 2500 iterations. Bspec: 21829 Signed-off-by: Gaurav K Singh Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 709d6ca68074..656f6c931341 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, struct drm_i915_private *dev_priv = kdev_to_i915(kdev); u32 tmp; - if (!IS_GEN9_BC(dev_priv)) + if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv)) return; i915_audio_component_get_power(kdev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm: i915: Fix audio issue on BXT
On Apollolake, with stress test warm reboot, audio card was not getting enumerated after reboot. This was a spurious issue happening on Apollolake. HW codec and HD audio controller link was going out of sync for which there was a fix in i915 driver but was not getting invoked for BXT. Extending this fix to BXT as well. Tested on apollolake chromebook by stress test warm reboot with 2500 iterations. Bspec: 21829 Signed-off-by: Gaurav K Singh Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 709d6ca68074..656f6c931341 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, struct drm_i915_private *dev_priv = kdev_to_i915(kdev); u32 tmp; - if (!IS_GEN9_BC(dev_priv)) + if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv)) return; i915_audio_component_get_power(kdev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm: i915: Fix audio issue on BXT
On Apollolake, with stress test warm reboot, audio card was not getting enumerated after reboot. This was a spurious issue happening on Apollolake. HW codec and HD audio controller link was going out of sync for which there was a fix in i915 driver but was not getting invoked for BXT. Extending this fix to BXT as well. Bspec: 21829 Tested on apollolake chromebook by stress test warm reboot with 2500 iterations. v2: * Mention Bspec Index in commit message(Dhinakaran Pandiyan) Signed-off-by: Gaurav K Singh Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 709d6ca68074..656f6c931341 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, struct drm_i915_private *dev_priv = kdev_to_i915(kdev); u32 tmp; - if (!IS_GEN9_BC(dev_priv)) + if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv)) return; i915_audio_component_get_power(kdev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/10] drm/i915: Encoder enable/disable seq wrt DSC
1. Send PPS and enable DSC after decompression is enabled in DP sink 2. Enable DSC in Source before enabling pipe 3. Disabling compression after disabling pipe, but before disabling port Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_drv.h | 5 + drivers/gpu/drm/i915/intel_display.c | 20 2 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4073c98a267f..0e0034f7ad67 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -4318,6 +4318,11 @@ extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable); extern void intel_dp_compute_dsc_parameters(struct intel_dp *dp); +extern void intel_dsc_enable(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state); +extern void intel_dsc_disable(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state); + int i915_reg_read_ioctl(struct drm_device *dev, void *data, struct drm_file *file); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3c479e3fd553..812dcf8a15c4 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5226,6 +5226,11 @@ static void intel_encoders_pre_enable(struct drm_crtc *crtc, if (encoder->pre_enable) encoder->pre_enable(encoder, crtc_state, conn_state); + /* +* Send PPS and Enable DSC after decompression is +* enabled in DP sink +*/ + intel_dsc_enable(encoder, crtc_state); } } @@ -5623,7 +5628,10 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state, struct drm_crtc *crtc = old_crtc_state->base.crtc; struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_connector_state *conn_state; + struct drm_connector *conn; enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; + int i; intel_encoders_disable(crtc, old_crtc_state, old_state); @@ -5640,6 +5648,18 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state, if (!transcoder_is_dsi(cpu_transcoder)) intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); + /* Invoke intel_dsc_disable */ + for_each_new_connector_in_state(old_state, conn, conn_state, i) { + struct intel_encoder *encoder = + to_intel_encoder(conn_state->best_encoder); + + if (conn_state->crtc != crtc) + continue; + + /* Disable DSC if supported by platform and panel */ + intel_dsc_disable(encoder, old_crtc_state); + } + if (INTEL_GEN(dev_priv) >= 9) skylake_scaler_disable(intel_crtc); else -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 09/10] drm: i915: Disable VDSC from Source
1. Disable Left/right VDSC branch in DSS Ctrl reg depending on the number of VDSC engines being used 2. Disable joiner in DSS Ctrl reg Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_vdsc.c | 51 +++ 2 files changed, 54 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7d0574cf6e94..bd2c0832a4dc 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9676,11 +9676,14 @@ enum skl_power_gate { #define DSS_CONTROL1 _MMIO(0x67400) #define JOINER_ENABLE (1 << 30) +#define JOINER_DISABLE (0 << 30) #define SPLITTER_ENABLE(1 << 31) #define DSS_CONTROL2 _MMIO(0x67404) #define LEFT_BRANCH_VDSC_ENABLE(1 << 31) +#define LEFT_BRANCH_VDSC_DISABLE (0 << 31) #define RIGHT_BRANCH_VDSC_ENABLE (1 << 15) +#define RIGHT_BRANCH_VDSC_DISABLE (0 << 15) #define PIPE_DSS_CTL1_PB _MMIO(0x78200) #define PIPE_DSS_CTL2_PB _MMIO(0x78204) diff --git a/drivers/gpu/drm/i915/intel_vdsc.c b/drivers/gpu/drm/i915/intel_vdsc.c index 16f84044f47b..86b2d17df3a8 100644 --- a/drivers/gpu/drm/i915/intel_vdsc.c +++ b/drivers/gpu/drm/i915/intel_vdsc.c @@ -1190,3 +1190,54 @@ void intel_dsc_enable(struct intel_encoder *encoder, I915_WRITE(dsc_regs.dss_ctrl2_reg, dss_ctrl2_value); } } + +void intel_dsc_disable(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsc_regs dsc_regs; + struct drm_crtc *crtc = pipe_config->base.crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + int type = encoder->type; + unsigned int dss_ctrl1_value = 0; + unsigned int dss_ctrl2_value = 0; + + if ((INTEL_GEN(dev_priv) < 9) || + !intel_dp->compr_params.compression_support) + return; + + if (type == INTEL_OUTPUT_EDP) { + dsc_regs.dss_ctrl1_reg = DSS_CONTROL1; + dsc_regs.dss_ctrl2_reg = DSS_CONTROL2; + } else if (type == INTEL_OUTPUT_DP) { + switch (pipe) { + case PIPE_A: + dsc_regs.dss_ctrl1_reg = PIPE_DSS_CTL1_PB; + dsc_regs.dss_ctrl2_reg = PIPE_DSS_CTL2_PB; + break; + case PIPE_B: + dsc_regs.dss_ctrl1_reg = PIPE_DSS_CTL1_PC; + dsc_regs.dss_ctrl2_reg = PIPE_DSS_CTL2_PC; + break; + default: + return; + } + } else { + DRM_ERROR("Func:%s Unsupported port:%d\n", __func__, type); + } + + dss_ctrl1_value = I915_READ(dsc_regs.dss_ctrl1_reg); + dss_ctrl2_value = I915_READ(dsc_regs.dss_ctrl2_reg); + + if ((dss_ctrl2_value & LEFT_BRANCH_VDSC_ENABLE) || + (dss_ctrl2_value & RIGHT_BRANCH_VDSC_ENABLE)) + dss_ctrl2_value &= LEFT_BRANCH_VDSC_DISABLE & + RIGHT_BRANCH_VDSC_DISABLE; + I915_WRITE(dsc_regs.dss_ctrl2_reg, dss_ctrl2_value); + + if (dss_ctrl1_value & JOINER_ENABLE) + dss_ctrl1_value &= JOINER_DISABLE; + I915_WRITE(dsc_regs.dss_ctrl1_reg, dss_ctrl1_value); +} -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/10] drm: i915: Enable VDSC in Source
Below are the things being taken care as part of this patch: 1. Program Picture Parameter Set(PPS) MMIO regs and Rate Control params regs in DSC Controller. Depending on the no of VDSC engines, program the above regs. 2. Populate PPS Secondary Data Packet for Sink device 3. Data is send only to Sink device once DIP PPS is enabled in DIP ctrl reg 4. DSC is only enabled only after Gen9 onwards 5. DSC capability should be supported from Sink side before programming the source side. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_vdsc.c | 425 +- 1 file changed, 424 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_vdsc.c b/drivers/gpu/drm/i915/intel_vdsc.c index 536f417624cb..16f84044f47b 100644 --- a/drivers/gpu/drm/i915/intel_vdsc.c +++ b/drivers/gpu/drm/i915/intel_vdsc.c @@ -596,7 +596,8 @@ void populate_pps_sdp_for_sink(struct intel_encoder *encoder, pps_params->bpp_high = (unsigned short)(vdsc_cfg->bits_per_pixel & 0xFF); - /* The PPS structure is stored as per our hardware registers which + /* +* The PPS structure is stored as per our hardware registers which * are in little endian. When a value is assigned to a variable, * Intel systems stores data in little endian. * For e.g UINT16 a = 0x1234; @@ -767,3 +768,425 @@ void populate_pps_sdp_for_sink(struct intel_encoder *encoder, pps_params->rc_range_parameter14 = SWAP_TWO_BYTES(rc_range_parameters[14]); } + +void intel_dsc_regs_init(struct intel_encoder *encoder, + struct intel_dsc_regs *dsc_regs, int dsc_type) +{ + switch (dsc_type) { + case DSC_A: + dsc_regs->dsc_picture_params0 = DSCA_PICTURE_PARAMETER_SET_0; + dsc_regs->dsc_picture_params1 = DSCA_PICTURE_PARAMETER_SET_1; + dsc_regs->dsc_picture_params2 = DSCA_PICTURE_PARAMETER_SET_2; + dsc_regs->dsc_picture_params3 = DSCA_PICTURE_PARAMETER_SET_3; + dsc_regs->dsc_picture_params4 = DSCA_PICTURE_PARAMETER_SET_4; + dsc_regs->dsc_picture_params5 = DSCA_PICTURE_PARAMETER_SET_5; + dsc_regs->dsc_picture_params6 = DSCA_PICTURE_PARAMETER_SET_6; + dsc_regs->dsc_picture_params7 = DSCA_PICTURE_PARAMETER_SET_7; + dsc_regs->dsc_picture_params8 = DSCA_PICTURE_PARAMETER_SET_8; + dsc_regs->dsc_picture_params9 = DSCA_PICTURE_PARAMETER_SET_9; + dsc_regs->dsc_picture_params10 = DSCA_PICTURE_PARAMETER_SET_10; + dsc_regs->dsc_picture_params16 = DSCA_PICTURE_PARAMETER_SET_16; + dsc_regs->dsc_rc_buff_thresh0_0 = DSCA_RC_BUF_THRESH_0_0; + dsc_regs->dsc_rc_buff_thresh0_1 = DSCA_RC_BUF_THRESH_0_1; + dsc_regs->dsc_rc_buff_thresh1_0 = DSCA_RC_BUF_THRESH_1_0; + dsc_regs->dsc_rc_buff_thresh1_1 = DSCA_RC_BUF_THRESH_1_1; + dsc_regs->dsc_rc_range0_0 = DSCA_RC_RANGE_PARAMETERS_0_0; + dsc_regs->dsc_rc_range0_1 = DSCA_RC_RANGE_PARAMETERS_0_1; + dsc_regs->dsc_rc_range1_0 = DSCA_RC_RANGE_PARAMETERS_1_0; + dsc_regs->dsc_rc_range1_1 = DSCA_RC_RANGE_PARAMETERS_1_1; + dsc_regs->dsc_rc_range2_0 = DSCA_RC_RANGE_PARAMETERS_2_0; + dsc_regs->dsc_rc_range2_1 = DSCA_RC_RANGE_PARAMETERS_2_1; + dsc_regs->dsc_rc_range3_0 = DSCA_RC_RANGE_PARAMETERS_3_0; + dsc_regs->dsc_rc_range3_1 = DSCA_RC_RANGE_PARAMETERS_3_1; + break; + case DSC_C: + dsc_regs->dsc_picture_params0 = DSCC_PICTURE_PARAMETER_SET_0; + dsc_regs->dsc_picture_params1 = DSCC_PICTURE_PARAMETER_SET_1; + dsc_regs->dsc_picture_params2 = DSCC_PICTURE_PARAMETER_SET_2; + dsc_regs->dsc_picture_params3 = DSCC_PICTURE_PARAMETER_SET_3; + dsc_regs->dsc_picture_params4 = DSCC_PICTURE_PARAMETER_SET_4; + dsc_regs->dsc_picture_params5 = DSCC_PICTURE_PARAMETER_SET_5; + dsc_regs->dsc_picture_params6 = DSCC_PICTURE_PARAMETER_SET_6; + dsc_regs->dsc_picture_params7 = DSCC_PICTURE_PARAMETER_SET_7; + dsc_regs->dsc_picture_params8 = DSCC_PICTURE_PARAMETER_SET_8; + dsc_regs->dsc_picture_params9 = DSCC_PICTURE_PARAMETER_SET_9; + dsc_regs->dsc_picture_params10 = DSCC_PICTURE_PARAMETER_SET_10; + dsc_regs->dsc_picture_params16 = DSCC_PICTURE_PARAMETER_SET_16; + dsc_regs->dsc_rc_buff_thresh0_0 = DSCC_RC_BUF_THRESH_0_0; + dsc_regs->dsc_rc_buff_thresh0_1 = DSCC_RC_BUF_THRESH_0_1; + dsc_regs->dsc_rc_buff_thresh1_0 = DSCC_RC_B
[Intel-gfx] [PATCH 01/10] drm: i915: Defining Compression Capabilities
For Vesa Display Stream compression, defining structures for compression capabilities to be stored in encoder. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_drv.h | 125 +++ drivers/gpu/drm/i915/intel_drv.h | 62 +++ include/drm/drm_dp_helper.h | 1 + 3 files changed, 188 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0d8cb74e7d02..4b1c323c0925 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -780,6 +780,131 @@ struct i915_psr { void (*setup_vsc)(struct intel_dp *, const struct intel_crtc_state *); }; +/* DSC Configuration structure */ +#define NUM_BUF_RANGES 15 + +/* Configuration for a single Rate Control model range */ +struct rc_range_parameters { + /* Min Quantization Parameters allowed for this range */ + unsigned long range_min_qp; + /* Max Quantization Parameters allowed for this range */ + unsigned long range_max_qp; + /* Bits/group offset to apply to target for this group */ + unsigned long range_bpg_offset; +}; + +struct vdsc_config { + /* Bits / component for previous reconstructed line buffer */ + unsigned long line_buf_depth; + /* +* Rate control buffer size (in bits); not in PPS, +* used only in C model for checking overflow +*/ + unsigned long rc_bits; + /* Bits per component to code (must be 8, 10, or 12) */ + unsigned long bits_per_component; + /* +* Flag indicating to do RGB - YCoCg conversion +* and back (should be 1 for RGB input) +*/ + bool convert_rgb; + unsigned long slice_count; + /* Slice Width */ + unsigned long slice_width; + /* Slice Height */ + unsigned long slice_height; + /* +* 4:2:2 enable mode (from PPS, 4:2:2 conversion happens +* outside of DSC encode/decode algorithm) +*/ + bool enable422; + /* Picture Width */ + unsigned long pic_width; + /* Picture Height */ + unsigned long pic_height; + /* Offset to bits/group used by RC to determine QP adjustment */ + unsigned long rc_tgt_offset_high; + /* Offset to bits/group used by RC to determine QP adjustment */ + unsigned long rc_tgt_offset_low; + /* Bits/pixel target << 4 (ie., 4 fractional bits) */ + unsigned long bits_per_pixel; + /* +* Factor to determine if an edge is present based +* on the bits produced +*/ + unsigned long rc_edge_factor; + /* Slow down incrementing once the range reaches this value */ + unsigned long rc_quant_incr_limit1; + /* Slow down incrementing once the range reaches this value */ + unsigned long rc_quant_incr_limit0; + /* Number of pixels to delay the initial transmission */ + unsigned long initial_xmit_delay; + /* Number of pixels to delay the VLD on the decoder,not including SSM */ + unsigned long initial_dec_delay; + /* Block prediction range (in pixels) */ + bool block_pred_enable; + /* Bits/group offset to use for first line of the slice */ + unsigned long first_line_bpg_Ofs; + /* Value to use for RC model offset at slice start */ + unsigned long initial_offset; + /* X position in the picture of top-left corner of slice */ + unsigned long x_start; + /* Y position in the picture of top-left corner of slice */ + unsigned long y_start; + /* Thresholds defining each of the buffer ranges */ + unsigned long rc_buf_thresh[NUM_BUF_RANGES - 1]; + /* Parameters for each of the RC ranges */ + struct rc_range_parameters rc_range_params[NUM_BUF_RANGES]; + /* Total size of RC model */ + unsigned long rc_model_size; + /* Minimum QP where flatness information is sent */ + unsigned long flatness_minQp; + /* Maximum QP where flatness information is sent */ + unsigned long flatness_maxQp; + /* +* MAX-MIN for all components is required to +* be <= this value for flatness to be used +*/ + unsigned long flatness_det_thresh; + /* Initial value for scale factor */ + unsigned long initial_scale_value; + /* Decrement scale factor every scale_decrement_interval groups */ + unsigned long scale_decrement_interval; + /* Increment scale factor every scale_increment_interval groups */ + unsigned long scale_increment_interval; + /* Non-first line BPG offset to use */ + unsigned long nfl_bpg_offset; + /* BPG offset used to enforce slice bit */ + unsigned long slice_bpg_offset; + /* Final RC linear transformation offset value */ + unsigned long final_offset; + /* Enable on-off VBR (ie., disable stuffing bits) */ + bool vbr_enable; + /* Mux word size (in
[Intel-gfx] [PATCH 03/10] drm: i915: Enable/Disable DSC in DP sink
Below changes are being taken care in this patch: 1. If there is no DSC support from DPCD offset 0x60, just return 2. If DSC support is there, disable decompression in DPCD offset 0x160 during DP encoder disable sequence. 3. If DSC support is there, enable decompression in DPCD offset 0x160 during DP encoder enable sequence before sending PPS. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_ddi.c | 4 drivers/gpu/drm/i915/intel_dp.c | 14 ++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ include/drm/drm_dp_helper.h | 2 ++ 4 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index db92a2691206..693061444d4b 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2177,6 +2177,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, intel_ddi_init_dp_buf_reg(encoder); if (!is_mst) intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); + /* Enable Decompression in DP Sink at DPCD offset 0x00160 offset */ + intel_dp_sink_set_decompression_state(intel_dp, DECOMPRESSION_ENABLE); intel_dp_start_link_train(intel_dp); if (port != PORT_A || INTEL_GEN(dev_priv) >= 9) intel_dp_stop_link_train(intel_dp); @@ -2480,6 +2482,8 @@ static void intel_disable_ddi_dp(struct intel_encoder *encoder, intel_edp_drrs_disable(intel_dp, old_crtc_state); intel_psr_disable(intel_dp, old_crtc_state); intel_edp_backlight_off(old_conn_state); + /* Disable Decompression in DP Sink at DPCD offset 0x00160 offset */ + intel_dp_sink_set_decompression_state(intel_dp, DECOMPRESSION_DISABLE); } static void intel_disable_ddi_hdmi(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f494a851ff89..c3b48b214e8f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2538,6 +2538,20 @@ static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp) intel_dp->downstream_ports[0] & DP_DS_PORT_HPD; } +void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, + int decomp_state) +{ + int ret; + + if (!intel_dp->compr_params.compression_support) + return; + + ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_DSC_ENABLE, decomp_state); + if (ret < 0) + DRM_ERROR("DCPD write fail offset:0x%x for decompr state:%d\n", + DP_DSC_ENABLE, decomp_state); +} + /* If the sink supports it, try to set the power state appropriately */ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6e1b907990bf..8d8d4486773a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1595,6 +1595,8 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, void intel_dp_start_link_train(struct intel_dp *intel_dp); void intel_dp_stop_link_train(struct intel_dp *intel_dp); void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); +void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, + int decomp_state); void intel_dp_encoder_reset(struct drm_encoder *encoder); void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); void intel_dp_encoder_destroy(struct drm_encoder *encoder); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 05f811c50d28..f3f44847c86e 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -445,6 +445,8 @@ # define DP_AUX_FRAME_SYNC_VALID (1 << 0) #define DP_DSC_ENABLE 0x160 /* DP 1.4 */ +#define DECOMPRESSION_ENABLE (1 << 0) +#define DECOMPRESSION_DISABLE 0 #define DP_PSR_EN_CFG 0x170 /* XXX 1.2? */ # define DP_PSR_ENABLE (1 << 0) -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/10] drm: i915: Define VDSC regs and DSC params
Defining all mmio regs from Gen9 onwards to be used for VDSC programming. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_drv.h | 58 ++ drivers/gpu/drm/i915/i915_reg.h | 448 2 files changed, 506 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 760b97ec89ff..4073c98a267f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1169,8 +1169,66 @@ struct picture_parameters_set { unsigned long pps_long_124_reserved; }; +/* Secondary Data Packet Header */ +struct sdp_header { + /* SDP ID */ + unsigned char sdp_id; + /* SDP Type */ + unsigned char sdp_type; + union { + unsigned char sdp_byte1; + struct { + unsigned char revision_no :5; + unsigned char reserved1 :3; + }; + }; + + union { + unsigned char sdp_byte2; + struct { + unsigned char num_of_valid_data_bytes : 5; + unsigned char reserved2 : 3; + }; + }; +}; + +union pps_sdp { + struct { + /* VS header data */ + struct sdp_header secondary_data_packet_header; + /* PPS Payload */ + struct picture_parameters_set pps_payload; + }; +}; + +/* There are two instances of VDSC engines */ +#define DSC0 0 +#define DSC1 1 + +/* Dislay Compression Units */ +enum dsc_types { + /* DSC_0 engine for eDP/MIPIDSI */ + DSC_A = 0, + /* DSC_1 engine for eDP/MIPI DSI */ + DSC_C = 1, + /* Applicable from Gen11.5 */ + PIPEA_DSC_0 = 2, + PIPEA_DSC_1 = 3, + PIPEB_DSC_0 = 4, + PIPEB_DSC_1 = 5, + PIPEC_DSC_0 = 6, + PIPEC_DSC_1 = 7, + PIPED_DSC_0 = 8, + PIPED_DSC_1 = 9, + MAX_DSC_TYPES, + DSC_UNDEFINED = 127 +}; + /* DSC Configuration structure */ #define NUM_BUF_RANGES 15 +/* Size in Bytes */ +#define SDP_HEADER_SIZE4 +#define PPS_PAYLOAD_SIZE 128 /* Configuration for a single Rate Control model range */ struct rc_range_parameters { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0fc24ab3a8ca..7d0574cf6e94 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9672,4 +9672,452 @@ enum skl_power_gate { _ICL_PHY_MISC_B) #define ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN (1 << 23) +/* VDSC regs */ + +#define DSS_CONTROL1 _MMIO(0x67400) +#define JOINER_ENABLE (1 << 30) +#define SPLITTER_ENABLE(1 << 31) + +#define DSS_CONTROL2 _MMIO(0x67404) +#define LEFT_BRANCH_VDSC_ENABLE(1 << 31) +#define RIGHT_BRANCH_VDSC_ENABLE (1 << 15) + +#define PIPE_DSS_CTL1_PB _MMIO(0x78200) +#define PIPE_DSS_CTL2_PB _MMIO(0x78204) +#define PIPE_DSS_CTL1_PC _MMIO(0x78400) +#define PIPE_DSS_CTL2_PC _MMIO(0x78404) + +#define DSCA_PICTURE_PARAMETER_SET_0 _MMIO(0x6B200) +#define DSCA_PICTURE_PARAMETER_SET_1 _MMIO(0x6B204) +#define DSCA_PICTURE_PARAMETER_SET_2 _MMIO(0x6B208) +#define DSCA_PICTURE_PARAMETER_SET_3 _MMIO(0x6B20C) +#define DSCA_PICTURE_PARAMETER_SET_4 _MMIO(0x6B210) +#define DSCA_PICTURE_PARAMETER_SET_5 _MMIO(0x6B214) +#define DSCA_PICTURE_PARAMETER_SET_6 _MMIO(0x6B218) +#define DSCA_PICTURE_PARAMETER_SET_7 _MMIO(0x6B21C) +#define DSCA_PICTURE_PARAMETER_SET_8 _MMIO(0x6B220) +#define DSCA_PICTURE_PARAMETER_SET_9 _MMIO(0x6B224) +#define DSCA_PICTURE_PARAMETER_SET_10 _MMIO(0x6B228) +#define DSCA_PICTURE_PARAMETER_SET_11 _MMIO(0x6B22C) +#define DSCA_PICTURE_PARAMETER_SET_12 _MMIO(0x6B260) +#define DSCA_PICTURE_PARAMETER_SET_13 _MMIO(0x6B264) +#define DSCA_PICTURE_PARAMETER_SET_14 _MMIO(0x6B268) +#define DSCA_PICTURE_PARAMETER_SET_15 _MMIO(0x6B26C) +#define DSCA_PICTURE_PARAMETER_SET_16 _MMIO(0x6B270) + +#define DSCC_PICTURE_PARAMETER_SET_0 _MMIO(0x6BA00) +#define DSCC_PICTURE_PARAMETER_SET_1 _MMIO(0x6BA04) +#define DSCC_PICTURE_PARAMETER_SET_2 _MMIO(0x6BA08) +#define DSCC_PICTURE_PARAMETER_SET_3 _MMIO(0x6BA0C) +#define DSCC_PICTURE_PARAMETER_SET_4 _MMIO(0x6BA10) +#define DSCC_PICTURE_PARAMETER_SET_5 _MMIO(0x6BA14) +#define DSCC_PICTURE_PARAMETER_SET_6 _MMIO(0x6BA18) +#define DSCC_PICTURE_PARAMETER_SET_7 _MMIO(0x6BA1C) +#define DSCC_PICTURE_PARAMETER_SET_8 _MMIO(0x6BA20) +#define DSCC_PICTURE_PARAMETER
[Intel-gfx] [PATCH 06/10] drm/i915: Populate PPS Secondary Data Pkt for Sink
Vesa Display Stream Compression defines Picture Parameter Set(PPS), which encoders must communicate to decoders. PPS is encapsulated in 128 bytes(PS0 through PS127). The PPS contains parameters that the decoder needs to correctly decode pictures. Correct decoding requires that an identical PPS be used at the encoder(@Source) and decoder(@Sink). The PPS is not considered to be part of any picture or slice budget within the DSC coding algorithm. This patch populates PPS parameters that needs to be transmitted to the Sink device. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_vdsc.c | 207 ++ 1 file changed, 207 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_vdsc.c b/drivers/gpu/drm/i915/intel_vdsc.c index 5eef551f0d09..536f417624cb 100644 --- a/drivers/gpu/drm/i915/intel_vdsc.c +++ b/drivers/gpu/drm/i915/intel_vdsc.c @@ -48,6 +48,9 @@ enum COLUMN_INDEX_BPC { MAX_COLUMN_INDEX }; +#define SWAP_TWO_BYTES(x) (unsigned short)(((x >> 8) & 0xFF) | \ + ((x << 8) & 0xFF00)) + #define TWOS_COMPLEMENT(x) (unsigned char)((~(x) + 1) & 0x3F) /* From DSC_v1.11 spec, rc_parameter_Set syntax element typically constant */ @@ -560,3 +563,207 @@ void intel_dp_compute_dsc_parameters(struct intel_dp *intel_dp) intel_compute_rc_parameters(intel_dp); } + +void populate_pps_sdp_for_sink(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + struct picture_parameters_set *pps_params) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct vdsc_config *vdsc_cfg = &(intel_dp->compr_params.dsc_cfg); + unsigned long rc_range_parameters[NUM_BUF_RANGES]; + unsigned char i = 0; + + /* PPS0 */ + pps_params->major = (unsigned char)vdsc_cfg->dsc_version_major; + pps_params->minor = (unsigned char)vdsc_cfg->dsc_version_minor; + + /* PPS1, PPS2 */ + pps_params->picture_params_set_identifier = 0; + + /* PPS3 */ + pps_params->line_buffer_depth = (unsigned char)vdsc_cfg->line_buf_depth; + pps_params->bits_per_component = + (unsigned char)vdsc_cfg->bits_per_component; + + /* PPS4,5 */ + pps_params->block_prediction_enable = + (unsigned short)vdsc_cfg->block_pred_enable; + pps_params->convert_RGB = (unsigned short)vdsc_cfg->convert_rgb; + pps_params->enable422 = (unsigned short)vdsc_cfg->enable422; + pps_params->vbr_mode = (unsigned short)vdsc_cfg->vbr_enable; + pps_params->bpp_low = (unsigned short)( + (vdsc_cfg->bits_per_pixel >> 8) & 0x3); + pps_params->bpp_high = (unsigned short)(vdsc_cfg->bits_per_pixel & + 0xFF); + + /* The PPS structure is stored as per our hardware registers which +* are in little endian. When a value is assigned to a variable, +* Intel systems stores data in little endian. +* For e.g UINT16 a = 0x1234; +* 0x34 is stored at lower address followed by 0x12. +* Though, PPS packet to the panel must have big endian format for +* data spanning 2 bytes. According to that logic, swap the +* fields of the PPS packets that span more than one byte. +*/ + + /* PPS6,7 */ + pps_params->picture_height = SWAP_TWO_BYTES(vdsc_cfg->pic_height); + + /* PPS8,9 */ + pps_params->picture_width = SWAP_TWO_BYTES(vdsc_cfg->pic_width); + + /* PPS10,11 */ + pps_params->slice_height = SWAP_TWO_BYTES(vdsc_cfg->slice_height); + + /* PPS12,13 */ + pps_params->slice_width = SWAP_TWO_BYTES(vdsc_cfg->slice_width); + + /* PPS14,15 */ + pps_params->chunk_size = SWAP_TWO_BYTES(vdsc_cfg->chunk_size); + + /* PPS15,16 */ + pps_params->transmission_delay_low = (unsigned short) + ((vdsc_cfg->initial_xmit_delay >> 8) & + 0x3); //[9:8] + pps_params->transmission_delay_high = (unsigned short) + (vdsc_cfg->initial_xmit_delay & 0xFF); + + /* PPS18,19 */ + pps_params->initial_decode_delay = + SWAP_TWO_BYTES(vdsc_cfg->initial_dec_delay); + + /* PPS20,21 */ + pps_params->initial_scale = + (unsigned short)vdsc_cfg->initial_scale_value; + + /* PPS22,23 */ + pps_params->scale_increment_interval = + SWAP_TWO_BYTES(vdsc_cfg->scale_increment_interval); + + /* PPS24,25 */ + pps_params->scale_decrement_low = (
[Intel-gfx] [PATCH 02/10] drm: i915: Get DSC capability from DP sink
Get decompression capabilities from DP sink by doing DPCD reads of different offsets as per eDP/DP specs. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dp.c | 167 1 file changed, 167 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1868f73f730c..f494a851ff89 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5883,6 +5883,149 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, return downclock_mode; } +static void intel_dp_sink_get_dsc_capability(struct intel_dp *intel_dp, + struct dp_sink_dsc_caps *dp_dsc_caps) +{ + u8 rcbuffer_blocksize; + u8 fec_dpcd; + unsigned long line_buffer_bit_depth, sink_support_max_bpp_msb; + + /* VDSC is supported only for eDp v1.4 or higher, DPCD 0x00700 offset */ + if (intel_dp->edp_dpcd[0] < 0x03) + return; + + /* Read DPCD 0x060 to 0x06a */ + if (drm_dp_dpcd_read(&intel_dp->aux, DP_DSC_SUPPORT, intel_dp->dsc_dpcd, +sizeof(intel_dp->dsc_dpcd)) < 0) + return; + + dp_dsc_caps->is_dsc_supported = intel_dp->dsc_dpcd[0] & + DP_DSC_DECOMPRESSION_IS_SUPPORTED; + + if (!dp_dsc_caps->is_dsc_supported) + return; + + drm_dp_dpcd_readb(&intel_dp->aux, 0x090, &fec_dpcd); + intel_dp->fec_dpcd = fec_dpcd; + + /* For DP DSC, FEC support is must */ + if (!(intel_dp->fec_dpcd & 0x1)) + return; + + /* No VDSC support for less than 8 BPC */ + if (intel_dp->dsc_dpcd[0xa] < DP_DSC_8_BPC) + return; + + if (intel_dp->dsc_dpcd[0xa] & DP_DSC_8_BPC) + DRM_INFO("8 Bits per color support\n"); + if (intel_dp->dsc_dpcd[0xa] & DP_DSC_10_BPC) + DRM_INFO("10 Bits per color support\n"); + if (intel_dp->dsc_dpcd[0xa] & DP_DSC_12_BPC) + DRM_INFO("12 Bits per color support\n"); + + dp_dsc_caps->dsc_major_ver = intel_dp->dsc_dpcd[1] & DP_DSC_MAJOR_MASK; + dp_dsc_caps->dsc_minor_ver = (intel_dp->dsc_dpcd[1] & + DP_DSC_MINOR_MASK) >> DP_DSC_MINOR_SHIFT; + + rcbuffer_blocksize = intel_dp->dsc_dpcd[2] & 0x3; + + switch (rcbuffer_blocksize) { + case 0: + dp_dsc_caps->rcbuffer_blocksize = 1; + break; + case 1: + dp_dsc_caps->rcbuffer_blocksize = 4; + break; + case 2: + dp_dsc_caps->rcbuffer_blocksize = 16; + break; + case 3: + dp_dsc_caps->rcbuffer_blocksize = 64; + break; + default: + break; + + } + dp_dsc_caps->rcbuffer_size_in_blocks = intel_dp->dsc_dpcd[3] + 1; + + dp_dsc_caps->rcbuffer_size = + dp_dsc_caps->rcbuffer_size_in_blocks * + dp_dsc_caps->rcbuffer_blocksize * 1024 * 8; + + dp_dsc_caps->slice_caps = intel_dp->dsc_dpcd[4]; + line_buffer_bit_depth = intel_dp->dsc_dpcd[5]; + + if (line_buffer_bit_depth == 8) + dp_dsc_caps->line_buffer_bit_depth = intel_dp->dsc_dpcd[5]; + else + dp_dsc_caps->line_buffer_bit_depth = intel_dp->dsc_dpcd[5] + 9; + + dp_dsc_caps->is_block_pred_supported = intel_dp->dsc_dpcd[6] & + DP_DSC_BLK_PREDICTION_IS_SUPPORTED; + + dp_dsc_caps->sink_support_max_bpp = intel_dp->dsc_dpcd[7]; + sink_support_max_bpp_msb = (intel_dp->dsc_dpcd[8] & 0x3) << 8; + dp_dsc_caps->sink_support_max_bpp |= sink_support_max_bpp_msb; + + dp_dsc_caps->color_format_caps = intel_dp->dsc_dpcd[9]; + dp_dsc_caps->color_depth_caps = intel_dp->dsc_dpcd[0xa]; +} + +static void intel_dp_get_compression_data(struct intel_dp *intel_dp, + struct dp_sink_dsc_caps dp_dsc_caps) +{ + if (!dp_dsc_caps.is_dsc_supported) + return; + + intel_dp->compr_params.compression_support = + dp_dsc_caps.is_dsc_supported; + intel_dp->compr_params.dsc_cfg.dsc_version_major = + dp_dsc_caps.dsc_major_ver; + intel_dp->compr_params.dsc_cfg.dsc_version_minor = + dp_dsc_caps.dsc_minor_ver; + + /* By default set bpc to 8 */ + intel_dp->compr_params.dsc_cfg.bits_per_component = 8; + + /* Take the max for Bits per component */ + if (intel_dp->dsc_dpcd[0xa] & DP_DSC_8_BPC) +
[Intel-gfx] [PATCH 00/10] Enabling VDSC in i915 driver for GLK
Display manufacturers are turning to higher-resolution displays to differentiate their products. The increased pixel counts have required increased bandwidth over the links that drive these displays. However, advances in physical layer technology have not kept up with the increases in pixel counts. These factors have created a need for compression on display links. The Video Electronics Standards Association(VESA),in liaison with the MIPI Alliance, has developed an industry standard Display Stream Compression(DSC) for interoperable, visually lossless compression over display links. These patches enable VDSC in i915 gfx driver for Gen9,Gen10 platforms and provide basic code for future platforms. Testing: Did testing on GLK RVP. By default GLK RVP has non-DSC EDP panel, there was no regression with these patches. BA Chrome Team (OTC) do not have EDP panel which supports DSC. Trying to arrrage DSC EDP panel from other teams in BA, hopeful to get it in few weeks. Dropping the patches to get the review started. Gaurav K Singh (10): drm: i915: Defining Compression Capabilities drm: i915: Get DSC capability from DP sink drm: i915: Enable/Disable DSC in DP sink drm: i915: Compute RC & DSC parameters drm: i915: Define Picture Parameter Set drm/i915: Populate PPS Secondary Data Pkt for Sink drm: i915: Define VDSC regs and DSC params drm: i915: Enable VDSC in Source drm: i915: Disable VDSC from Source drm/i915: Encoder enable/disable seq wrt DSC drivers/gpu/drm/i915/Makefile|1 + drivers/gpu/drm/i915/i915_drv.h | 589 drivers/gpu/drm/i915/i915_reg.h | 451 drivers/gpu/drm/i915/intel_ddi.c |4 + drivers/gpu/drm/i915/intel_display.c | 20 + drivers/gpu/drm/i915/intel_dp.c | 182 + drivers/gpu/drm/i915/intel_drv.h | 64 ++ drivers/gpu/drm/i915/intel_vdsc.c| 1243 ++ include/drm/drm_dp_helper.h |3 + 9 files changed, 2557 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_vdsc.c -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/10] drm: i915: Define Picture Parameter Set
Vesa Display Stream Compression defines Picture Parameter Set(PPS), which encoders must communicate to decoders. PPS is encapsulated in 128 bytes(PS0 through PS127). PPS specifies the syntax for DSC bitstreams.Correct decoding also requires that an identical PPS be used at the encoder and decoder. The PPS contains parameters that the decoder needs to correctly decode pictures. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_drv.h | 389 1 file changed, 389 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4720a5ce3e69..760b97ec89ff 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -780,6 +780,395 @@ struct i915_psr { void (*setup_vsc)(struct intel_dp *, const struct intel_crtc_state *); }; +struct picture_parameters_set { + union { + /* PPS0 */ + unsigned char dsc_version; + struct { + /* Bit 0-3 Major version no */ + unsigned char minor : 4; + /* Bit 4-7 Minor version no */ + unsigned char major : 4; + }; + }; + + union { + /* PPS 1 ,2 */ + unsigned short picture_params_set_identifier; + struct { + /* +* Bit 0-7 Application-specific identifier that can be +* used to differentiate between different PPS table +*/ + unsigned short pps_identifier : 8; + /* Bit 8-15 Reserved */ + unsigned short pps2_reserved :8; + }; + }; + + union { + /* PPS 3 */ + unsigned char bpc_and_lbd; + struct { + /* +* Bit 0-3 [1000 = 8 bits, 1001 = 9 bits, +* 1010 = 10 bits, 1011 = 11 bits, 1100 = 12bits} +*/ + unsigned char line_buffer_depth : 4; + /* +* Bits 4-7 [1000 = 8 bits per component,1010 = 10 bits +* per component,1100 = 12 bits per component] +*/ + unsigned char bits_per_component : 4; + }; + }; + + union { + /* PPS 4,5 */ + unsigned short general_pps_params; + struct { + /* +* Bits 0-1 The target bits/pixel (bpp) rate that is +* used by the encoder, in steps of 1/16 of a +* bit per pixel +*/ + unsigned short bpp_low : 2; + /* +* Bit 2 [0 = VBR mode is disabled, +* 1 = VBR mode is enabled +*/ + unsigned short vbr_mode : 1; + /* Bit 3 [0 = 4:4:4 sampling, 1 = 4:2:2 sampling] */ + unsigned short enable422 : 1; + /* +* Bit 4 [ 0 = no conversion required, +* 1 = need conversion from RGB to YCoCg-R during +* encoding] +*/ + unsigned short convert_RGB : 1; + /* +* Bit 5 [0 = If block prediction is not supported +* on the receiver, 1 = If block prediction is +* supported on the receiver] +*/ + unsigned short block_prediction_enable : 1; + /* Bit 6-7 reserved */ + unsigned short pps4_reserved :2; + /* +* Bits 8-15 The target bits/pixel (bpp) rate that is +* used by the encoder, in steps of 1/16 of a bit per +* pixel +*/ + unsigned short bpp_high : 8; + }; + }; + + /* PPS 6,7 [2 bytes for pic height] */ + unsigned short picture_height; + /* PPS 8,9 [2 bytes for pic width] */ + unsigned short picture_width; + /* PPS 10,11 [2 bytes for slice height] */ + unsigned short slice_height; + /* PPS 12,13 [2 bytes for slice width] */ + unsigned short slice_width; + + /* PPS 14, 15 [2 bytes for Chunk size] */ + unsigned short chunk_size; + + union { + /* PPS 16,17 */ + unsigned short initial_transmission_delay; + struct { + /* +* Bit 0-1 Application-specific identifier that can be +* used to differentiate between
[Intel-gfx] [PATCH 04/10] drm: i915: Compute RC & DSC parameters
Below changes are there as part of this patch: 1. Adding Rate Control parameters for DSC 2. Compute Rate Control parameters 3. Compute DSC parameters for Picture Parameter Set 4. Adding a new .c file for VDSC operations Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.h | 12 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_vdsc.c | 562 ++ 4 files changed, 576 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_vdsc.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 838f9b48246b..fee46d41100e 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -114,6 +114,7 @@ i915-y += intel_audio.o \ intel_modes.o \ intel_overlay.o \ intel_psr.o \ + intel_vdsc.o \ intel_sideband.o \ intel_sprite.o i915-$(CONFIG_ACPI)+= intel_acpi.o intel_opregion.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4b1c323c0925..4720a5ce3e69 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -793,6 +793,17 @@ struct rc_range_parameters { unsigned long range_bpg_offset; }; +struct rc_parameters { + unsigned long initial_xmit_delay; + unsigned long first_line_bpg_Ofs; + unsigned long initial_offset; + unsigned long flatness_minQp; + unsigned long flatness_maxQp; + unsigned long rc_quant_incr_limit0; + unsigned long rc_quant_incr_limit1; + struct rc_range_parameters rc_range_params[NUM_BUF_RANGES]; +}; + struct vdsc_config { /* Bits / component for previous reconstructed line buffer */ unsigned long line_buf_depth; @@ -3858,6 +3869,7 @@ extern int intel_modeset_vga_set_state(struct drm_i915_private *dev_priv, extern int intel_set_rps(struct drm_i915_private *dev_priv, u8 val); extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable); +extern void intel_dp_compute_dsc_parameters(struct intel_dp *dp); int i915_reg_read_ioctl(struct drm_device *dev, void *data, struct drm_file *file); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c3b48b214e8f..93d3d6afa711 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6092,6 +6092,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, if (INTEL_GEN(dev_priv) >= 9) { intel_dp_sink_get_dsc_capability(intel_dp, &sink_dp_dsc_caps); intel_dp_get_compression_data(intel_dp, sink_dp_dsc_caps); + intel_dp_compute_dsc_parameters(intel_dp); } mutex_lock(&dev->mode_config.mutex); diff --git a/drivers/gpu/drm/i915/intel_vdsc.c b/drivers/gpu/drm/i915/intel_vdsc.c new file mode 100644 index ..5eef551f0d09 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_vdsc.c @@ -0,0 +1,562 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Gaurav K Singh + */ + +#include +#include +#include "i915_drv.h" +#include "intel_drv.h" + +enum ROW_INDEX_BPP { + ROW_INDEX_INVALID = 127, + ROW_INDEX_6BPP = 0, + ROW_INDEX_8BPP, + ROW_INDEX_10BPP, + ROW_INDEX_12BPP, + ROW_INDEX_15BPP, + MAX_ROW_INDEX +}; + +enum COLUMN_INDEX_BPC { + COLUMN_INDEX_INVALID = 127, + COLUMN_INDEX_8BPC = 0, + COLUMN_INDEX_10BPC, + COLUMN_INDEX_12BPC, + COLUMN_INDEX_14BPC, + COLUMN_INDEX_16BPC, + MAX_COLUMN_INDEX +}; + +#define TWOS_COMPLEMENT(x) (unsigned char)((~(x) + 1) & 0x3F) + +/* From DSC_v1.11 spec, rc_parameter_Set syntax element
[Intel-gfx] [PATCH] drm: i915: Fix audio issue on BXT
From: Gaurav Singh On Apollolake, with stress test warm reboot, audio card was not getting enumerated after reboot. This was a spurious issue happening on Apollolake. HW codec and HD audio controller link was going out of sync for which there was a fix in i915 driver but was not getting invoked for BXT. Extending this fix to BXT as well. Tested on apollolake chromebook by stress test warm reboot with 2500 iterations. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index f1502a0188eb..c71c04e1c3f6 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, struct drm_i915_private *dev_priv = kdev_to_i915(kdev); u32 tmp; - if (!IS_GEN9_BC(dev_priv)) + if (!IS_GEN9_BC(dev_priv) && !IS_BROXTON(dev_priv)) return; i915_audio_component_get_power(kdev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/14] drm/i915: Disable Tearing effect trigger by GPIO pin
While disabling MIPI Port in command mode, disable TE trigger by GPIO pin. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c |8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index d812e07..4a5905e 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -463,8 +463,12 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder) /* de-assert ip_tg_enable signal */ port_ctrl = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port); - temp = I915_READ(port_ctrl); - I915_WRITE(port_ctrl, temp & ~DPI_ENABLE); + if (is_cmd_mode(intel_dsi)) { + I915_WRITE(port_ctrl, 0); + } else { + temp = I915_READ(port_ctrl); + I915_WRITE(port_ctrl, temp & ~DPI_ENABLE); + } POSTING_READ(port_ctrl); } } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/14] DSI Command mode(DBI mode) enabling on CHT
Hi, These set of patches are for enabling DSI command mode on CHT. Command Mode refers to an operation in which transactions primarily take the form of sending commands and data to a peripheral that incorporates a display controller. The display controller may include local registers and a frame buffer. The host processor indirectly controls activity at the peripheral by sending commands, parameters and data to the display controller. Sink refreshes from its local frame buffer. Image updates require Source to write new data into the frame buffer which Source sends in the form of command + payload. The command mode panel we have here is 1080 x 1920. For this panel, features like support of i2c transactions for sending backlight on sequence, VBT version 3 patches, GPIO configuration changes for CHT are required. The same has been floated as part of different patch series. Floating the command mode enabling patches separately to start with the review. These patches have been rebased on top of BXT MIPI, BXT dual link changes. Regards Gaurav Gaurav K Singh (14): drm/i915: allocate DMA region for mipi dbi cmd buffer drm/i915: Add support for TEAR ON Sequence drm/i915: Add functions for dcs memory write cmd drm/i915: Calculate bw timer for mipi DBI interface drm/i915: Use the bpp value wrt the pixel format drm/i915: Disable vlank interrupt for disabling MIPI cmd mode drm/i915: Disable MIPI display self refresh mode drm/i915: Disable Tearing effect trigger by GPIO pin drm/i915: Changes for command mode preparation drm/i915: Enable Tearing effect trigger by GPIO pin drm/i915: Enable MIPI display self refresh mode drm/i915: Generalize DSI enable function drm/i915: Reset the display hw if vid mode to cmd mode drm/i915: send one frame after enabling mipi cmd mode drivers/gpu/drm/i915/i915_drv.h|1 + drivers/gpu/drm/i915/i915_reg.h|1 + drivers/gpu/drm/i915/intel_bios.h |2 + drivers/gpu/drm/i915/intel_display.c | 98 ++ drivers/gpu/drm/i915/intel_drv.h | 10 +++ drivers/gpu/drm/i915/intel_dsi.c | 121 +--- drivers/gpu/drm/i915/intel_dsi.h |3 + drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 34 +++- 8 files changed, 255 insertions(+), 15 deletions(-) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/14] drm/i915: Calculate bw timer for mipi DBI interface
This patch will calculate the bandwidth timer for MIPI DBI interface. If the BW timer value is available from VBT, then value from VBT will be used. Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 24 +++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index cacd5b8..7d9094a 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -56,6 +56,11 @@ static inline struct vbt_panel *to_vbt_panel(struct drm_panel *panel) #define CLK_ZERO_CNT_MAX 0xFF #define TRAIL_CNT_MAX 0x1F +#define LP_HDR_FOOT_SIZE 6 +#define BW_LP_NUM_OF_PKT 16 +#define BW_LP_LOAD_SIZE252 +#define EXTRA_ONE_BYTE 1 + #define NS_KHZ_RATIO 100 #define GPI0_NC_0_HV_DDI0_HPD 0x4130 @@ -443,7 +448,6 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->turn_arnd_val = mipi_config->turn_around_timeout; intel_dsi->rst_timer_val = mipi_config->device_reset_timer; intel_dsi->init_count = mipi_config->master_init_timer; - intel_dsi->bw_timer = mipi_config->dbi_bw_timer; intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; @@ -601,6 +605,24 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->dphy_reg = exit_zero_cnt << 24 | trail_cnt << 16 | clk_zero_cnt << 8 | prepare_cnt; + if (mipi_config->dbi_bw_timer) { + intel_dsi->bw_timer = mipi_config->dbi_bw_timer; + } else { + /* +* bw timer should be more than 16 longs packets containing +* 252 bytes + 2 blanking packets. +* bw timer = 16 long packets * (252 bytes payload for each +*long packet + 6 bytes for long packet header and +*footer) + 12 bytes for 2 blanking packets + 1 +*byte for having more of the above. +*/ + intel_dsi->bw_timer = DIV_ROUND_UP(BW_LP_NUM_OF_PKT * + (BW_LP_LOAD_SIZE + LP_HDR_FOOT_SIZE), + intel_dsi->lane_count); + + intel_dsi->bw_timer += (extra_byte_count + EXTRA_ONE_BYTE); + } + /* * LP to HS switch count = 4TLPX + PREP_COUNT * 2 + EXIT_ZERO_COUNT * 2 * + 10UI + Extra Byte Count -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/14] drm/i915: allocate DMA region for mipi dbi cmd buffer
Allocate DMA region for MIPI DBI command buffer. This memory will be used when sending command via DBI interface. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu --- drivers/gpu/drm/i915/intel_dsi.c | 17 + drivers/gpu/drm/i915/intel_dsi.h |2 ++ 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index d7e2118..6483d7f 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "i915_drv.h" #include "intel_drv.h" #include "intel_dsi.h" @@ -468,12 +469,22 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + dma_addr_t dma_handle; enum pipe pipe = intel_crtc->pipe; enum port port; u32 tmp; DRM_DEBUG_KMS("\n"); + if (IS_CHERRYVIEW(dev)) + intel_dsi->cmd_buff_virt_addr = dma_alloc_coherent(dev, 4096, + &dma_handle, GFP_KERNEL); + if (!intel_dsi->cmd_buff_virt_addr) + return -ENOMEM; + + intel_dsi->dma_handle = dma_handle; + } + /* Panel Enable over CRC PMIC */ if (intel_dsi->gpio_panel) gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1); @@ -661,6 +672,10 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder) msleep(intel_dsi->panel_off_delay); msleep(intel_dsi->panel_pwr_cycle_delay); + if (IS_CHERRYVIEW(dev_priv->dev) && intel_dsi->dma_handle) + dma_free_coherent(dev, 4096, + intel_dsi->cmd_buff_virt_addr, intel_dsi->dma_handle); + /* Panel Disable over CRC PMIC */ if (intel_dsi->gpio_panel) gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0); @@ -1198,6 +1213,8 @@ void intel_dsi_init(struct drm_device *dev) intel_encoder->crtc_mask = (1 << PIPE_B); intel_dsi->ports = (1 << PORT_C); } + intel_dsi->cmd_buff_virt_addr = NULL; + intel_dsi->dma_handle = 0; /* Create a DSI host (and a device) for each port. */ for_each_dsi_port(port, intel_dsi->ports) { diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index e6cb252..81b321f 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -46,6 +46,8 @@ struct intel_dsi { struct gpio_desc *gpio_panel; struct intel_connector *attached_connector; + void *cmd_buff_virt_addr; + dma_addr_t dma_handle; /* bit mask of ports being driven */ u16 ports; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/14] drm/i915: Add functions for dcs memory write cmd
Add functions for DCS memory write command. The mem write command to send fb data to panel is sent using this function. Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_reg.h |1 + drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_dsi.c | 41 ++ 3 files changed, 43 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4e5c0bb..ccba984 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4334,6 +4334,7 @@ enum skl_disp_power_wells { #define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */ #define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */ #define PIPECONF_INTERLACE_MODE_MASK (7 << 21) +#define PIPECONF_MIPI_DSR_ENABLE (1 << 20) #define PIPECONF_EDP_RR_MODE_SWITCH (1 << 20) #define PIPECONF_CXSR_DOWNCLOCK (1<<16) #define PIPECONF_EDP_RR_MODE_SWITCH_VLV (1 << 14) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index dae3cfd..b3d16ce 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1219,6 +1219,7 @@ void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port); /* intel_dsi.c */ void intel_dsi_init(struct drm_device *dev); +void intel_dsi_update_panel_fb(struct intel_encoder *encoder); /* intel_dvo.c */ void intel_dvo_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 6483d7f..8d018d0 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "i915_drv.h" #include "intel_drv.h" #include "intel_dsi.h" @@ -204,6 +205,38 @@ static struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, return host; } +int dsi_send_dcs_cmd(struct intel_dsi *intel_dsi, int channel, const u8 *data, +int len, bool pipe_render) +{ + struct drm_encoder *encoder = &intel_dsi->base.base; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum port port; + u32 cmd_addr; + + for_each_dsi_port(port, intel_dsi->ports) { + if (I915_READ(MIPI_COMMAND_ADDRESS(port)) & COMMAND_VALID) + return -EBUSY; + + if ((I915_READ(PIPECONF(port)) & PIPECONF_MIPI_DSR_ENABLE) == 0) + return -EBUSY; + + if (IS_CHERRYVIEW(dev)) { + cmd_addr = intel_dsi->dma_handle & + COMMAND_MEM_ADDRESS_MASK; + cmd_addr |= COMMAND_VALID; + + if (pipe_render) + cmd_addr |= MEMORY_WRITE_DATA_FROM_PIPE_RENDERING; + } + + I915_WRITE(MIPI_COMMAND_LENGTH(port), len); + I915_WRITE(MIPI_COMMAND_ADDRESS(port), cmd_addr); + } + + return 0; +} + /* * send a video mode command * @@ -748,6 +781,14 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, pipe_config->port_clock = pclk; } +void intel_dsi_update_panel_fb(struct intel_encoder *encoder) +{ + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + unsigned char uc_data[] = {MIPI_DCS_WRITE_MEMORY_START}; + + dsi_send_dcs_cmd(intel_dsi, 0, uc_data, sizeof(uc_data), true); +} + static enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 09/14] drm/i915: Changes for command mode preparation
Changes done in preparation of command mode- 1. Set DBI HS LS Switch bit for DBI packets to be tramitted in HS mode. 2. Set DBI FIFO watermark. 3. Timing regs need not be programmmed for command mode. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 4a5905e..70c4e56 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -999,12 +999,16 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) mode_hdisplay << HORIZONTAL_ADDRESS_SHIFT); } - set_dsi_timings(encoder, adjusted_mode); + if (is_vid_mode(intel_dsi)) + set_dsi_timings(encoder, adjusted_mode); val = intel_dsi->lane_count << DATA_LANES_PRG_REG_SHIFT; if (is_cmd_mode(intel_dsi)) { val |= intel_dsi->channel << CMD_MODE_CHANNEL_NUMBER_SHIFT; - val |= CMD_MODE_DATA_WIDTH_8_BIT; /* XXX */ + val |= CMD_MODE_DATA_WIDTH_OPTION2; + I915_WRITE(MIPI_DBI_FIFO_THROTTLE(port), + DBI_FIFO_EMPTY_QUARTER); + I915_WRITE(MIPI_HS_LP_DBI_ENABLE(port), 0); } else { val |= intel_dsi->channel << VID_MODE_CHANNEL_NUMBER_SHIFT; @@ -1117,6 +1121,11 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) intel_dsi->video_mode_format | IP_TG_CONFIG | RANDOM_DPI_DISPLAY_RESOLUTION); + else + I915_WRITE(MIPI_VIDEO_MODE_FORMAT(port), + intel_dsi->video_frmt_cfg_bits | + IP_TG_CONFIG | + RANDOM_DPI_DISPLAY_RESOLUTION); } } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/14] drm/i915: Add support for TEAR ON Sequence
For command mode panel, panel's fb enabling and tearing configuration is done as part of TEAR ON sequence. This patch parses and executes TEAR ON sequence for MIPI command mode. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_bios.h |2 ++ drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |9 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 1b7417e..d7fdb10 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -948,6 +948,8 @@ enum mipi_seq { MIPI_SEQ_DISPLAY_ON, MIPI_SEQ_DISPLAY_OFF, MIPI_SEQ_DEASSERT_RESET, + MIPI_SEQ_TEAR_ON, + MIPI_SEQ_TEAR_OFF, MIPI_SEQ_MAX }; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index feeca59..cacd5b8 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -251,7 +251,9 @@ static const char * const seq_name[] = { "MIPI_SEQ_INIT_OTP", "MIPI_SEQ_DISPLAY_ON", "MIPI_SEQ_DISPLAY_OFF", - "MIPI_SEQ_DEASSERT_RESET" + "MIPI_SEQ_DEASSERT_RESET", + "MIPI_SEQ_TEAR_ON", + "MIPI_SEQ_TEAR_OFF" }; static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) @@ -320,6 +322,11 @@ static int vbt_panel_prepare(struct drm_panel *panel) sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP]; generic_exec_sequence(intel_dsi, sequence); + if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) { + sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_TEAR_ON]; + generic_exec_sequence(intel_dsi, sequence); + } + return 0; } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/14] drm/i915: Enable Tearing effect trigger by GPIO pin
While enabling MIPI Port in command mode, enable tearing effect by GPIO pin. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c |5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 70c4e56..0f1bec4 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -445,7 +445,10 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) temp |= LANE_CONFIGURATION_DUAL_LINK_ENABLE; } /* assert ip_tg_enable signal */ - I915_WRITE(port_ctrl, temp | DPI_ENABLE); + if (is_cmd_mode(intel_dsi)) + I915_WRITE(port_ctrl, temp | TEARING_EFFECT_GPIO); + else + I915_WRITE(port_ctrl, temp | DPI_ENABLE); POSTING_READ(port_ctrl); } } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/14] drm/i915: Use the bpp value wrt the pixel format
The bpp value which is used while calulating the txbyteclkhs values should be wrt the pixel format value. Currently bpp is coming from pipe config to calculate txbyteclkhs. Signed-off-by: Deepak M Signed-off-by: Yogesh Mohan Marimuthu --- drivers/gpu/drm/i915/intel_dsi.c |5 ++--- drivers/gpu/drm/i915/intel_dsi.h |1 + drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 8d018d0..41f988c 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -843,10 +843,9 @@ static void set_dsi_timings(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - unsigned int bpp = intel_crtc->config->pipe_bpp; + unsigned int bpp = intel_dsi->dsi_bpp; unsigned int lane_count = intel_dsi->lane_count; u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; @@ -918,7 +917,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; enum port port; - unsigned int bpp = intel_crtc->config->pipe_bpp; + unsigned int bpp = intel_dsi->dsi_bpp; u32 val, tmp; u16 mode_hdisplay; diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 81b321f..31dc216 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -66,6 +66,7 @@ struct intel_dsi { /* video mode pixel format for MIPI_DSI_FUNC_PRG register */ u32 pixel_format; + u32 dsi_bpp; /* video mode format for MIPI_VIDEO_MODE_FORMAT register */ u32 video_mode_format; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 7d9094a..2abe9e8 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -450,6 +450,7 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->init_count = mipi_config->master_init_timer; intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; + intel_dsi->dsi_bpp = bits_per_pixel; pclk = mode->clock; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/14] drm/i915: Disable MIPI display self refresh mode
During disable sequence for MIPI encoder in command mode, disable MIPI display self-refresh mode bit in Pipe Ctrl reg. v2: Use crtc state flag instead of loop over encoders (Daniel) Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_display.c |3 +++ drivers/gpu/drm/i915/intel_drv.h |3 +++ drivers/gpu/drm/i915/intel_dsi.c |3 +++ 3 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0285af9..c2a5cdf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2159,6 +2159,9 @@ static void intel_disable_pipe(struct intel_crtc *crtc) if ((val & PIPECONF_ENABLE) == 0) return; + if (crtc->config->dsi_self_refresh) + val = val & ~PIPECONF_MIPI_DSR_ENABLE; + /* * Double wide has implications for planes * so best keep it disabled when not needed. diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b3d16ce..58fcd7d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -452,6 +452,9 @@ struct intel_crtc_state { bool double_wide; bool dp_encoder_is_mst; + + bool dsi_self_refresh; + int pbn; struct intel_crtc_scaler_state scaler_state; diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index d2b5d49..d812e07 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -307,6 +307,9 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, DRM_DEBUG_KMS("\n"); + if (is_cmd_mode(intel_dsi)) + config->dsi_self_refresh = true; + if (fixed_mode) intel_fixed_panel_mode(fixed_mode, adjusted_mode); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 13/14] drm/i915: Reset the display hw if vid mode to cmd mode
Reset the display hardware if video mode to command mode transition has to be done in MIPI display. otherwise command mode will not work. Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/intel_display.c | 43 ++ drivers/gpu/drm/i915/intel_dsi.c |4 3 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3d1700f..7538197 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1954,6 +1954,7 @@ struct drm_i915_private { } gt; bool edp_low_vswing; + bool video_disabled; /* * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0a6676f..5911a333 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6149,6 +6149,8 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; + bool all_pipe_disabled; + u32 val; /* * On gen2 planes are double buffered but the pipe isn't, so we must @@ -15444,6 +15446,47 @@ void intel_modeset_cleanup(struct drm_device *dev) mutex_lock(&dev->struct_mutex); intel_cleanup_gt_powersave(dev); mutex_unlock(&dev->struct_mutex); + + all_pipe_disabled = true; + for_each_pipe(dev_priv, pipe) { + if ((I915_READ(PIPECONF(pipe)) & + PIPECONF_ENABLE) == PIPECONF_ENABLE) + all_pipe_disabled = false; + } + + if ((all_pipe_disabled == true) && + (dev_priv->video_disabled == true)) { + + /* +* to switch from video mode to command mode, need to reset +* the display. +* FIXME: Even after resetting the display, the first modeset +* works sporadically(2 out of 3 times). Need to fix this. +* FIXME: Need to find a better way of doing this, because +* resetting the display resets all the registers in the +* display controller. Need to save and restore some of these +* required registers. +*/ + DRM_DEBUG_KMS("vid mode to cmd mode, reset display\n"); + if (IS_CHERRYVIEW(dev)) { + val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); + val = val | DP_SSC_PWR_GATE(0); + vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val); + + /* delay to power gate display controller */ + mdelay(5); + + val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); + val = val & ~((u32)DP_SSC_MASK(0)); + vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val); + + /* delay to power on display controller */ + mdelay(10); + } else + DRM_ERROR("vid mode to cmd mode reset is not done.\n"); + + i915_disable_vga(dev_priv->dev); + } } /* diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 2279859..da8526c 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -462,11 +462,15 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder) u32 temp; u32 port_ctrl; + dev_priv->video_disabled = false; + for_each_dsi_port(port, intel_dsi->ports) { /* de-assert ip_tg_enable signal */ port_ctrl = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port); if (is_cmd_mode(intel_dsi)) { + if (I915_READ(MIPI_PORT_CTRL(port)) & DPI_ENABLE) + dev_priv->video_disabled = true; I915_WRITE(port_ctrl, 0); } else { temp = I915_READ(port_ctrl); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/14] drm/i915: Enable MIPI display self refresh mode
During enable sequence for MIPI encoder in command mode, enable MIPI display self-refresh mode bit in Pipe Ctrl reg. v2: Use crtc state flag instead of loop over encoders (Daniel) Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_display.c |5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c2a5cdf..0a6676f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2122,6 +2122,11 @@ static void intel_enable_pipe(struct intel_crtc *crtc) return; } + if (crtc->config->dsi_self_refresh) { + val = val | PIPECONF_MIPI_DSR_ENABLE; + I915_WRITE(reg, val); + } + I915_WRITE(reg, val | PIPECONF_ENABLE); POSTING_READ(reg); } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 06/14] drm/i915: Disable vlank interrupt for disabling MIPI
vblank interrupt should be disabled before starting the disable sequence for MIPI command mode. Otherwise when pipe is disabled TE interurpt will be still handled and one memory write command will be sent with pipe disabled. This makes the pipe hw to get stuck and it doesn't recover in the next enable sequence causing display blank out. v2: Use drm_blank_off instead of platform specific disable vblank functions (Daniel) Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 41f988c..d2b5d49 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -568,13 +568,28 @@ static void intel_dsi_enable_nop(struct intel_encoder *encoder) static void intel_dsi_pre_disable(struct intel_encoder *encoder) { + struct drm_device *dev = encoder->base.dev; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + int pipe = intel_crtc->pipe; + enum port port; DRM_DEBUG_KMS("\n"); intel_panel_disable_backlight(intel_dsi->attached_connector); + if (is_cmd_mode(intel_dsi)) { + drm_vblank_off(dev, pipe); + + /* +* Make sure that the last frame is sent otherwise pipe can get +* stuck. Currently providing delay time for ~2 vblanks +* assuming 60fps. +*/ + mdelay(40); + } + if (is_vid_mode(intel_dsi)) { /* Send Shutdown command to the panel in LP mode */ for_each_dsi_port(port, intel_dsi->ports) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 12/14] drm/i915: Generalize DSI enable function
For command mode and video mode, panel prepare, wait for FIFO checks are required. Making these changes generic across command mode and video mode. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 0f1bec4..2279859 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -494,14 +494,14 @@ static void intel_dsi_enable(struct intel_encoder *encoder) for_each_dsi_port(port, intel_dsi->ports) dpi_send_cmd(intel_dsi, TURN_ON, false, port); msleep(100); + } - drm_panel_enable(intel_dsi->panel); + drm_panel_enable(intel_dsi->panel); - for_each_dsi_port(port, intel_dsi->ports) - wait_for_dsi_fifo_empty(intel_dsi, port); + for_each_dsi_port(port, intel_dsi->ports) + wait_for_dsi_fifo_empty(intel_dsi, port); - intel_dsi_port_enable(encoder); - } + intel_dsi_port_enable(encoder); intel_panel_enable_backlight(intel_dsi->attached_connector); } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 14/14] drm/i915: send one frame after enabling mipi cmd mode
If MIPI is operated in command mode, and after display reset. if not even one frame is sent after enabling the pipe and then if it is disabled, pipe is getting stuck. This patch will fix this issue by sending one frame after enabling the pipe. Ideally,there should not be a case where there is mode set and no frames are sent. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu --- drivers/gpu/drm/i915/intel_display.c | 47 ++ drivers/gpu/drm/i915/intel_drv.h |6 + 2 files changed, 53 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5911a333..37757bb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -44,6 +44,7 @@ #include #include #include +#include "intel_dsi.h" /* Primary plane formats for gen <= 3 */ static const uint32_t i8xx_primary_formats[] = { @@ -6016,6 +6017,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; + struct intel_dsi *intel_dsi; int pipe = intel_crtc->pipe; bool is_dsi; @@ -6071,6 +6073,25 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder->enable(encoder); + + for_each_encoder_on_crtc(dev, crtc, encoder) { + if (encoder->type != INTEL_OUTPUT_DSI) + continue; + + intel_dsi = enc_to_intel_dsi(&encoder->base); + if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) { + /* +* save the current pipe counter. During disable use +* this variable to check if at least one frame has +* been sent. If no frame is sent and MIPI is disabled +* in command mode, then pipe gets stuck. +*/ + intel_crtc->hw_frm_cnt_at_enable = + I915_READ(PIPEFRAME(pipe)); + } + break; + } + } static void i9xx_set_pll_dividers(struct intel_crtc *crtc) @@ -6148,10 +6169,36 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; + struct intel_dsi *intel_dsi; int pipe = intel_crtc->pipe; bool all_pipe_disabled; u32 val; + for_each_encoder_on_crtc(dev, crtc, encoder) { + if (encoder->type != INTEL_OUTPUT_DSI) + continue; + + intel_dsi = enc_to_intel_dsi(&encoder->base); + if ((intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) && + (intel_crtc->hw_frm_cnt_at_enable == + I915_READ(PIPEFRAME(pipe { + + intel_dsi_update_panel_fb(encoder); + + /* +* wait for ~2 frames for TE interrupt and sending one +* frame. +*/ + msleep(40); + + if (intel_crtc->hw_frm_cnt_at_enable == + I915_READ(PIPEFRAME(pipe))) + DRM_ERROR("Pipe is stuck for DSI cmd mode."); + } + + break; + } + /* * On gen2 planes are double buffered but the pipe isn't, so we must * wait for planes to fully turn off before disabling the pipe. diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 58fcd7d..9013f93 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -576,6 +576,12 @@ struct intel_crtc { /* scalers available on this crtc */ int num_scalers; + /* +* save the frame counter at enable sequence to make sure one frame has +* been sent before disable sequence. +*/ + u32 hw_frm_cnt_at_enable; + struct vlv_wm_state wm_state; }; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/4] drm/i915: Enable dual link mode in BXT
Enable BIT 0 of MIPI Port Ctrl reg to enable dual link mode. Signed-off-by: Deepak M Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_reg.h |7 --- drivers/gpu/drm/i915/intel_dsi.c |9 ++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1ea4686..4e5c0bb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7581,17 +7581,17 @@ enum skl_disp_power_wells { /* BXT MIPI mode configure */ #define _BXT_MIPIA_TRANS_HACTIVE 0x6B0F8 #define _BXT_MIPIC_TRANS_HACTIVE 0x6B8F8 -#define BXT_MIPI_TRANS_HACTIVE(tc)_MIPI_PORT(tc, \ +#define BXT_MIPI_TRANS_HACTIVE(port) _MIPI_PORT(port, \ _BXT_MIPIA_TRANS_HACTIVE, _BXT_MIPIC_TRANS_HACTIVE) #define _BXT_MIPIA_TRANS_VACTIVE 0x6B0FC #define _BXT_MIPIC_TRANS_VACTIVE 0x6B8FC -#define BXT_MIPI_TRANS_VACTIVE(tc)_MIPI_PORT(tc, \ +#define BXT_MIPI_TRANS_VACTIVE(port) _MIPI_PORT(port, \ _BXT_MIPIA_TRANS_VACTIVE, _BXT_MIPIC_TRANS_VACTIVE) #define _BXT_MIPIA_TRANS_VTOTAL 0x6B100 #define _BXT_MIPIC_TRANS_VTOTAL 0x6B900 -#define BXT_MIPI_TRANS_VTOTAL(tc) _MIPI_PORT(tc, \ +#define BXT_MIPI_TRANS_VTOTAL(port) _MIPI_PORT(port, \ _BXT_MIPIA_TRANS_VTOTAL, _BXT_MIPIC_TRANS_VTOTAL) #define BXT_DSI_PLL_CTL0x161000 @@ -7665,6 +7665,7 @@ enum skl_disp_power_wells { #define LANE_CONFIGURATION_4LANE (0 << 0) #define LANE_CONFIGURATION_DUAL_LINK_A(1 << 0) #define LANE_CONFIGURATION_DUAL_LINK_B(2 << 0) +#define LANE_CONFIGURATION_DUAL_LINK_ENABLE (1 << 0) #define _MIPIA_TEARING_CTRL(VLV_DISPLAY_BASE + 0x61194) #define _MIPIC_TEARING_CTRL(VLV_DISPLAY_BASE + 0x61704) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 2ccbda5..ec7e48b 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -400,9 +400,12 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) { temp |= (intel_dsi->dual_link - 1) << DUAL_LINK_MODE_SHIFT; - temp |= intel_crtc->pipe ? - LANE_CONFIGURATION_DUAL_LINK_B : - LANE_CONFIGURATION_DUAL_LINK_A; + if (IS_VALLEYVIEW(dev)) + temp |= intel_crtc->pipe ? + LANE_CONFIGURATION_DUAL_LINK_B : + LANE_CONFIGURATION_DUAL_LINK_A; + else if (IS_BROXTON(dev)) + temp |= LANE_CONFIGURATION_DUAL_LINK_ENABLE; } /* assert ip_tg_enable signal */ I915_WRITE(port_ctrl, temp | DPI_ENABLE); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/4] drm/i915: Program vactive & hactive display size for both ports
Program the required mmio regs for hactive and vactive display size. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_display.c | 37 ++ 1 file changed, 37 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ab9f06a..0285af9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7653,6 +7653,7 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; + bool is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); uint32_t tmp; tmp = I915_READ(HTOTAL(cpu_transcoder)); @@ -7681,6 +7682,25 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc, pipe_config->base.adjusted_mode.crtc_vblank_end += 1; } +if (IS_BROXTON(dev) && is_dsi) { + struct intel_encoder *encoder; + + for_each_encoder_on_crtc(dev, &crtc->base, encoder) { + struct intel_dsi *intel_dsi = + enc_to_intel_dsi(&encoder->base); + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) { + pipe_config->base.adjusted_mode.crtc_hdisplay = + I915_READ(BXT_MIPI_TRANS_HACTIVE(port)); + pipe_config->base.adjusted_mode.crtc_vdisplay = + I915_READ(BXT_MIPI_TRANS_VACTIVE(port)); + pipe_config->base.adjusted_mode.crtc_vtotal = + I915_READ(BXT_MIPI_TRANS_VTOTAL(port)); + } + } + } + tmp = I915_READ(PIPESRC(crtc->pipe)); pipe_config->pipe_src_h = (tmp & 0x) + 1; pipe_config->pipe_src_w = ((tmp >> 16) & 0x) + 1; @@ -10569,6 +10589,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, int vtot = I915_READ(VTOTAL(cpu_transcoder)); int vsync = I915_READ(VSYNC(cpu_transcoder)); enum pipe pipe = intel_crtc->pipe; + bool is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI); mode = kzalloc(sizeof(*mode), GFP_KERNEL); if (!mode) @@ -10598,6 +10619,22 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, mode->vsync_start = (vsync & 0x) + 1; mode->vsync_end = ((vsync & 0x) >> 16) + 1; + if (IS_BROXTON(dev) && is_dsi) { + struct intel_encoder *encoder; + + for_each_encoder_on_crtc(dev, &intel_crtc->base, encoder) { + struct intel_dsi *intel_dsi = + enc_to_intel_dsi(&encoder->base); + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) { + mode->vtotal = I915_READ(BXT_MIPI_TRANS_VTOTAL(port)); + mode->hdisplay = I915_READ(BXT_MIPI_TRANS_HACTIVE(port)); + mode->vdisplay = I915_READ(BXT_MIPI_TRANS_VACTIVE(port)); + } + } + } + drm_mode_set_name(mode); return mode; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/4] drm/i915: Use adjusted mode clk for calculating DSI clk
Earlier, pclk was getting used for calculating DSI clk. For single link MIPI panels, it will work fine. But for dual link MIPI, since pclk gets halved, DSI clk will have a wrong value. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_pll.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index bf0f622..a53ccc9 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -468,12 +468,14 @@ static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port) static bool bxt_configure_dsi_pll(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); u8 dsi_ratio; u32 dsi_clk; u32 val; - dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format, + dsi_clk = dsi_clk_from_pclk(mode->clock, intel_dsi->pixel_format, intel_dsi->lane_count); /* -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/4] DSI Dual link enabling on BXT
Hi, These patches enable DSI dual link mode on BXT boards. These set of patches build on top of the floated DSI Video mode patches on BXT (Uma's patches). Regards Gaurav Gaurav K Singh (4): drm/i915: Enable dual link mode in BXT drm/i915: Use adjusted mode clk for calculating DSI clk drm/i915: Execute RESET sequence before device ready drm/i915: Program vactive & hactive display size for both ports drivers/gpu/drm/i915/i915_reg.h|7 +++--- drivers/gpu/drm/i915/intel_display.c | 37 drivers/gpu/drm/i915/intel_dsi.c | 11 ++--- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 15 +++ drivers/gpu/drm/i915/intel_dsi_pll.c |4 ++- include/drm/drm_panel.h|9 +++ 6 files changed, 76 insertions(+), 7 deletions(-) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/4] drm/i915: Execute RESET sequence before device ready
Before setting the MIPI device to ready state, execute the RESET sequence. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi.c |2 ++ drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 15 +++ include/drm/drm_panel.h|9 + 3 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index ec7e48b..d7e2118 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -497,6 +497,8 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder) I915_WRITE(DSPCLK_GATE_D, tmp); } + drm_panel_reset(intel_dsi->panel); + /* put device in ready state */ intel_dsi_device_ready(encoder); diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index a5e99ac..feeca59 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -292,6 +292,20 @@ static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) } } +static int vbt_panel_reset(struct drm_panel *panel) +{ + struct vbt_panel *vbt_panel = to_vbt_panel(panel); + struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; + struct drm_device *dev = intel_dsi->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + const u8 *sequence; + + sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET]; + generic_exec_sequence(intel_dsi, sequence); + + return 0; +} + static int vbt_panel_prepare(struct drm_panel *panel) { struct vbt_panel *vbt_panel = to_vbt_panel(panel); @@ -377,6 +391,7 @@ static const struct drm_panel_funcs vbt_panel_funcs = { .disable = vbt_panel_disable, .unprepare = vbt_panel_unprepare, .prepare = vbt_panel_prepare, + .reset = vbt_panel_reset, .enable = vbt_panel_enable, .get_modes = vbt_panel_get_modes, }; diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 13ff44b..1e2432e 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -68,6 +68,7 @@ struct display_timing; struct drm_panel_funcs { int (*disable)(struct drm_panel *panel); int (*unprepare)(struct drm_panel *panel); + int (*reset)(struct drm_panel *panel); int (*prepare)(struct drm_panel *panel); int (*enable)(struct drm_panel *panel); int (*get_modes)(struct drm_panel *panel); @@ -101,6 +102,14 @@ static inline int drm_panel_disable(struct drm_panel *panel) return panel ? -ENOSYS : -EINVAL; } +static inline int drm_panel_reset(struct drm_panel *panel) +{ + if (panel && panel->funcs && panel->funcs->prepare) + return panel->funcs->reset(panel); + + return panel ? -ENOSYS : -EINVAL; +} + static inline int drm_panel_prepare(struct drm_panel *panel) { if (panel && panel->funcs && panel->funcs->prepare) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Allow DSI dual link to be configured on any pipe
Just like single link MIPI panels, similarly for dual link panels, pipe to be configured is based on the DVO port from VBT Block 2. In hardware, Port A is mapped with Pipe A and Port C is mapped with Pipe B. This issue got introduced in - commit 7e9804fdcffc650515c60f524b8b2076ee59e710 Author: Jani Nikula Date: Fri Jan 16 14:27:23 2015 +0200 drm/i915/dsi: add drm mipi dsi host support Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi.c |9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 18dd7d7..8aa9c7cc 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1048,11 +1048,7 @@ void intel_dsi_init(struct drm_device *dev) intel_connector->unregister = intel_connector_unregister; /* Pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI port C */ - if (dev_priv->vbt.dsi.config->dual_link) { - /* XXX: does dual link work on either pipe? */ - intel_encoder->crtc_mask = (1 << PIPE_A); - intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C)); - } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) { + if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIA) { intel_encoder->crtc_mask = (1 << PIPE_A); intel_dsi->ports = (1 << PORT_A); } else if (dev_priv->vbt.dsi.port == DVO_PORT_MIPIC) { @@ -1060,6 +1056,9 @@ void intel_dsi_init(struct drm_device *dev) intel_dsi->ports = (1 << PORT_C); } + if (dev_priv->vbt.dsi.config->dual_link) + intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C)); + /* Create a DSI host (and a device) for each port. */ for_each_dsi_port(port, intel_dsi->ports) { struct intel_dsi_host *host; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] {Intel-gfx] [RFC 01/14] drm/i915: allocate gem memory for mipi dbi cmd buffer
Allocate gem memory for MIPI DBI command buffer. This memory will be used when sending command via DBI interface. v2: lock mutex before gem object unreference and later set gem obj ptr to NULL (Gaurav) Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 40 ++ drivers/gpu/drm/i915/intel_dsi.h |4 2 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 98998e9..011fef2 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -407,9 +407,35 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder) enum pipe pipe = intel_crtc->pipe; enum port port; u32 tmp; + int ret; DRM_DEBUG_KMS("\n"); + if (!intel_dsi->gem_obj && is_cmd_mode(intel_dsi)) { + intel_dsi->gem_obj = i915_gem_alloc_object(dev, 4096); + if (!intel_dsi->gem_obj) { + DRM_ERROR("Failed to allocate seqno page\n"); + return; + } + + ret = i915_gem_object_set_cache_level(intel_dsi->gem_obj, + I915_CACHE_LLC); + if (ret) + goto err_unref; + + ret = i915_gem_obj_ggtt_pin(intel_dsi->gem_obj, 4096, 0); + if (ret) { +err_unref: + drm_gem_object_unreference(&intel_dsi->gem_obj->base); + return; + } + + intel_dsi->cmd_buff = + kmap(sg_page(intel_dsi->gem_obj->pages->sgl)); + intel_dsi->cmd_buff_phy_addr = page_to_phys( + sg_page(intel_dsi->gem_obj->pages->sgl)); + } + /* Disable DPOunit clock gating, can stall pipe * and we need DPLL REFA always enabled */ tmp = I915_READ(DPLL(pipe)); @@ -555,6 +581,7 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct drm_device *dev = encoder->base.dev; u32 val; DRM_DEBUG_KMS("\n"); @@ -571,6 +598,15 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder) msleep(intel_dsi->panel_off_delay); msleep(intel_dsi->panel_pwr_cycle_delay); + + if (intel_dsi->gem_obj) { + kunmap(intel_dsi->cmd_buff); + i915_gem_object_ggtt_unpin(intel_dsi->gem_obj); + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(&intel_dsi->gem_obj->base); + mutex_unlock(&dev->struct_mutex); + } + intel_dsi->gem_obj = NULL; } static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, @@ -1042,6 +1078,10 @@ void intel_dsi_init(struct drm_device *dev) intel_dsi->ports = (1 << PORT_C); } + intel_dsi->cmd_buff = NULL; + intel_dsi->cmd_buff_phy_addr = 0; + intel_dsi->gem_obj = NULL; + /* Create a DSI host (and a device) for each port. */ for_each_dsi_port(port, intel_dsi->ports) { struct intel_dsi_host *host; diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 2784ac4..36ca3cc 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -44,6 +44,10 @@ struct intel_dsi { struct intel_connector *attached_connector; + struct drm_i915_gem_object *gem_obj; + void *cmd_buff; + dma_addr_t cmd_buff_phy_addr; + /* bit mask of ports being driven */ u16 ports; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 11/14] drm/i915: Enable MIPI display self refresh mode
During enable sequence for MIPI encoder in command mode, enable MIPI display self-refresh mode bit in Pipe Ctrl reg. v2: Use crtc state flag instead of loop over encoders (Daniel) Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_display.c |5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dd518d6..c53f66d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2158,6 +2158,11 @@ static void intel_enable_pipe(struct intel_crtc *crtc) return; } + if (crtc->config->dsi_self_refresh) { + val = val | PIPECONF_MIPI_DSR_ENABLE; + I915_WRITE(reg, val); + } + I915_WRITE(reg, val | PIPECONF_ENABLE); POSTING_READ(reg); } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 07/14] drm/i915: Disable MIPI display self refresh mode
During disable sequence for MIPI encoder in command mode, disable MIPI display self-refresh mode bit in Pipe Ctrl reg. v2: Use crtc state flag instead of loop over encoders (Daniel) Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_display.c |3 +++ drivers/gpu/drm/i915/intel_drv.h |3 +++ drivers/gpu/drm/i915/intel_dsi.c |3 +++ 3 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 067b1de..dd518d6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2193,6 +2193,9 @@ static void intel_disable_pipe(struct intel_crtc *crtc) if ((val & PIPECONF_ENABLE) == 0) return; + if (crtc->config->dsi_self_refresh) + val = val & ~PIPECONF_MIPI_DSR_ENABLE; + /* * Double wide has implications for planes * so best keep it disabled when not needed. diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 14562c6..4298a00 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -444,6 +444,9 @@ struct intel_crtc_state { bool double_wide; bool dp_encoder_is_mst; + + bool dsi_self_refresh; + int pbn; struct intel_crtc_scaler_state scaler_state; diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 7021591..36d8ad6 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -308,6 +308,9 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, DRM_DEBUG_KMS("\n"); + if (is_cmd_mode(intel_dsi)) + config->dsi_self_refresh = true; + if (fixed_mode) intel_fixed_panel_mode(fixed_mode, adjusted_mode); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 06/14] drm/i915: Disable vlank interrupt for disabling MIPI cmd mode
vblank interrupt should be disabled before starting the disable sequence for MIPI command mode. Otherwise when pipe is disabled TE interurpt will be still handled and one memory write command will be sent with pipe disabled. This makes the pipe hw to get stuck and it doesn't recover in the next enable sequence causing display blank out. v2: Use drm_blank_off instead of platform specific disable vblank functions (Daniel) Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index d378246..7021591 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -513,11 +513,25 @@ static void intel_dsi_enable_nop(struct intel_encoder *encoder) static void intel_dsi_pre_disable(struct intel_encoder *encoder) { + struct drm_device *dev = encoder->base.dev; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + int pipe = intel_crtc->pipe; enum port port; DRM_DEBUG_KMS("\n"); + if (is_cmd_mode(intel_dsi)) { + drm_vblank_off(dev, pipe); + + /* +* Make sure that the last frame is sent otherwise pipe can get +* stuck. Currently providing delay time for ~2 vblanks +* assuming 60fps. +*/ + mdelay(40); + } + if (is_vid_mode(intel_dsi)) { /* Send Shutdown command to the panel in LP mode */ for_each_dsi_port(port, intel_dsi->ports) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 14/14] drm/i915: send one frame after enabling mipi cmd mode
If MIPI is operated in command mode, and after display reset. if not even one frame is sent after enabling the pipe and then if it is disabled, pipe is getting stuck. This patch will fix this issue by sending one frame after enabling the pipe. Ideally,there should not be a case where there is mode set and no frames are sent. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu --- drivers/gpu/drm/i915/intel_display.c | 46 ++ drivers/gpu/drm/i915/intel_drv.h |6 + 2 files changed, 52 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8dd0066..46e7f0b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5905,6 +5905,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; + struct intel_dsi *intel_dsi; int pipe = intel_crtc->pipe; bool is_dsi; @@ -5967,6 +5968,25 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) for_each_encoder_on_crtc(dev, crtc, encoder) encoder->enable(encoder); + + for_each_encoder_on_crtc(dev, crtc, encoder) { + if (encoder->type != INTEL_OUTPUT_DSI) + continue; + + intel_dsi = enc_to_intel_dsi(&encoder->base); + if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) { + /* +* save the current pipe counter. During disable use +* this variable to check if at least one frame has +* been sent. If no frame is sent and MIPI is disabled +* in command mode, then pipe gets stuck. +*/ + intel_crtc->hw_frm_cnt_at_enable = + I915_READ(PIPEFRAME(pipe)); + } + break; + } + } static void i9xx_set_pll_dividers(struct intel_crtc *crtc) @@ -6065,6 +6085,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; + struct intel_dsi *intel_dsi; int pipe = intel_crtc->pipe; bool all_pipe_disabled; u32 val; @@ -6072,6 +6093,31 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) if (!intel_crtc->active) return; + for_each_encoder_on_crtc(dev, crtc, encoder) { + if (encoder->type != INTEL_OUTPUT_DSI) + continue; + + intel_dsi = enc_to_intel_dsi(&encoder->base); + if ((intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) && + (intel_crtc->hw_frm_cnt_at_enable == + I915_READ(PIPEFRAME(pipe { + + intel_dsi_update_panel_fb(encoder); + + /* +* wait for ~2 frames for TE interrupt and sending one +* frame. +*/ + msleep(40); + + if (intel_crtc->hw_frm_cnt_at_enable == + I915_READ(PIPEFRAME(pipe))) + DRM_ERROR("Pipe is stuck for DSI cmd mode."); + } + + break; + } + /* * On gen2 planes are double buffered but the pipe isn't, so we must * wait for planes to fully turn off before disabling the pipe. diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7c59862..e453934 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -550,6 +550,12 @@ struct intel_crtc { /* scalers available on this crtc */ int num_scalers; + + /* +* save the frame counter at enable sequence to make sure one frame has +* been sent before disable sequence. +*/ + u32 hw_frm_cnt_at_enable; }; struct intel_plane_wm_parameters { -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 12/14] drm/i915: Generalize DSI enable function
For command mode and video mode, panel prepare, wait for FIFO checks are required. Making these changes generic across command mode and video mode. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 484ed38..fc552f1 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -437,14 +437,15 @@ static void intel_dsi_enable(struct intel_encoder *encoder) for_each_dsi_port(port, intel_dsi->ports) dpi_send_cmd(intel_dsi, TURN_ON, false, port); msleep(100); + } - drm_panel_enable(intel_dsi->panel); + drm_panel_enable(intel_dsi->panel); - for_each_dsi_port(port, intel_dsi->ports) - wait_for_dsi_fifo_empty(intel_dsi, port); + for_each_dsi_port(port, intel_dsi->ports) + wait_for_dsi_fifo_empty(intel_dsi, port); + + intel_dsi_port_enable(encoder); - intel_dsi_port_enable(encoder); - } } static void intel_dsi_pre_enable(struct intel_encoder *encoder) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 09/14] drm/i915: Changes for command mode preparation
Changes done in preparation of command mode- 1. Set DBI HS LS Switch bit for DBI packets to be tramitted in HS mode. 2. Set DBI FIFO watermark. 3. Timing regs need not be programmmed for command mode. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 91ed2c2..f2fb3fc 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -876,12 +876,16 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) mode_hdisplay << HORIZONTAL_ADDRESS_SHIFT); } - set_dsi_timings(encoder, adjusted_mode); + if (is_vid_mode(intel_dsi)) + set_dsi_timings(encoder, adjusted_mode); val = intel_dsi->lane_count << DATA_LANES_PRG_REG_SHIFT; if (is_cmd_mode(intel_dsi)) { val |= intel_dsi->channel << CMD_MODE_CHANNEL_NUMBER_SHIFT; - val |= CMD_MODE_DATA_WIDTH_8_BIT; /* XXX */ + val |= CMD_MODE_DATA_WIDTH_OPTION2; + I915_WRITE(MIPI_DBI_FIFO_THROTTLE(port), + DBI_FIFO_EMPTY_QUARTER); + I915_WRITE(MIPI_HS_LP_DBI_ENABLE(port), 0); } else { val |= intel_dsi->channel << VID_MODE_CHANNEL_NUMBER_SHIFT; @@ -983,6 +987,11 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) intel_dsi->video_mode_format | IP_TG_CONFIG | RANDOM_DPI_DISPLAY_RESOLUTION); + else + I915_WRITE(MIPI_VIDEO_MODE_FORMAT(port), + intel_dsi->video_frmt_cfg_bits | + IP_TG_CONFIG | + RANDOM_DPI_DISPLAY_RESOLUTION); } } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 11/14] drm/i915: Enable MIPI display self refresh mode
During enable sequence for MIPI encoder in command mode, enable MIPI display self-refresh mode bit in Pipe Ctrl reg. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_display.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cab2ac8..fc84313 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -44,6 +44,7 @@ #include #include #include +#include "intel_dsi.h" /* Primary plane formats supported by all gen */ #define COMMON_PRIMARY_FORMATS \ @@ -2110,6 +2111,8 @@ static void intel_enable_pipe(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_encoder *encoder; + struct intel_dsi *intel_dsi; enum pipe pipe = crtc->pipe; enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, pipe); @@ -2154,6 +2157,18 @@ static void intel_enable_pipe(struct intel_crtc *crtc) return; } + for_each_encoder_on_crtc(dev, &crtc->base, encoder) { + if (encoder->type == INTEL_OUTPUT_DSI) { + intel_dsi = enc_to_intel_dsi(&encoder->base); + if (intel_dsi && (intel_dsi->operation_mode == + INTEL_DSI_COMMAND_MODE)) { + val = val | PIPECONF_MIPI_DSR_ENABLE; + I915_WRITE(reg, val); + } + break; + } + } + I915_WRITE(reg, val | PIPECONF_ENABLE); POSTING_READ(reg); } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 05/14] drm/i915: Use the bpp value wrt the pixel format
The bpp value which is used while calulating the txbyteclkhs values should be wrt the pixel format value. Currently bpp is coming from pipe config to calculate txbyteclkhs. Signed-off-by: Gaurav K Singh Signed-off-by: Deepak M Signed-off-by: Yogesh Mohan Marimuthu --- drivers/gpu/drm/i915/intel_dsi.c |5 ++--- drivers/gpu/drm/i915/intel_dsi.h |1 + drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 7cedd63..04d8ce0 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -762,10 +762,9 @@ static void set_dsi_timings(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - unsigned int bpp = intel_crtc->config->pipe_bpp; + unsigned int bpp = intel_dsi->dsi_bpp; unsigned int lane_count = intel_dsi->lane_count; u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; @@ -822,7 +821,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; enum port port; - unsigned int bpp = intel_crtc->config->pipe_bpp; + unsigned int bpp = intel_dsi->dsi_bpp; u32 val, tmp; u16 mode_hdisplay; diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 36ca3cc..6b53b1f 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -65,6 +65,7 @@ struct intel_dsi { /* video mode pixel format for MIPI_DSI_FUNC_PRG register */ u32 pixel_format; + u32 dsi_bpp; /* video mode format for MIPI_VIDEO_MODE_FORMAT register */ u32 video_mode_format; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 38de166..6774726 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -437,6 +437,7 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->init_count = mipi_config->master_init_timer; intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; + intel_dsi->dsi_bpp = bits_per_pixel; pclk = mode->clock; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 10/14] drm/i915: Enable Tearing effect trigger by GPIO pin
While enabling MIPI Port in command mode, enable tearing effect by GPIO pin. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c |6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index f2fb3fc..484ed38 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -352,7 +352,11 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) LANE_CONFIGURATION_DUAL_LINK_A; } /* assert ip_tg_enable signal */ - I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); + if (is_cmd_mode(intel_dsi)) + I915_WRITE(MIPI_PORT_CTRL(port), + temp | TEARING_EFFECT_GPIO); + else + I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(port)); } } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 13/14] drm/i915: Reset the display hw if vid mode to cmd mode
Reset the display hardware if video mode to command mode transition has to be done in MIPI display. otherwise command mode will not work. Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/intel_display.c | 81 ++ drivers/gpu/drm/i915/intel_dsi.c |4 ++ 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6a66d6b..8c06377 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1854,6 +1854,7 @@ struct drm_i915_private { } gt; bool edp_low_vswing; + bool video_disabled; /* * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fc84313..8dd0066 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6025,6 +6025,25 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) encoder->enable(encoder); } +/* Disable the VGA plane that we never use */ +static void i915_disable_vga(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u8 sr1; + u32 vga_reg = i915_vgacntrl_reg(dev); + + /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */ + vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); + outb(SR01, VGA_SR_INDEX); + sr1 = inb(VGA_SR_DATA); + outb(sr1 | 1<<5, VGA_SR_DATA); + vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); + udelay(300); + + I915_WRITE(vga_reg, VGA_DISP_DISABLE); + POSTING_READ(vga_reg); +} + static void i9xx_pfit_disable(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; @@ -6047,6 +6066,8 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; + bool all_pipe_disabled; + u32 val; if (!intel_crtc->active) return; @@ -6091,6 +6112,47 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) mutex_lock(&dev->struct_mutex); intel_fbc_update(dev); mutex_unlock(&dev->struct_mutex); + + all_pipe_disabled = true; + for_each_pipe(dev_priv, pipe) { + if ((I915_READ(PIPECONF(pipe)) & + PIPECONF_ENABLE) == PIPECONF_ENABLE) + all_pipe_disabled = false; + } + + if ((all_pipe_disabled == true) && + (dev_priv->video_disabled == true)) { + + /* +* to switch from video mode to command mode, need to reset +* the display. +* FIXME: Even after resetting the display, the first modeset +* works sporadically(2 out of 3 times). Need to fix this. +* FIXME: Need to find a better way of doing this, because +* resetting the display resets all the registers in the +* display controller. Need to save and restore some of these +* required registers. +*/ + DRM_DEBUG_KMS("vid mode to cmd mode, reset display\n"); + if (IS_CHERRYVIEW(dev)) { + val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); + val = val | DP_SSC_PWR_GATE(0); + vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val); + + /* delay to power gate display controller */ + mdelay(5); + + val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); + val = val & ~((u32)DP_SSC_MASK(0)); + vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val); + + /* delay to power on display controller */ + mdelay(10); + } else + DRM_ERROR("vid mode to cmd mode reset is not done.\n"); + + i915_disable_vga(dev_priv->dev); + } } static void i9xx_crtc_off(struct drm_crtc *crtc) @@ -14405,25 +14467,6 @@ static void intel_init_quirks(struct drm_device *dev) } } -/* Disable the VGA plane that we never use */ -static void i915_disable_vga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u8 sr1; - u32 vga_reg = i915_vgacntrl_reg(dev); - - /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */ - vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); - outb(SR01, VGA_SR_INDEX); - sr1 = inb(VGA_SR_DATA); - outb(sr1 | 1<<5, VGA_SR_DATA); - vga_put
[Intel-gfx] [RFC 08/14] drm/i915: Disable Tearing effect trigger by GPIO pin
While disabling MIPI Port in command mode, disable TE trigger by GPIO pin. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c |8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index aeea289..91ed2c2 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -367,8 +367,12 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder) for_each_dsi_port(port, intel_dsi->ports) { /* de-assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); + if (is_cmd_mode(intel_dsi)) { + I915_WRITE(MIPI_PORT_CTRL(port), 0); + } else { + temp = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); + } POSTING_READ(MIPI_PORT_CTRL(port)); } } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 07/14] drm/i915: Disable MIPI display self refresh mode
During disable sequence for MIPI encoder in command mode, disable MIPI display self-refresh mode bit in Pipe Ctrl reg. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_display.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 895d7c7..cab2ac8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2171,6 +2171,9 @@ static void intel_enable_pipe(struct intel_crtc *crtc) static void intel_disable_pipe(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct intel_encoder *encoder; + struct intel_dsi *intel_dsi; + struct drm_device *dev = crtc->base.dev; enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; enum pipe pipe = crtc->pipe; int reg; @@ -2189,6 +2192,16 @@ static void intel_disable_pipe(struct intel_crtc *crtc) if ((val & PIPECONF_ENABLE) == 0) return; + for_each_encoder_on_crtc(dev, &crtc->base, encoder) { + if (encoder->type == INTEL_OUTPUT_DSI) { + intel_dsi = enc_to_intel_dsi(&encoder->base); + if (intel_dsi && (intel_dsi->operation_mode == + INTEL_DSI_COMMAND_MODE)) + val = val & ~PIPECONF_MIPI_DSR_ENABLE; + break; + } + } + /* * Double wide has implications for planes * so best keep it disabled when not needed. -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 06/14] drm/i915: Disable vlank interrupt for disabling MIPI cmd mode
vblank interrupt should be disabled before starting the disable sequence for MIPI command mode. Otherwise when pipe is disabled TE interurpt will be still handled and one memory write command will be sent with pipe disabled. This makes the pipe hw to get stuck and it doesn't recover in the next enable sequence causing display blank out. Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 04d8ce0..aeea289 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -513,11 +513,25 @@ static void intel_dsi_enable_nop(struct intel_encoder *encoder) static void intel_dsi_pre_disable(struct intel_encoder *encoder) { + struct drm_device *dev = encoder->base.dev; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + int pipe = intel_crtc->pipe; enum port port; DRM_DEBUG_KMS("\n"); + if (is_cmd_mode(intel_dsi)) { + dev->driver->disable_vblank(dev, pipe); + + /* +* Make sure that the last frame is sent otherwise pipe can get +* stuck. Currently providing delay time for ~2 vblanks +* assuming 60fps. +*/ + mdelay(40); + } + if (is_vid_mode(intel_dsi)) { /* Send Shutdown command to the panel in LP mode */ for_each_dsi_port(port, intel_dsi->ports) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 01/14] drm/i915: allocate gem memory for mipi dbi cmd buffer
Allocate gem memory for MIPI DBI command buffer. This memory will be used when sending command via DBI interface. Signed-off-by: Yogesh Mohan Marimuthu Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 31 +++ drivers/gpu/drm/i915/intel_dsi.h |4 2 files changed, 35 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 5196642..2e3c801 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -415,6 +415,27 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder) DRM_DEBUG_KMS("\n"); + if (!intel_dsi->gem_obj && is_cmd_mode(intel_dsi)) { + intel_dsi->gem_obj = i915_gem_alloc_object(dev, 4096); + if (!intel_dsi->gem_obj) { + DRM_ERROR("Failed to allocate seqno page\n"); + return; + } + + i915_gem_object_set_cache_level(intel_dsi->gem_obj, + I915_CACHE_LLC); + + if (i915_gem_obj_ggtt_pin(intel_dsi->gem_obj, 4096, 0)) { + DRM_ERROR("MIPI command buffer GTT pin failed"); + return; + } + + intel_dsi->cmd_buff = + kmap(sg_page(intel_dsi->gem_obj->pages->sgl)); + intel_dsi->cmd_buff_phy_addr = page_to_phys( + sg_page(intel_dsi->gem_obj->pages->sgl)); + } + /* Disable DPOunit clock gating, can stall pipe * and we need DPLL REFA always enabled */ tmp = I915_READ(DPLL(pipe)); @@ -576,6 +597,12 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder) msleep(intel_dsi->panel_off_delay); msleep(intel_dsi->panel_pwr_cycle_delay); + + if (intel_dsi->gem_obj) { + kunmap(intel_dsi->cmd_buff); + i915_gem_object_ggtt_unpin(intel_dsi->gem_obj); + drm_gem_object_unreference(&intel_dsi->gem_obj->base); + } } static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, @@ -1048,6 +1075,10 @@ void intel_dsi_init(struct drm_device *dev) intel_dsi->ports = (1 << PORT_C); } + intel_dsi->cmd_buff = NULL; + intel_dsi->cmd_buff_phy_addr = 0; + intel_dsi->gem_obj = NULL; + /* Create a DSI host (and a device) for each port. */ for_each_dsi_port(port, intel_dsi->ports) { struct intel_dsi_host *host; diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 2784ac4..36ca3cc 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -44,6 +44,10 @@ struct intel_dsi { struct intel_connector *attached_connector; + struct drm_i915_gem_object *gem_obj; + void *cmd_buff; + dma_addr_t cmd_buff_phy_addr; + /* bit mask of ports being driven */ u16 ports; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 02/14] drm/i915: Add support for TEAR ON Sequence
For command mode panel, panel's fb enabling and tearing configuration is done as part of TEAR ON sequence. This patch parses and executes TEAR ON sequence for MIPI command mode. Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar Signed-off-by: Yogesh Mohan Marimuthu --- drivers/gpu/drm/i915/intel_bios.h |4 drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 11 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index af0b476..be4eaab 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -934,6 +934,10 @@ enum mipi_seq { MIPI_SEQ_DISPLAY_ON, MIPI_SEQ_DISPLAY_OFF, MIPI_SEQ_DEASSERT_RESET, + MIPI_SEQ_BACKLIGHT_ON, + MIPI_SEQ_BACKLIGHT_OFF, + MIPI_SEQ_TEAR_ON, + MIPI_SEQ_TEAR_OFF, MIPI_SEQ_MAX }; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index d2cd8d5..9deaec3 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -251,7 +251,11 @@ static const char * const seq_name[] = { "MIPI_SEQ_INIT_OTP", "MIPI_SEQ_DISPLAY_ON", "MIPI_SEQ_DISPLAY_OFF", - "MIPI_SEQ_DEASSERT_RESET" + "MIPI_SEQ_DEASSERT_RESET", + "MIPI_SEQ_BACKLIGHT_ON", + "MIPI_SEQ_BACKLIGHT_OFF", + "MIPI_SEQ_TEAR_ON", + "MIPI_SEQ_TEAR_OFF" }; static void generic_exec_sequence(struct intel_dsi *intel_dsi, const u8 *data) @@ -306,6 +310,11 @@ static int vbt_panel_prepare(struct drm_panel *panel) sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP]; generic_exec_sequence(intel_dsi, sequence); + if (intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE) { + sequence = dev_priv->vbt.dsi.sequence[MIPI_SEQ_TEAR_ON]; + generic_exec_sequence(intel_dsi, sequence); + } + return 0; } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 03/14] drm/i915: Add functions for dcs memory write cmd
Add functions for DCS memory write command. The mem write command to send fb data to panel is sent using this function. Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar Signed-off-by: Yogesh Mohan Marimuthu --- drivers/gpu/drm/i915/i915_reg.h |1 + drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_dsi.c | 44 ++ 3 files changed, 46 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 77055b9..464719b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4231,6 +4231,7 @@ enum skl_disp_power_wells { #define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */ #define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */ #define PIPECONF_INTERLACE_MODE_MASK (7 << 21) +#define PIPECONF_MIPI_DSR_ENABLE (1 << 20) #define PIPECONF_EDP_RR_MODE_SWITCH (1 << 20) #define PIPECONF_CXSR_DOWNCLOCK (1<<16) #define PIPECONF_EDP_RR_MODE_SWITCH_VLV (1 << 14) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 47bc729..7c59862 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1197,6 +1197,7 @@ void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port); /* intel_dsi.c */ void intel_dsi_init(struct drm_device *dev); +void intel_dsi_update_panel_fb(struct intel_encoder *encoder); /* intel_dvo.c */ void intel_dvo_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 2e3c801..7cedd63 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "i915_drv.h" #include "intel_drv.h" #include "intel_dsi.h" @@ -202,6 +203,41 @@ static struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, return host; } +int dsi_send_dcs_cmd(struct intel_dsi *intel_dsi, int channel, const u8 *data, +int len, bool pipe_render) +{ + struct drm_encoder *encoder = &intel_dsi->base.base; + struct drm_device *dev = encoder->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + enum port port; + u32 cmd_addr; + + for_each_dsi_port(port, intel_dsi->ports) { + if (I915_READ(MIPI_COMMAND_ADDRESS(port)) & COMMAND_VALID) + return -EBUSY; + + if ((I915_READ(PIPECONF(port)) & PIPECONF_MIPI_DSR_ENABLE) == 0) + return -EBUSY; + + if (!intel_dsi->cmd_buff) + return -ENOMEM; + + memcpy(intel_dsi->cmd_buff, data, len); + + cmd_addr = intel_dsi->cmd_buff_phy_addr & + COMMAND_MEM_ADDRESS_MASK; + cmd_addr |= COMMAND_VALID; + + if (pipe_render) + cmd_addr |= MEMORY_WRITE_DATA_FROM_PIPE_RENDERING; + + I915_WRITE(MIPI_COMMAND_LENGTH(port), len); + I915_WRITE(MIPI_COMMAND_ADDRESS(port), cmd_addr); + } + + return 0; +} + /* * send a video mode command * @@ -667,6 +703,14 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, pipe_config->port_clock = pclk; } +void intel_dsi_update_panel_fb(struct intel_encoder *encoder) +{ + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + unsigned char uc_data[] = {MIPI_DCS_WRITE_MEMORY_START}; + + dsi_send_dcs_cmd(intel_dsi, 0, uc_data, sizeof(uc_data), true); +} + static enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 04/14] drm/i915: Calculate bw timer for mipi DBI interface
This patch will calculate the bandwidth timer for MIPI DBI interface. If the BW timer value is available from VBT, then value from VBT will be used. Signed-off-by: Gaurav K Singh Signed-off-by: Yogesh Mohan Marimuthu --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 24 +++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 9deaec3..38de166 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -56,6 +56,11 @@ static inline struct vbt_panel *to_vbt_panel(struct drm_panel *panel) #define CLK_ZERO_CNT_MAX 0xFF #define TRAIL_CNT_MAX 0x1F +#define LP_HDR_FOOT_SIZE 6 +#define BW_LP_NUM_OF_PKT 16 +#define BW_LP_LOAD_SIZE252 +#define EXTRA_ONE_BYTE 1 + #define NS_KHZ_RATIO 100 #define GPI0_NC_0_HV_DDI0_HPD 0x4130 @@ -430,7 +435,6 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->turn_arnd_val = mipi_config->turn_around_timeout; intel_dsi->rst_timer_val = mipi_config->device_reset_timer; intel_dsi->init_count = mipi_config->master_init_timer; - intel_dsi->bw_timer = mipi_config->dbi_bw_timer; intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; @@ -588,6 +592,24 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) intel_dsi->dphy_reg = exit_zero_cnt << 24 | trail_cnt << 16 | clk_zero_cnt << 8 | prepare_cnt; + if (mipi_config->dbi_bw_timer) { + intel_dsi->bw_timer = mipi_config->dbi_bw_timer; + } else { + /* +* bw timer should be more than 16 longs packets containing +* 252 bytes + 2 blanking packets. +* bw timer = 16 long packets * (252 bytes payload for each +*long packet + 6 bytes for long packet header and +*footer) + 12 bytes for 2 blanking packets + 1 +*byte for having more of the above. +*/ + intel_dsi->bw_timer = DIV_ROUND_UP(BW_LP_NUM_OF_PKT * + (BW_LP_LOAD_SIZE + LP_HDR_FOOT_SIZE), + intel_dsi->lane_count); + + intel_dsi->bw_timer += (extra_byte_count + EXTRA_ONE_BYTE); + } + /* * LP to HS switch count = 4TLPX + PREP_COUNT * 2 + EXIT_ZERO_COUNT * 2 * + 10UI + Extra Byte Count -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [RFC 00/14] DSI Command mode(DBI mode) enabling on CHT
Hi, These set of patches are for enabling DSI command mode. Command Mode refers to an operation in which transactions primarily take the form of sending commands and data to a peripheral that incorporates a display controller. The display controller may include local registers and a frame buffer. The host processor indirectly controls activity at the peripheral by sending commands, parameters and data to the display controller. Sink refreshes from its local frame buffer. Image updates require Source to write new data into the frame buffer which Source sends in the form of command + payload. The command mode panel we have here is 1080 x 1920. For this panel, features like support of i2c transactions for sending backlight on sequence, VBT version 3 patches, GPIO configuration changes for CHT are required. The same will be added as part of different patch series. Floating the command mode patches separately to start with the initial review. Regards Gaurav Gaurav K Singh (14): drm/i915: allocate gem memory for mipi dbi cmd buffer drm/i915: Add support for TEAR ON Sequence drm/i915: Add functions for dcs memory write cmd drm/i915: Calculate bw timer for mipi DBI interface drm/i915: Use the bpp value wrt the pixel format drm/i915: Disable vlank interrupt for disabling MIPI cmd mode drm/i915: Disable MIPI display self refresh mode drm/i915: Disable Tearing effect trigger by GPIO pin drm/i915: Changes for command mode preparation drm/i915: Enable Tearing effect trigger by GPIO pin drm/i915: Enable MIPI display self refresh mode drm/i915: Generalize DSI enable function drm/i915: Reset the display hw if vid mode to cmd mode drm/i915: send one frame after enabling mipi cmd mode drivers/gpu/drm/i915/i915_drv.h|1 + drivers/gpu/drm/i915/i915_reg.h|1 + drivers/gpu/drm/i915/intel_bios.h |4 + drivers/gpu/drm/i915/intel_display.c | 155 drivers/gpu/drm/i915/intel_drv.h |7 ++ drivers/gpu/drm/i915/intel_dsi.c | 136 +--- drivers/gpu/drm/i915/intel_dsi.h |5 + drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 36 ++- 8 files changed, 311 insertions(+), 34 deletions(-) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Changes for calculating dsi clk for CHT
Depending on the correct refclk, n ,p for CHT, calculate the dsi clk during readout DSI HW state. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_pll.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 5e44c9b..c7d55e8 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -357,9 +357,17 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) u32 m = 0, p = 0; int refclk = 25000; int i; + u32 n = 1; + u32 m_start = 62; DRM_DEBUG_KMS("\n"); + if (IS_CHERRYVIEW(dev_priv->dev)) { + refclk = 10; + n = 4; + m_start = 70; + } + mutex_lock(&dev_priv->dpio_lock); pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER); @@ -394,9 +402,9 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) return 0; } - m = i + 62; + m = i + m_start; - dsi_clock = (m * refclk) / p; + dsi_clock = (m * refclk) / (p * n); /* pixel_format and pipe_bpp should agree */ assert_bpp_mismatch(intel_dsi->pixel_format, pipe_bpp); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Changes required to enable DSI Video Mode on CHT
On CHT, changes are required for calculating the correct m,n & p with minimal error +/- for the required DSI clock, so that the correct dividor & ctrl values are written in cck regs for DSI. This patch has been tested on CHT RVP with 1200 x 1920 panel. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_pll.c | 43 ++ 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 3622d0b..b7a94c2 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -162,7 +162,8 @@ static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count) #endif -static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) +static int dsi_calc_mnp(struct drm_i915_private *dev_priv, + u32 dsi_clk, struct dsi_mnp *dsi_mnp) { u32 m, n, p; u32 ref_clk; @@ -173,6 +174,10 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) u32 calc_m; u32 calc_p; u32 m_seed; + u32 m_start; + u32 m_limit; + u32 n_limit; + u32 p_limit; /* dsi_clk is expected in KHZ */ if (dsi_clk < 30 || dsi_clk > 115) { @@ -180,18 +185,33 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) return -ECHRNG; } - ref_clk = 25000; + if (IS_CHERRYVIEW(dev_priv->dev)) { + ref_clk = 10; + m_start = 70; + m_limit = 96; + n_limit = 4; + p_limit = 6; + } else if (IS_VALLEYVIEW(dev_priv->dev)) { + ref_clk = 25000; + m_start = 62; + m_limit = 92; + n_limit = 1; + p_limit = 6; + } else { + DRM_ERROR("Unsupported device\n"); + return -ENODEV; + } target_dsi_clk = dsi_clk; error = 0x; tmp_error = 0x; calc_m = 0; calc_p = 0; - for (m = 62; m <= 92; m++) { - for (p = 2; p <= 6; p++) { + for (m = m_start; m <= m_limit; m++) { + for (p = 2; p <= p_limit; p++) { /* Find the optimal m and p divisors with minimal error +/- the required clock */ - calc_dsi_clk = (m * ref_clk) / p; + calc_dsi_clk = (m * ref_clk) / (p * n_limit); if (calc_dsi_clk == target_dsi_clk) { calc_m = m; calc_p = p; @@ -212,11 +232,14 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) } m_seed = lfsr_converts[calc_m - 62]; - n = 1; + n = n_limit; dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2); - dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT | - m_seed << DSI_PLL_M1_DIV_SHIFT; - + if (IS_CHERRYVIEW(dev_priv->dev)) + dsi_mnp->dsi_pll_div = (n/2) << DSI_PLL_N1_DIV_SHIFT | + m_seed << DSI_PLL_M1_DIV_SHIFT; + else + dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT | + m_seed << DSI_PLL_M1_DIV_SHIFT; return 0; } @@ -235,7 +258,7 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder) dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format, intel_dsi->lane_count); - ret = dsi_calc_mnp(dsi_clk, &dsi_mnp); + ret = dsi_calc_mnp(dev_priv, dsi_clk, &dsi_mnp); if (ret) { DRM_DEBUG_KMS("dsi_calc_mnp failed\n"); return; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Support for higher DSI clk
For MIPI panels requiring higher DSI clk, values needs to be added in lfsr_converts table for getting the correct values of pll ctrl and dividor values which gets programmed in cck regs, otherwise DSI PLL does not get locked leading to no display on the MIPI panel. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_pll.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 3622d0b..471336d 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -46,8 +46,8 @@ struct dsi_mnp { static const u32 lfsr_converts[] = { 426, 469, 234, 373, 442, 221, 110, 311, 411,/* 62 - 70 */ 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */ - 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */ - 71, 35 /* 91 - 92 */ + 106, 53, 282, 397, 454, 227, 113, 56, 284, 142, /* 81 - 90 */ + 71, 35, 273, 136, 324, 418, 465, 488, 500, 506 /* 91 - 100 */ }; #ifdef DSI_CLK_FROM_RR -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/4] drm/i915: Changes related to the sequence port no for
From now on for both DSI Ports A & C, the seq_port value has been set to 0. seq_port value is parsed from Sequence block#53 of VBT. So, for packets that needs to be read/write for DSI single link on Port A and Port C will now be based on the DVO port from VBT block 2, instead of seq_port. Signed-off-by: Gaurav K Singh Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index f8c2269..5493aef 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -110,7 +110,15 @@ static u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, u8 *data) vc = (byte >> MIPI_VIRTUAL_CHANNEL_SHIFT) & 0x3; seq_port = (byte >> MIPI_PORT_SHIFT) & 0x3; - port = intel_dsi_seq_port_to_port(seq_port); + /* For DSI single link on Port A & C, the seq_port value which is +* parsed from Sequence Block#53 of VBT has been set to 0 +* Now, read/write of packets for the DSI single link on Port A and +* Port C will based on the DVO port from VBT block 2. +*/ + if (intel_dsi->ports == (1 << PORT_C)) + port = PORT_C; + else + port = intel_dsi_seq_port_to_port(seq_port); /* LP or HS mode */ intel_dsi->hs = mode; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Changes required to enable DSI Video Mode on CHT
For CHT changes are required for calculating the correct m,n & p with minimal error +/- for the required DSI clock, so that the correct dividor & ctrl values are written in cck regs for DSI. This patch has been tested on CHT RVP with 1200 x 1920 panel. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_pll.c | 43 ++ 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 8957f10..9236b66 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -162,7 +162,8 @@ static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count) #endif -static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) +static int dsi_calc_mnp(struct drm_i915_private *dev_priv, + u32 dsi_clk, struct dsi_mnp *dsi_mnp) { u32 m, n, p; u32 ref_clk; @@ -173,6 +174,10 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) u32 calc_m; u32 calc_p; u32 m_seed; + u32 m_start; + u32 m_limit; + u32 n_limit; + u32 p_limit; /* dsi_clk is expected in KHZ */ if (dsi_clk < 30 || dsi_clk > 115) { @@ -180,18 +185,33 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) return -ECHRNG; } - ref_clk = 25000; + if (IS_CHERRYVIEW(dev_priv->dev)) { + ref_clk = 10; + m_start = 70; + m_limit = 96; + n_limit = 4; + p_limit = 6; + } else if (IS_VALLEYVIEW(dev_priv->dev)) { + ref_clk = 25000; + m_start = 62; + m_limit = 92; + n_limit = 1; + p_limit = 6; + } else { + DRM_ERROR("Unsupported device\n"); + return -ENODEV; + } target_dsi_clk = dsi_clk; error = 0x; tmp_error = 0x; calc_m = 0; calc_p = 0; - for (m = 62; m <= 92; m++) { - for (p = 2; p <= 6; p++) { + for (m = m_start; m <= m_limit; m++) { + for (p = 2; p <= p_limit; p++) { /* Find the optimal m and p divisors with minimal error +/- the required clock */ - calc_dsi_clk = (m * ref_clk) / p; + calc_dsi_clk = (m * ref_clk) / (p * n_limit); if (calc_dsi_clk == target_dsi_clk) { calc_m = m; calc_p = p; @@ -212,11 +232,14 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) } m_seed = lfsr_converts[calc_m - 62]; - n = 1; + n = n_limit; dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2); - dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT | - m_seed << DSI_PLL_M1_DIV_SHIFT; - + if (IS_CHERRYVIEW(dev_priv->dev)) + dsi_mnp->dsi_pll_div = (n/2) << DSI_PLL_N1_DIV_SHIFT | + m_seed << DSI_PLL_M1_DIV_SHIFT; + else + dsi_mnp->dsi_pll_div = (n - 1) << DSI_PLL_N1_DIV_SHIFT | + m_seed << DSI_PLL_M1_DIV_SHIFT; return 0; } @@ -235,7 +258,7 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder) dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format, intel_dsi->lane_count); - ret = dsi_calc_mnp(dsi_clk, &dsi_mnp); + ret = dsi_calc_mnp(dev_priv, dsi_clk, &dsi_mnp); if (ret) { DRM_DEBUG_KMS("dsi_calc_mnp failed\n"); return; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/4] drm/i915: Software workaround for getting the HW status of DSI Port C on BYT
Due to hardware limitations on BYT, MIPI Port C DPI Enable bit does not get set. To check whether DSI Port C was enabled in BIOS, check the Pipe B enable bit for DSI Port C. In hardware, DSI Port C is linked with Pipe B. v2: Addressed review comments of Jani, Nikula - Used platform checks for this software workaround for BYT Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi.c | 22 +- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 215d004..42b6d6f 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -398,8 +398,10 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct drm_device *dev = encoder->base.dev; enum intel_display_power_domain power_domain; - u32 port_ctl, func; + u32 dpi_enabled, func; enum port port; DRM_DEBUG_KMS("\n"); @@ -409,13 +411,23 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, return false; /* XXX: this only works for one DSI output */ - for_each_dsi_port(port, (1 << PORT_A) | (1 << PORT_C)) { - port_ctl = I915_READ(MIPI_PORT_CTRL(port)); + for_each_dsi_port(port, intel_dsi->ports) { func = I915_READ(MIPI_DSI_FUNC_PRG(port)); + dpi_enabled = I915_READ(MIPI_PORT_CTRL(port)) & + DPI_ENABLE; + + /* Due to some hardware limitations on BYT, MIPI Port C DPI +* Enable bit does not get set. To check whether DSI Port C +* was enabled in BIOS, check the Pipe B enable bit +*/ + if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) && + (port == PORT_C)) + dpi_enabled = I915_READ(PIPECONF(PIPE_B)) & + PIPECONF_ENABLE; - if ((port_ctl & DPI_ENABLE) || (func & CMD_MODE_DATA_WIDTH_MASK)) { + if (dpi_enabled || (func & CMD_MODE_DATA_WIDTH_MASK)) { if (I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY) { - *pipe = port == PORT_A ? PIPE_A : PIPE_C; + *pipe = port == PORT_A ? PIPE_A : PIPE_B; return true; } } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/4] drm/i915: Use DSI Pll1 for enabling MIPI DSI on Port C
DSI Pll1 is used for enabling DSI on Port C. v2: Addressed review comments of Jani - Used & operator instead of == for intel_dsi->ports Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_pll.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 8957f10..3622d0b 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -241,9 +241,10 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder) return; } - dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL; + if (intel_dsi->ports & (1 << PORT_A)) + dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL; - if (intel_dsi->dual_link) + if (intel_dsi->ports & (1 << PORT_C)) dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL; DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n", -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Use DSI Pll1 for enabling MIPI DSI on Port C
DSI Pll1 is used for enabling DSI on Port C. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_pll.c |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 8957f10..9b7f6a5 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -241,9 +241,12 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder) return; } - dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL; + if ((intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) || + (intel_dsi->ports == (1 << PORT_A))) + dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL; - if (intel_dsi->dual_link) + if ((intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) || + (intel_dsi->ports == (1 << PORT_C))) dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL; DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n", -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/4] drm/i915: DSI sequence related changes for DSI Port C
For DSI Port A & C, the seq_port value has been set to 0 now in VBT Now the sequence of DSI single link on Port A and Port C will based on the DVO port from VBT block 2. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index f8c2269..e7e2e52 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -110,7 +110,14 @@ static u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, u8 *data) vc = (byte >> MIPI_VIRTUAL_CHANNEL_SHIFT) & 0x3; seq_port = (byte >> MIPI_PORT_SHIFT) & 0x3; - port = intel_dsi_seq_port_to_port(seq_port); + /* For DSI Port A & C, the seq_port value has been set to 0 now in VBT +* Now the sequence of DSI single link on Port A and Port C will based +* on the DVO port from VBT block 2. +*/ + if (intel_dsi->ports == (1 << PORT_C)) + port = PORT_C; + else + port = intel_dsi_seq_port_to_port(seq_port); /* LP or HS mode */ intel_dsi->hs = mode; -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/4] drm/i915: Enable MIPI PHY transparent latch for DSI Port C
Common bit to be used for both DSI Port A & DSI Port C. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi.c |7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 8f8b952..215d004 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -177,7 +177,12 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) usleep_range(2500, 3000); val = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD); + + /* Enable MIPI PHY transparent latch +* Common bit for both MIPI Port A & MIPI Port C +* No similar bit in MIPI Port C reg +*/ + I915_WRITE(MIPI_PORT_CTRL(PORT_A), val | LP_OUTPUT_HOLD); usleep_range(1000, 1500); I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/4] drm/i915: Use DSI Pll1 for enabling MIPI DSI on Port C
DSI Pll1 is used for enabling DSI on Port C. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_pll.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 8957f10..74a6fb5 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -243,7 +243,8 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder) dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL; - if (intel_dsi->dual_link) + if ((intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) || + (intel_dsi->ports == (1 << PORT_C))) dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL; DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n", -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/4] drm/i915: Get HW state changes required for DSI port C
Due to some hardware limitations, MIPI Port C DPI Enable bit does not get set. To check whether DSI Port C was enabled in BIOS, check the Pipe B enable bit for DSI Port C. In hardware, DSI Port C is linked with Pipe B. Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi.c | 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 215d004..0334c4d 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -398,8 +398,9 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum intel_display_power_domain power_domain; - u32 port_ctl, func; + u32 dsi_status, func; enum port port; DRM_DEBUG_KMS("\n"); @@ -409,13 +410,23 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, return false; /* XXX: this only works for one DSI output */ - for_each_dsi_port(port, (1 << PORT_A) | (1 << PORT_C)) { - port_ctl = I915_READ(MIPI_PORT_CTRL(port)); + for_each_dsi_port(port, intel_dsi->ports) { func = I915_READ(MIPI_DSI_FUNC_PRG(port)); - if ((port_ctl & DPI_ENABLE) || (func & CMD_MODE_DATA_WIDTH_MASK)) { + /* Due to some hardware limitations, MIPI Port C DPI Enable +* bit does not get set. To check whether DSI Port C was +* enabled in BIOS, check the Pipe B enable bit +*/ + if (port == PORT_C) + dsi_status = I915_READ(PIPECONF(PIPE_B)) & + PIPECONF_ENABLE; + else + dsi_status = I915_READ(MIPI_PORT_CTRL(port)) & + DPI_ENABLE; + + if (dsi_status || (func & CMD_MODE_DATA_WIDTH_MASK)) { if (I915_READ(MIPI_DEVICE_READY(port)) & DEVICE_READY) { - *pipe = port == PORT_A ? PIPE_A : PIPE_C; + *pipe = port == PORT_A ? PIPE_A : PIPE_B; return true; } } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/4] BYT DSI Enable on Port C
Hi, These set of patches build on top of the existing DSI Video mode support to enable DSI on Port C. These patches have been tested on a 1920 x 1200 panel on Port C. Regards Gaurav Gaurav K Singh (4): drm/i915: Use DSI Pll1 for enabling MIPI DSI on Port C drm/i915: DSI sequence related changes for DSI Port C drm/i915: Enable MIPI PHY transparent latch for DSI Port C drm/i915: Get HW state changes required for DSI port C drivers/gpu/drm/i915/intel_dsi.c | 28 ++-- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |9 - drivers/gpu/drm/i915/intel_dsi_pll.c |3 ++- 3 files changed, 32 insertions(+), 8 deletions(-) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/10] drm/i915: Update the DSI enable path to support dual
We need to program both port registers during dual link enable path. v2: Address review comments by Jani - Used a for loop instead of do-while loop. v3: Used for_each_dsi_port macro instead of for loop v4: Renamed mode_hactive variable to mode_hdisplay Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.c | 244 +- 1 file changed, 134 insertions(+), 110 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 8054928..84e0231 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -156,8 +156,8 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder) static void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; u32 val; DRM_DEBUG_KMS("\n"); @@ -171,18 +171,21 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) /* bandgap reset is needed after everytime we do power gate */ band_gap_reset(dev_priv); - I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER); - usleep_range(2500, 3000); + for_each_dsi_port(port, intel_dsi->ports) { - val = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD); - usleep_range(1000, 1500); + I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER); + usleep_range(2500, 3000); - I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT); - usleep_range(2500, 3000); + val = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD); + usleep_range(1000, 1500); - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY); - usleep_range(2500, 3000); + I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT); + usleep_range(2500, 3000); + + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY); + usleep_range(2500, 3000); + } } static void intel_dsi_enable(struct intel_encoder *encoder) @@ -547,32 +550,43 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct drm_display_mode *adjusted_mode = &intel_crtc->config.adjusted_mode; - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; unsigned int bpp = intel_crtc->config.pipe_bpp; u32 val, tmp; + u16 mode_hdisplay; DRM_DEBUG_KMS("pipe %c\n", pipe_name(intel_crtc->pipe)); - /* escape clock divider, 20MHz, shared for A and C. device ready must be -* off when doing this! txclkesc? */ - tmp = I915_READ(MIPI_CTRL(PORT_A)); - tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK; - I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1); - - /* read request priority is per pipe */ - tmp = I915_READ(MIPI_CTRL(port)); - tmp &= ~READ_REQUEST_PRIORITY_MASK; - I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH); + mode_hdisplay = adjusted_mode->hdisplay; - /* XXX: why here, why like this? handling in irq handler?! */ - I915_WRITE(MIPI_INTR_STAT(port), 0x); - I915_WRITE(MIPI_INTR_EN(port), 0x); - - I915_WRITE(MIPI_DPHY_PARAM(port), intel_dsi->dphy_reg); + if (intel_dsi->dual_link) { + mode_hdisplay /= 2; + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) + mode_hdisplay += intel_dsi->pixel_overlap; + } - I915_WRITE(MIPI_DPI_RESOLUTION(port), - adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT | - adjusted_mode->hdisplay << HORIZONTAL_ADDRESS_SHIFT); + for_each_dsi_port(port, intel_dsi->ports) { + /* escape clock divider, 20MHz, shared for A and C. +* device ready must be off when doing this! txclkesc? */ + tmp = I915_READ(MIPI_CTRL(PORT_A)); + tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK; + I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1); + + /* read request priority is per pipe */ + tmp = I915_READ(MIPI_CTRL(port)); + tmp &= ~READ_REQUEST_PRIORITY_MASK; + I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH); + + /* XXX: why here, why like this? handling in irq handler?! */ +
[Intel-gfx] [PATCH 5/5] drm/i915: Dual link needs Shutdown and Turn on packet for both ports
For dual link MIPI panels, SHUTDOWN packet needs to send to both Ports A & C during MIPI encoder disabling sequence. Similarly, TURN ON packet to be sent to both Ports during MIPI encoder enabling sequence. v2: Address review comments by Jani - Used a for loop instead of do-while loop. v3: Used for_each_dsi_port macro instead of for loop Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi_cmd.c | 26 +++--- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c index 8e30684..e97fb6a 100644 --- a/drivers/gpu/drm/i915/intel_dsi_cmd.c +++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c @@ -385,8 +385,7 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs) struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; u32 mask; /* XXX: pipe, hs */ @@ -395,18 +394,23 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs) else cmd |= DPI_LP_MODE; - /* clear bit */ - I915_WRITE(MIPI_INTR_STAT(port), SPL_PKT_SENT_INTERRUPT); + for_each_dsi_port(port, intel_dsi->ports) { + /* clear bit */ + I915_WRITE(MIPI_INTR_STAT(port), SPL_PKT_SENT_INTERRUPT); - /* XXX: old code skips write if control unchanged */ - if (cmd == I915_READ(MIPI_DPI_CONTROL(port))) - DRM_ERROR("Same special packet %02x twice in a row.\n", cmd); + /* XXX: old code skips write if control unchanged */ + if (cmd == I915_READ(MIPI_DPI_CONTROL(port))) + DRM_ERROR("Same special packet %02x twice in a row.\n", + cmd); - I915_WRITE(MIPI_DPI_CONTROL(port), cmd); + I915_WRITE(MIPI_DPI_CONTROL(port), cmd); - mask = SPL_PKT_SENT_INTERRUPT; - if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, 100)) - DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd); + mask = SPL_PKT_SENT_INTERRUPT; + if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, +100)) + DRM_ERROR("Video mode command 0x%08x send failed.\n", + cmd); + } return 0; } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 10/10] drm/i915: Update the DSI enable path to support dual
We need to program both port registers during dual link enable path. v2: Address review comments by Jani - Used a for loop instead of do-while loop. v3: Used for_each_dsi_port macro instead of for loop v4: Renamed mode_hactive variable to mode_hdisplay Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.c | 241 +- 1 file changed, 131 insertions(+), 110 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 8054928..8f8b952 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -156,8 +156,8 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder) static void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; u32 val; DRM_DEBUG_KMS("\n"); @@ -171,18 +171,21 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) /* bandgap reset is needed after everytime we do power gate */ band_gap_reset(dev_priv); - I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER); - usleep_range(2500, 3000); + for_each_dsi_port(port, intel_dsi->ports) { - val = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD); - usleep_range(1000, 1500); + I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER); + usleep_range(2500, 3000); - I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT); - usleep_range(2500, 3000); + val = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD); + usleep_range(1000, 1500); - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY); - usleep_range(2500, 3000); + I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT); + usleep_range(2500, 3000); + + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY); + usleep_range(2500, 3000); + } } static void intel_dsi_enable(struct intel_encoder *encoder) @@ -547,32 +550,43 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct drm_display_mode *adjusted_mode = &intel_crtc->config.adjusted_mode; - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; unsigned int bpp = intel_crtc->config.pipe_bpp; u32 val, tmp; + u16 mode_hdisplay; DRM_DEBUG_KMS("pipe %c\n", pipe_name(intel_crtc->pipe)); - /* escape clock divider, 20MHz, shared for A and C. device ready must be -* off when doing this! txclkesc? */ - tmp = I915_READ(MIPI_CTRL(PORT_A)); - tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK; - I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1); - - /* read request priority is per pipe */ - tmp = I915_READ(MIPI_CTRL(port)); - tmp &= ~READ_REQUEST_PRIORITY_MASK; - I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH); + mode_hdisplay = adjusted_mode->hdisplay; - /* XXX: why here, why like this? handling in irq handler?! */ - I915_WRITE(MIPI_INTR_STAT(port), 0x); - I915_WRITE(MIPI_INTR_EN(port), 0x); - - I915_WRITE(MIPI_DPHY_PARAM(port), intel_dsi->dphy_reg); + if (intel_dsi->dual_link) { + mode_hdisplay /= 2; + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) + mode_hdisplay += intel_dsi->pixel_overlap; + } - I915_WRITE(MIPI_DPI_RESOLUTION(port), - adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT | - adjusted_mode->hdisplay << HORIZONTAL_ADDRESS_SHIFT); + for_each_dsi_port(port, intel_dsi->ports) { + /* escape clock divider, 20MHz, shared for A and C. +* device ready must be off when doing this! txclkesc? */ + tmp = I915_READ(MIPI_CTRL(PORT_A)); + tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK; + I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1); + + /* read request priority is per pipe */ + tmp = I915_READ(MIPI_CTRL(port)); + tmp &= ~READ_REQUEST_PRIORITY_MASK; + I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH); + + /* XXX: why here, why like this? handling in irq handler?! */ +
[Intel-gfx] [PATCH v4 09/10] drm/i915: Update the DSI disable path to support dual link panel disabling
We need to program both port registers during dual link disable path. v2: Address review comments by Jani - Used a for loop instead of do-while loop. v3: Used for_each_dsi_port macro instead of for loop v4: Added comments for the usage of AFE latchout bit Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.c | 83 +- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 585538b..8054928 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -281,9 +281,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; u32 temp; DRM_DEBUG_KMS("\n"); @@ -295,23 +294,24 @@ static void intel_dsi_disable(struct intel_encoder *encoder) msleep(2); } - /* Panel commands can be sent when clock is in LP11 */ - I915_WRITE(MIPI_DEVICE_READY(port), 0x0); - - temp = I915_READ(MIPI_CTRL(port)); - temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; - I915_WRITE(MIPI_CTRL(port), temp | - intel_dsi->escape_clk_div << - ESCAPE_CLOCK_DIVIDER_SHIFT); + for_each_dsi_port(port, intel_dsi->ports) { + /* Panel commands can be sent when clock is in LP11 */ + I915_WRITE(MIPI_DEVICE_READY(port), 0x0); - I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP); + temp = I915_READ(MIPI_CTRL(port)); + temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; + I915_WRITE(MIPI_CTRL(port), temp | + intel_dsi->escape_clk_div << + ESCAPE_CLOCK_DIVIDER_SHIFT); - temp = I915_READ(MIPI_DSI_FUNC_PRG(port)); - temp &= ~VID_MODE_FORMAT_MASK; - I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp); + I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP); - I915_WRITE(MIPI_DEVICE_READY(port), 0x1); + temp = I915_READ(MIPI_DSI_FUNC_PRG(port)); + temp &= ~VID_MODE_FORMAT_MASK; + I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp); + I915_WRITE(MIPI_DEVICE_READY(port), 0x1); + } /* if disable packets are sent before sending shutdown packet then in * some next enable sequence send turn on packet error is observed */ if (intel_dsi->dev.dev_ops->disable) @@ -323,31 +323,42 @@ static void intel_dsi_disable(struct intel_encoder *encoder) static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; u32 val; DRM_DEBUG_KMS("\n"); + for_each_dsi_port(port, intel_dsi->ports) { - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | ULPS_STATE_ENTER); - usleep_range(2000, 2500); - - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | ULPS_STATE_EXIT); - usleep_range(2000, 2500); - - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | ULPS_STATE_ENTER); - usleep_range(2000, 2500); - - if (wait_for(((I915_READ(MIPI_PORT_CTRL(port)) & AFE_LATCHOUT) - == 0x0), 30)) - DRM_ERROR("DSI LP not going Low\n"); - - val = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), val & ~LP_OUTPUT_HOLD); - usleep_range(1000, 1500); - - I915_WRITE(MIPI_DEVICE_READY(port), 0x00); - usleep_range(2000, 2500); + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | + ULPS_STATE_ENTER); + usleep_range(2000, 2500); + + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | + ULPS_STATE_EXIT); + usleep_range(2000, 2500); + + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | + ULPS_STATE_ENTER); + usleep_range(2000, 2500); + + /* Wait till Clock lanes are in LP-00 state for MIPI Port A +* only. MIPI Port C has no si
[Intel-gfx] [PATCH v2 07/10] drm/i915: cck reg used for checking DSI Pll locked
Instead of pipe configuration reg, cck reg to be used for checking whether DSI Pll is getting locked or not. v2: dpio_lock unlocked now in case DSI PLL lock fails Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi_pll.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 636d72f..8957f10 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -272,12 +272,14 @@ void vlv_enable_dsi_pll(struct intel_encoder *encoder) tmp |= DSI_PLL_VCO_EN; vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp); - mutex_unlock(&dev_priv->dpio_lock); + if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) & + DSI_PLL_LOCK, 20)) { - if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED, 20)) { + mutex_unlock(&dev_priv->dpio_lock); DRM_ERROR("DSI PLL lock failed\n"); return; } + mutex_unlock(&dev_priv->dpio_lock); DRM_DEBUG_KMS("DSI PLL locked\n"); } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 04/10] drm/i915: Pixel Clock changes for DSI dual link
For dual link MIPI Panels, each port needs half of pixel clock. Pixel overlap can be enabled if needed by panel, then in that case, pixel clock will be increased for extra pixels. v2 : Address review comments by Jani - Removed the bit mask used for ->dual_link - Used DSI instead of MIPI for #define variables v3: Added the VLV_DISPLAY_BASE to VLV_CHICKEN_3 register Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h|4 drivers/gpu/drm/i915/intel_bios.h |3 ++- drivers/gpu/drm/i915/intel_dsi.c |8 drivers/gpu/drm/i915/intel_dsi.h |6 ++ drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 21 + 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c981f5d..92dd142 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6029,6 +6029,10 @@ enum punit_power_well { #define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31) #define VLV_PWRDWNUPCTL0xA294 +#define VLV_CHICKEN_3 (VLV_DISPLAY_BASE + 0x7040C) +#define PIXEL_OVERLAP_CNT_MASK(3 << 30) +#define PIXEL_OVERLAP_CNT_SHIFT 30 + #define GEN6_PMISR 0x44020 #define GEN6_PMIMR 0x44024 /* rps_lock */ #define GEN6_PMIIR 0x44028 diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index de01167..a6a8710 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -818,7 +818,8 @@ struct mipi_config { #define DUAL_LINK_PIXEL_ALT2 u16 dual_link:2; u16 lane_cnt:2; - u16 rsvd3:12; + u16 pixel_overlap:3; + u16 rsvd3:9; u16 rsvd4; diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index fd4d397..a1b93c5 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -111,6 +111,14 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) enum port port; u32 temp; + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { + temp = I915_READ(VLV_CHICKEN_3); + temp &= ~PIXEL_OVERLAP_CNT_MASK | + intel_dsi->pixel_overlap << + PIXEL_OVERLAP_CNT_SHIFT; + I915_WRITE(VLV_CHICKEN_3, temp); + } + for_each_dsi_port(port, intel_dsi->ports) { temp = I915_READ(MIPI_PORT_CTRL(port)); temp &= ~LANE_CONFIGURATION_MASK; diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index f2cc2fc..8fe2064 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -28,6 +28,11 @@ #include #include "intel_drv.h" +/* Dual Link support */ +#define DSI_DUAL_LINK_NONE 0 +#define DSI_DUAL_LINK_FRONT_BACK 1 +#define DSI_DUAL_LINK_PIXEL_ALT2 + struct intel_dsi_device { unsigned int panel_id; const char *name; @@ -105,6 +110,7 @@ struct intel_dsi { u8 escape_clk_div; u8 dual_link; + u8 pixel_overlap; u32 port_bits; u32 bw_timer; u32 dphy_reg; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index f60146f..f8c2269 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -288,6 +288,7 @@ static bool generic_init(struct intel_dsi_device *dsi) intel_dsi->lane_count = mipi_config->lane_cnt + 1; intel_dsi->pixel_format = mipi_config->videomode_color_format << 7; intel_dsi->dual_link = mipi_config->dual_link; + intel_dsi->pixel_overlap = mipi_config->pixel_overlap; if (intel_dsi->dual_link) intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C)); @@ -310,6 +311,20 @@ static bool generic_init(struct intel_dsi_device *dsi) pclk = mode->clock; + /* In dual link mode each port needs half of pixel clock */ + if (intel_dsi->dual_link) { + pclk = pclk / 2; + + /* we can enable pixel_overlap if needed by panel. In this +* case we need to increase the pixelclock for extra pixels +*/ + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { + pclk += DIV_ROUND_UP(mode->vtotal * + intel_dsi->pixel_overlap * + 60, 1000); + } + } + /* Burst Mode Ratio
[Intel-gfx] [PATCH v4 03/10] drm/i915: Add support for port enable/disable for dual link configuration
For Dual Link MIPI Panels, both Port A and Port C should be enabled during the MIPI encoder enabling sequence. Similarly, during the disabling sequence, both ports needs to be disabled. v2: Used for_each_dsi_port macro instead of for loop v3: Used intel_dsi->ports instead of dual_link var for dual link configuration check v4: Masking of the required MIPI port bits before writing proper values Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h|1 + drivers/gpu/drm/i915/intel_dsi.c | 37 +++- drivers/gpu/drm/i915/intel_dsi.h |1 + drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |4 +++ 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index dc03fac..c981f5d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6664,6 +6664,7 @@ enum punit_power_well { #define DPI_ENABLE(1 << 31) /* A + C */ #define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27 #define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27) +#define DUAL_LINK_MODE_SHIFT 26 #define DUAL_LINK_MODE_MASK (1 << 26) #define DUAL_LINK_MODE_FRONT_BACK (0 << 26) #define DUAL_LINK_MODE_PIXEL_ALTERNATIVE (1 << 26) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 693736b..fd4d397 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -108,28 +108,41 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; u32 temp; - /* assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)) & ~LANE_CONFIGURATION_MASK; - temp = temp | intel_dsi->port_bits; - I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); - POSTING_READ(MIPI_PORT_CTRL(port)); + for_each_dsi_port(port, intel_dsi->ports) { + temp = I915_READ(MIPI_PORT_CTRL(port)); + temp &= ~LANE_CONFIGURATION_MASK; + temp &= ~DUAL_LINK_MODE_MASK; + + if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) { + temp |= (intel_dsi->dual_link - 1) + << DUAL_LINK_MODE_SHIFT; + temp |= intel_crtc->pipe ? + LANE_CONFIGURATION_DUAL_LINK_B : + LANE_CONFIGURATION_DUAL_LINK_A; + } + /* assert ip_tg_enable signal */ + I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); + POSTING_READ(MIPI_PORT_CTRL(port)); + } } static void intel_dsi_port_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; u32 temp; - /* de-assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); - POSTING_READ(MIPI_PORT_CTRL(port)); + for_each_dsi_port(port, intel_dsi->ports) { + /* de-assert ip_tg_enable signal */ + temp = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); + POSTING_READ(MIPI_PORT_CTRL(port)); + } } static void intel_dsi_device_ready(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 7f5d028..f2cc2fc 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -104,6 +104,7 @@ struct intel_dsi { u8 clock_stop; u8 escape_clk_div; + u8 dual_link; u32 port_bits; u32 bw_timer; u32 dphy_reg; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 7766c42..f60146f 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -287,6 +287,10 @@ static bool generic_init(struct intel_dsi_device *dsi) intel_dsi->clock_stop = m
[Intel-gfx] [PATCH 09/10] drm/i915: Update the DSI disable path to support dual link panel disabling
We need to program both port registers during dual link disable path. v2: Address review comments by Jani - Used a for loop instead of do-while loop. v3: Used for_each_dsi_port macro instead of for loop Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 67 -- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 22b1570..5ae4015 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -281,9 +281,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; u32 temp; DRM_DEBUG_KMS("\n"); @@ -295,23 +294,24 @@ static void intel_dsi_disable(struct intel_encoder *encoder) msleep(2); } - /* Panel commands can be sent when clock is in LP11 */ - I915_WRITE(MIPI_DEVICE_READY(port), 0x0); - - temp = I915_READ(MIPI_CTRL(port)); - temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; - I915_WRITE(MIPI_CTRL(port), temp | - intel_dsi->escape_clk_div << - ESCAPE_CLOCK_DIVIDER_SHIFT); + for_each_dsi_port(port, intel_dsi->ports) { + /* Panel commands can be sent when clock is in LP11 */ + I915_WRITE(MIPI_DEVICE_READY(port), 0x0); - I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP); + temp = I915_READ(MIPI_CTRL(port)); + temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; + I915_WRITE(MIPI_CTRL(port), temp | + intel_dsi->escape_clk_div << + ESCAPE_CLOCK_DIVIDER_SHIFT); - temp = I915_READ(MIPI_DSI_FUNC_PRG(port)); - temp &= ~VID_MODE_FORMAT_MASK; - I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp); + I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP); - I915_WRITE(MIPI_DEVICE_READY(port), 0x1); + temp = I915_READ(MIPI_DSI_FUNC_PRG(port)); + temp &= ~VID_MODE_FORMAT_MASK; + I915_WRITE(MIPI_DSI_FUNC_PRG(port), temp); + I915_WRITE(MIPI_DEVICE_READY(port), 0x1); + } /* if disable packets are sent before sending shutdown packet then in * some next enable sequence send turn on packet error is observed */ if (intel_dsi->dev.dev_ops->disable) @@ -323,31 +323,36 @@ static void intel_dsi_disable(struct intel_encoder *encoder) static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; u32 val; DRM_DEBUG_KMS("\n"); + for_each_dsi_port(port, intel_dsi->ports) { - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | ULPS_STATE_ENTER); - usleep_range(2000, 2500); + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | + ULPS_STATE_ENTER); + usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | ULPS_STATE_EXIT); - usleep_range(2000, 2500); + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | + ULPS_STATE_EXIT); + usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | ULPS_STATE_ENTER); - usleep_range(2000, 2500); + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY | + ULPS_STATE_ENTER); + usleep_range(2000, 2500); - if (wait_for(((I915_READ(MIPI_PORT_CTRL(port)) & AFE_LATCHOUT) - == 0x0), 30)) - DRM_ERROR("DSI LP not going Low\n"); + if (wait_for(((I915_READ(MIPI_PORT_CTRL(PORT_A)) & AFE_LATCHOUT) + == 0x0), 30)) + DRM_ERROR("DSI LP not going Low\n"); - val = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), val & ~LP_OUTPUT_HOLD); - usleep_range(1000, 1500); + val = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), val & ~LP_
[Intel-gfx] [PATCH 06/10] drm/i915: Enable DSI PLL for both DSI0 and DSI1 in case of dual link
For Dual link MIPI Panels, dsipll clock for both DSI0 and DSI1 needs to be enabled. v2: Address review comments by Jani - Added wait time for PLL to be locked. v3: separate patch created for cck read for checking PLL to be locked Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi_pll.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index fa7a6ca..636d72f 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -243,6 +243,9 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder) dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL; + if (intel_dsi->dual_link) + dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL; + DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n", dsi_mnp.dsi_pll_div, dsi_mnp.dsi_pll_ctrl); -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/10] drm/i915: Added port as parameter to the functions which does read/write of DSI Controller
This patch is in preparation of DSI dual link panels. For dual link panels, few packets needs to be sent to Port A or Port C or both. Based on the portno from MIPI Sequence Block#53, these sequences needs to be sent accordingly. v2: Addressed review comments by Jani - port variables named properly Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/intel_dsi_cmd.c | 75 drivers/gpu/drm/i915/intel_dsi_cmd.h | 46 + drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 25 ++ 3 files changed, 74 insertions(+), 72 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c index 004fa91..8e30684 100644 --- a/drivers/gpu/drm/i915/intel_dsi_cmd.c +++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c @@ -48,13 +48,11 @@ * For memory writes, these should probably be used for performance. */ -static void print_stat(struct intel_dsi *intel_dsi) +static void print_stat(struct intel_dsi *intel_dsi, enum port port) { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); u32 val; val = I915_READ(MIPI_INTR_STAT(port)); @@ -104,13 +102,12 @@ enum dsi_type { }; /* enable or disable command mode hs transmissions */ -void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable) +void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable, + enum port port) { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); u32 temp; u32 mask = DBI_FIFO_EMPTY; @@ -125,13 +122,11 @@ void dsi_hs_mode_enable(struct intel_dsi *intel_dsi, bool enable) } static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel, -u8 data_type, u16 data) +u8 data_type, u16 data, enum port port) { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); u32 ctrl_reg; u32 ctrl; u32 mask; @@ -149,7 +144,7 @@ static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel, if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & mask) == 0, 50)) { DRM_ERROR("Timeout waiting for HS/LP CTRL FIFO !full\n"); - print_stat(intel_dsi); + print_stat(intel_dsi, port); } /* @@ -167,13 +162,11 @@ static int dsi_vc_send_short(struct intel_dsi *intel_dsi, int channel, } static int dsi_vc_send_long(struct intel_dsi *intel_dsi, int channel, - u8 data_type, const u8 *data, int len) + u8 data_type, const u8 *data, int len, enum port port) { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); u32 data_reg; int i, j, n; u32 mask; @@ -204,12 +197,12 @@ static int dsi_vc_send_long(struct intel_dsi *intel_dsi, int channel, * dwords, then wait for not set, then continue. */ } - return dsi_vc_send_short(intel_dsi, channel, data_type, len); + return dsi_vc_send_short(intel_dsi, channel, data_type, len, port); } static int dsi_vc_write_common(struct intel_dsi *intel_dsi, int channel, const u8 *data, int len, - enum dsi_type type) + enum dsi_type type, enum port port) { int ret; @@ -217,50 +210,54 @@ static int dsi_vc_write_common(struct intel_dsi *intel_dsi, BUG_ON(type == DSI_GENERIC); ret = dsi_vc_send_short(intel_dsi, channel, MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM, - 0); + 0, port); } else if (len == 1) { ret = dsi_vc_send_short(intel_dsi, channel, type ==
[Intel-gfx] [PATCH 08/10] drm/i915: MIPI Timings related changes for dual link
hactive, hfp, hbp, hsync needs to be halved for dual link MIPI Panels. Accordingly timing related mmio regs needs to be programmed for both MIPI Ports. v2: Address review comments by Jani - Used a for loop instead of do-while loop v3: Used for_each_dsi_port macro instead of for loop Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 37 - 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 4e18abd..22b1570 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -479,7 +479,7 @@ static void set_dsi_timings(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; unsigned int bpp = intel_crtc->config.pipe_bpp; unsigned int lane_count = intel_dsi->lane_count; @@ -490,6 +490,15 @@ static void set_dsi_timings(struct drm_encoder *encoder, hsync = mode->hsync_end - mode->hsync_start; hbp = mode->htotal - mode->hsync_end; + if (intel_dsi->dual_link) { + hactive /= 2; + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) + hactive += intel_dsi->pixel_overlap; + hfp /= 2; + hsync /= 2; + hbp /= 2; + } + vfp = mode->vsync_start - mode->vdisplay; vsync = mode->vsync_end - mode->vsync_start; vbp = mode->vtotal - mode->vsync_end; @@ -502,18 +511,20 @@ static void set_dsi_timings(struct drm_encoder *encoder, intel_dsi->burst_mode_ratio); hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio); - I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive); - I915_WRITE(MIPI_HFP_COUNT(port), hfp); - - /* meaningful for video mode non-burst sync pulse mode only, can be zero -* for non-burst sync events and burst modes */ - I915_WRITE(MIPI_HSYNC_PADDING_COUNT(port), hsync); - I915_WRITE(MIPI_HBP_COUNT(port), hbp); - - /* vertical values are in terms of lines */ - I915_WRITE(MIPI_VFP_COUNT(port), vfp); - I915_WRITE(MIPI_VSYNC_PADDING_COUNT(port), vsync); - I915_WRITE(MIPI_VBP_COUNT(port), vbp); + for_each_dsi_port(port, intel_dsi->ports) { + I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive); + I915_WRITE(MIPI_HFP_COUNT(port), hfp); + + /* meaningful for video mode non-burst sync pulse mode only, +* can be zero for non-burst sync events and burst modes */ + I915_WRITE(MIPI_HSYNC_PADDING_COUNT(port), hsync); + I915_WRITE(MIPI_HBP_COUNT(port), hbp); + + /* vertical values are in terms of lines */ + I915_WRITE(MIPI_VFP_COUNT(port), vfp); + I915_WRITE(MIPI_VSYNC_PADDING_COUNT(port), vsync); + I915_WRITE(MIPI_VBP_COUNT(port), vbp); + } } static void intel_dsi_prepare(struct intel_encoder *intel_encoder) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/10] drm/i915: New functions added for enabling & disabling MIPI Port Ctrl reg
This patch is in preparation for the DSI dual link port enable and disable related changes. Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 43 -- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 259cb4a..693736b 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -102,6 +102,36 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, return true; } +static void intel_dsi_port_enable(struct intel_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + u32 temp; + + /* assert ip_tg_enable signal */ + temp = I915_READ(MIPI_PORT_CTRL(port)) & ~LANE_CONFIGURATION_MASK; + temp = temp | intel_dsi->port_bits; + I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); + POSTING_READ(MIPI_PORT_CTRL(port)); +} + +static void intel_dsi_port_disable(struct intel_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + u32 temp; + + /* de-assert ip_tg_enable signal */ + temp = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); + POSTING_READ(MIPI_PORT_CTRL(port)); +} + static void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; @@ -141,7 +171,6 @@ static void intel_dsi_enable(struct intel_encoder *encoder) struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); - u32 temp; DRM_DEBUG_KMS("\n"); @@ -157,11 +186,7 @@ static void intel_dsi_enable(struct intel_encoder *encoder) wait_for_dsi_fifo_empty(intel_dsi); - /* assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)) & ~LANE_CONFIGURATION_MASK; - temp = temp | intel_dsi->port_bits; - I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); - POSTING_READ(MIPI_PORT_CTRL(port)); + intel_dsi_port_enable(encoder); } } @@ -245,11 +270,7 @@ static void intel_dsi_disable(struct intel_encoder *encoder) if (is_vid_mode(intel_dsi)) { wait_for_dsi_fifo_empty(intel_dsi); - /* de-assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); - POSTING_READ(MIPI_PORT_CTRL(port)); - + intel_dsi_port_disable(encoder); msleep(2); } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 03/10] drm/i915: Add support for port enable/disable for dual link configuration
For Dual Link MIPI Panels, both Port A and Port C should be enabled during the MIPI encoder enabling sequence. Similarly, during the disabling sequence, both ports needs to be disabled. v2: Used for_each_dsi_port macro instead of for loop v3: Used intel_dsi->ports instead of dual_link var for dual link configuration check Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/i915_reg.h|1 + drivers/gpu/drm/i915/intel_dsi.c | 37 +++- drivers/gpu/drm/i915/intel_dsi.h |1 + drivers/gpu/drm/i915/intel_dsi_panel_vbt.c |4 +++ 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index dc03fac..c981f5d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6664,6 +6664,7 @@ enum punit_power_well { #define DPI_ENABLE(1 << 31) /* A + C */ #define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27 #define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27) +#define DUAL_LINK_MODE_SHIFT 26 #define DUAL_LINK_MODE_MASK (1 << 26) #define DUAL_LINK_MODE_FRONT_BACK (0 << 26) #define DUAL_LINK_MODE_PIXEL_ALTERNATIVE (1 << 26) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 693736b..dbe52e9 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -108,28 +108,41 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; u32 temp; - /* assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)) & ~LANE_CONFIGURATION_MASK; - temp = temp | intel_dsi->port_bits; - I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); - POSTING_READ(MIPI_PORT_CTRL(port)); + for_each_dsi_port(port, intel_dsi->ports) { + temp = I915_READ(MIPI_PORT_CTRL(port)); + + if (intel_dsi->ports == ((1 << PORT_A) | (1 << PORT_C))) { + temp |= (intel_dsi->dual_link - 1) + << DUAL_LINK_MODE_SHIFT; + temp |= intel_crtc->pipe ? + LANE_CONFIGURATION_DUAL_LINK_B : + LANE_CONFIGURATION_DUAL_LINK_A; + } else + temp &= ~LANE_CONFIGURATION_MASK; + + /* assert ip_tg_enable signal */ + I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); + POSTING_READ(MIPI_PORT_CTRL(port)); + } } static void intel_dsi_port_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; u32 temp; - /* de-assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); - POSTING_READ(MIPI_PORT_CTRL(port)); + for_each_dsi_port(port, intel_dsi->ports) { + /* de-assert ip_tg_enable signal */ + temp = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); + POSTING_READ(MIPI_PORT_CTRL(port)); + } } static void intel_dsi_device_ready(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 7f5d028..f2cc2fc 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -104,6 +104,7 @@ struct intel_dsi { u8 clock_stop; u8 escape_clk_div; + u8 dual_link; u32 port_bits; u32 bw_timer; u32 dphy_reg; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 7766c42..f60146f 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -287,6 +287,10 @@ static bool generic_init(struct intel_dsi_device *dsi) intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0; intel_dsi->lane_count = mipi_config->lane_cnt + 1; intel_dsi->pixel_forma
[Intel-gfx] [PATCH 05/10] drm/i915: Dual link needs Shutdown and Turn on packet for both ports
For dual link MIPI panels, SHUTDOWN packet needs to send to both Ports A & C during MIPI encoder disabling sequence. Similarly, TURN ON packet to be sent to both Ports during MIPI encoder enabling sequence. v2: Address review comments by Jani - Used a for loop instead of do-while loop. v3: Used for_each_dsi_port macro instead of for loop Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi_cmd.c | 26 +++--- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c index 8e30684..562811c 100644 --- a/drivers/gpu/drm/i915/intel_dsi_cmd.c +++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c @@ -385,8 +385,7 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs) struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; u32 mask; /* XXX: pipe, hs */ @@ -395,18 +394,23 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs) else cmd |= DPI_LP_MODE; - /* clear bit */ - I915_WRITE(MIPI_INTR_STAT(port), SPL_PKT_SENT_INTERRUPT); + for_each_dsi_port(port, intel_dsi->ports) { + /* clear bit */ + I915_WRITE(MIPI_INTR_STAT(port), SPL_PKT_SENT_INTERRUPT); - /* XXX: old code skips write if control unchanged */ - if (cmd == I915_READ(MIPI_DPI_CONTROL(port))) - DRM_ERROR("Same special packet %02x twice in a row.\n", cmd); + /* XXX: old code skips write if control unchanged */ + if (cmd == I915_READ(MIPI_DPI_CONTROL(port))) + DRM_ERROR("Same special packet %02x twice in a row.\n", + cmd); - I915_WRITE(MIPI_DPI_CONTROL(port), cmd); + I915_WRITE(MIPI_DPI_CONTROL(port), cmd); - mask = SPL_PKT_SENT_INTERRUPT; - if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, 100)) - DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd); + mask = SPL_PKT_SENT_INTERRUPT; + if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, + 100)) + DRM_ERROR("Video mode command 0x%08x send failed.\n", + cmd); + } return 0; } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/10] BYT DSI Dual Link Support
Hi, These set of patches build on top of the existing DSI Video mode support to enable dual link MIPI panels with high resolutions. These patches have been tested on a 25x16 panel and works well. v2: Commit message added to all patches. All review comments of Jani, Nikula have been addressed in the second version of patches. v3: for_each_dsi_port macro used instead of for loop for dual link support v4: From 6th patch, separte patch created for DSI Pll lock check. All review comments of Jani, Nikula have been addressed. Regards Gaurav Gaurav K Singh (10): drm/i915: New functions added for enabling & disabling MIPI Port Ctrl reg drm/i915: Added port as parameter to the functions which does read/write of DSI Controller drm/i915: Add support for port enable/disable for dual link configuration drm/i915: Pixel Clock changes for DSI dual link drm/i915: Dual link needs Shutdown and Turn on packet for both ports drm/i915: Enable DSI PLL for both DSI0 and DSI1 in case of dual link drm/i915: cck reg used for checking DSI Pll locked drm/i915: MIPI Timings related changes for dual link drm/i915: Update the DSI disable path to support dual link panel disabling drm/i915: Update the DSI enable path to support dual link panel enabling drivers/gpu/drm/i915/i915_reg.h|5 + drivers/gpu/drm/i915/intel_bios.h |3 +- drivers/gpu/drm/i915/intel_dsi.c | 413 +--- drivers/gpu/drm/i915/intel_dsi.h |7 + drivers/gpu/drm/i915/intel_dsi_cmd.c | 101 --- drivers/gpu/drm/i915/intel_dsi_cmd.h | 46 ++-- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 50 +++- drivers/gpu/drm/i915/intel_dsi_pll.c |8 +- 8 files changed, 380 insertions(+), 253 deletions(-) -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 10/10] drm/i915: Update the DSI enable path to support dual link panel enabling
We need to program both port registers during dual link enable path. v2: Address review comments by Jani - Used a for loop instead of do-while loop. v3: Used for_each_dsi_port macro instead of for loop Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 251 +- 1 file changed, 136 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 5ae4015..ad82d0d 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -156,8 +156,8 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder) static void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; u32 val; DRM_DEBUG_KMS("\n"); @@ -171,18 +171,21 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) /* bandgap reset is needed after everytime we do power gate */ band_gap_reset(dev_priv); - I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER); - usleep_range(2500, 3000); + for_each_dsi_port(port, intel_dsi->ports) { - val = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD); - usleep_range(1000, 1500); + I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER); + usleep_range(2500, 3000); - I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT); - usleep_range(2500, 3000); + val = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD); + usleep_range(1000, 1500); - I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY); - usleep_range(2500, 3000); + I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_EXIT); + usleep_range(2500, 3000); + + I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY); + usleep_range(2500, 3000); + } } static void intel_dsi_enable(struct intel_encoder *encoder) @@ -541,32 +544,43 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct drm_display_mode *adjusted_mode = &intel_crtc->config.adjusted_mode; - enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + enum port port; unsigned int bpp = intel_crtc->config.pipe_bpp; u32 val, tmp; + u16 mode_hactive; DRM_DEBUG_KMS("pipe %c\n", pipe_name(intel_crtc->pipe)); - /* escape clock divider, 20MHz, shared for A and C. device ready must be -* off when doing this! txclkesc? */ - tmp = I915_READ(MIPI_CTRL(PORT_A)); - tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK; - I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1); - - /* read request priority is per pipe */ - tmp = I915_READ(MIPI_CTRL(port)); - tmp &= ~READ_REQUEST_PRIORITY_MASK; - I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH); + mode_hactive = adjusted_mode->hdisplay; - /* XXX: why here, why like this? handling in irq handler?! */ - I915_WRITE(MIPI_INTR_STAT(port), 0x); - I915_WRITE(MIPI_INTR_EN(port), 0x); - - I915_WRITE(MIPI_DPHY_PARAM(port), intel_dsi->dphy_reg); + if (intel_dsi->dual_link) { + mode_hactive /= 2; + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) + mode_hactive += intel_dsi->pixel_overlap; + } - I915_WRITE(MIPI_DPI_RESOLUTION(port), - adjusted_mode->vdisplay << VERTICAL_ADDRESS_SHIFT | - adjusted_mode->hdisplay << HORIZONTAL_ADDRESS_SHIFT); + for_each_dsi_port(port, intel_dsi->ports) { + /* escape clock divider, 20MHz, shared for A and C. +* device ready must be off when doing this! txclkesc? */ + tmp = I915_READ(MIPI_CTRL(PORT_A)); + tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK; + I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1); + + /* read request priority is per pipe */ + tmp = I915_READ(MIPI_CTRL(port)); + tmp &= ~READ_REQUEST_PRIORITY_MASK; + I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH); + + /* XXX: why here, why like this? handling in irq handler?! */ + I915_WRITE(MIPI_INTR_STAT(port), 0x); + I915_
[Intel-gfx] [PATCH 04/10] drm/i915: Pixel Clock changes for DSI dual link
For dual link MIPI Panels, each port needs half of pixel clock. Pixel overlap can be enabled if needed by panel, then in that case, pixel clock will be increased for extra pixels. v2 : Address review comments by Jani - Removed the bit mask used for ->dual_link - Used DSI instead of MIPI for #define variables Signed-off-by: Gaurav K Singh --- drivers/gpu/drm/i915/i915_reg.h|4 drivers/gpu/drm/i915/intel_bios.h |3 ++- drivers/gpu/drm/i915/intel_dsi.c |8 drivers/gpu/drm/i915/intel_dsi.h |6 ++ drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 21 + 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c981f5d..87149ba 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6029,6 +6029,10 @@ enum punit_power_well { #define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31) #define VLV_PWRDWNUPCTL0xA294 +#define VLV_CHICKEN_3 0x7040C +#define PIXEL_OVERLAP_CNT_MASK(3 << 30) +#define PIXEL_OVERLAP_CNT_SHIFT 30 + #define GEN6_PMISR 0x44020 #define GEN6_PMIMR 0x44024 /* rps_lock */ #define GEN6_PMIIR 0x44028 diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index de01167..a6a8710 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -818,7 +818,8 @@ struct mipi_config { #define DUAL_LINK_PIXEL_ALT2 u16 dual_link:2; u16 lane_cnt:2; - u16 rsvd3:12; + u16 pixel_overlap:3; + u16 rsvd3:9; u16 rsvd4; diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index dbe52e9..4e18abd 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -111,6 +111,14 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) enum port port; u32 temp; + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { + temp = I915_READ(VLV_CHICKEN_3); + temp &= ~PIXEL_OVERLAP_CNT_MASK | + intel_dsi->pixel_overlap << + PIXEL_OVERLAP_CNT_SHIFT; + I915_WRITE(VLV_CHICKEN_3, temp); + } + for_each_dsi_port(port, intel_dsi->ports) { temp = I915_READ(MIPI_PORT_CTRL(port)); diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index f2cc2fc..8fe2064 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -28,6 +28,11 @@ #include #include "intel_drv.h" +/* Dual Link support */ +#define DSI_DUAL_LINK_NONE 0 +#define DSI_DUAL_LINK_FRONT_BACK 1 +#define DSI_DUAL_LINK_PIXEL_ALT2 + struct intel_dsi_device { unsigned int panel_id; const char *name; @@ -105,6 +110,7 @@ struct intel_dsi { u8 escape_clk_div; u8 dual_link; + u8 pixel_overlap; u32 port_bits; u32 bw_timer; u32 dphy_reg; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index f60146f..f8c2269 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -288,6 +288,7 @@ static bool generic_init(struct intel_dsi_device *dsi) intel_dsi->lane_count = mipi_config->lane_cnt + 1; intel_dsi->pixel_format = mipi_config->videomode_color_format << 7; intel_dsi->dual_link = mipi_config->dual_link; + intel_dsi->pixel_overlap = mipi_config->pixel_overlap; if (intel_dsi->dual_link) intel_dsi->ports = ((1 << PORT_A) | (1 << PORT_C)); @@ -310,6 +311,20 @@ static bool generic_init(struct intel_dsi_device *dsi) pclk = mode->clock; + /* In dual link mode each port needs half of pixel clock */ + if (intel_dsi->dual_link) { + pclk = pclk / 2; + + /* we can enable pixel_overlap if needed by panel. In this +* case we need to increase the pixelclock for extra pixels +*/ + if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { + pclk += DIV_ROUND_UP(mode->vtotal * + intel_dsi->pixel_overlap * + 60, 1000); + } + } + /* Burst Mode Ratio * Target ddr frequency from VBT / non burst ddr freq * multiply by 100 to preserve remainder @@ -504,6 +519,12 @@ static bo
[Intel-gfx] [PATCH 07/10] drm/i915: cck reg used for checking DSI Pll locked
Instead of pipe configuration reg, cck reg to be used for checking whether DSI Pll is getting locked or not. Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi_pll.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 636d72f..dd45484 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -272,12 +272,13 @@ void vlv_enable_dsi_pll(struct intel_encoder *encoder) tmp |= DSI_PLL_VCO_EN; vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp); - mutex_unlock(&dev_priv->dpio_lock); + if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) & + DSI_PLL_LOCK, 20)) { - if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED, 20)) { DRM_ERROR("DSI PLL lock failed\n"); return; } + mutex_unlock(&dev_priv->dpio_lock); DRM_DEBUG_KMS("DSI PLL locked\n"); } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/9] drm/i915: New functions added for enabling & disabling MIPI Port Ctrl reg
This patch is in preparation for the DSI dual link port enable and disable related changes. Signed-off-by: Gaurav K Singh Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/intel_dsi.c | 43 -- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 259cb4a..693736b 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -102,6 +102,36 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, return true; } +static void intel_dsi_port_enable(struct intel_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + u32 temp; + + /* assert ip_tg_enable signal */ + temp = I915_READ(MIPI_PORT_CTRL(port)) & ~LANE_CONFIGURATION_MASK; + temp = temp | intel_dsi->port_bits; + I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); + POSTING_READ(MIPI_PORT_CTRL(port)); +} + +static void intel_dsi_port_disable(struct intel_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); + u32 temp; + + /* de-assert ip_tg_enable signal */ + temp = I915_READ(MIPI_PORT_CTRL(port)); + I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); + POSTING_READ(MIPI_PORT_CTRL(port)); +} + static void intel_dsi_device_ready(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; @@ -141,7 +171,6 @@ static void intel_dsi_enable(struct intel_encoder *encoder) struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port = intel_dsi_pipe_to_port(intel_crtc->pipe); - u32 temp; DRM_DEBUG_KMS("\n"); @@ -157,11 +186,7 @@ static void intel_dsi_enable(struct intel_encoder *encoder) wait_for_dsi_fifo_empty(intel_dsi); - /* assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)) & ~LANE_CONFIGURATION_MASK; - temp = temp | intel_dsi->port_bits; - I915_WRITE(MIPI_PORT_CTRL(port), temp | DPI_ENABLE); - POSTING_READ(MIPI_PORT_CTRL(port)); + intel_dsi_port_enable(encoder); } } @@ -245,11 +270,7 @@ static void intel_dsi_disable(struct intel_encoder *encoder) if (is_vid_mode(intel_dsi)) { wait_for_dsi_fifo_empty(intel_dsi); - /* de-assert ip_tg_enable signal */ - temp = I915_READ(MIPI_PORT_CTRL(port)); - I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE); - POSTING_READ(MIPI_PORT_CTRL(port)); - + intel_dsi_port_disable(encoder); msleep(2); } -- 1.7.9.5 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx