[Intel-gfx] [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder
From: Shashank Sharma This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector this probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. v2: Calling set_edid instead of hdmi_probe during init. Also, for platforms having DDI, intel_encoder for DP and HDMI is same (taken from intel_dig_port), so for DP also, hot_plug function gets called which is not intended here. So, check for HDMI in intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV. v3: Dropping the gen < 8 || !VLV check. Now all platforms should rely on hotplug or init for updating the edid.(Daniel) Also, calling hdmi_probe in init instead of set_edid v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug. Also calling this hotplug handler from intel_hpd_init to take care of init resume scenarios. v5: Moved the call to encoder hotplug during init to separate patch(Daniel) v6: Rebased and maintaining authorship. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 58 ++- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index bdd462e..16dd2a7 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force) return connected; } -static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector, bool force) +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder) { - enum drm_connector_status status; - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); bool live_status = false; unsigned int retry = 3; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); while (!live_status && --retry) { @@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) hdmi_to_dig_port(intel_hdmi)); mdelay(10); } + intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); if (!live_status) DRM_DEBUG_KMS("Live status not up!"); - intel_hdmi_unset_edid(connector); + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base, live_status)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + +static enum drm_connector_status +intel_hdmi_detect(struct drm_connector *connector, bool force) +{ + enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); - if (intel_hdmi_set_edid(connector, live_status)) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + + /* +* There are many userspace calls wh
[Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
Call the encoders, call the hot_plug if it is registered. This is required for connected boot and resume cases to generate fake hpd resulting in reading of edid. Removing the initial sdvo hot_plug call too so that it will be called just once from this loop. v2: Schedule a work function to call hot_plug. On CHT, it runs into a deadlock if we call ->hot_plug inside hpd_init. This is because, hot_plug calls set_edid which tries to acquire the power domain and if power well is disabled, we enable power well and call hpd_init again. So, schedule a work function from here to call hot_plug and run a detect cycle. Cc: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_hotplug.c | 26 ++ drivers/gpu/drm/i915/intel_sdvo.c| 1 - 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bc865e23..4f037b9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -228,6 +228,7 @@ enum hpd_pin { struct i915_hotplug { struct work_struct hotplug_work; + struct work_struct edid_work; struct { unsigned long last_jiffies; diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index b177857..72d8fe8 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -442,6 +442,24 @@ void intel_hpd_irq_handler(struct drm_device *dev, schedule_work(&dev_priv->hotplug.hotplug_work); } +static void i915_edid_work_func(struct work_struct *work) +{ + struct drm_i915_private *dev_priv = + container_of(work, struct drm_i915_private, hotplug.edid_work); + struct drm_device *dev = dev_priv->dev; + struct drm_mode_config *mode_config = &dev->mode_config; + struct intel_encoder *encoder; + + mutex_lock(&mode_config->mutex); + list_for_each_entry(encoder, &mode_config->encoder_list, + base.head) { + if (encoder->hot_plug) + encoder->hot_plug(encoder); + } + mutex_unlock(&mode_config->mutex); + drm_helper_hpd_irq_event(dev); +} + /** * intel_hpd_init - initializes and enables hpd support * @dev_priv: i915 device instance @@ -482,12 +500,19 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) if (dev_priv->display.hpd_irq_setup) dev_priv->display.hpd_irq_setup(dev); spin_unlock_irq(&dev_priv->irq_lock); + + /* +* Connected boot / resume scenarios can't generate new hot plug. +* So, probe it manually. +*/ + schedule_work(&dev_priv->hotplug.edid_work); } void intel_hpd_init_work(struct drm_i915_private *dev_priv) { INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func); INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func); + INIT_WORK(&dev_priv->hotplug.edid_work, i915_edid_work_func); INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work, intel_hpd_irq_storm_reenable_work); } @@ -504,5 +529,6 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) cancel_work_sync(&dev_priv->hotplug.dig_port_work); cancel_work_sync(&dev_priv->hotplug.hotplug_work); + cancel_work_sync(&dev_priv->hotplug.edid_work); cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work); } diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 06679f1..4238a02 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2466,7 +2466,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) * Ensure that they get re-enabled when an interrupt happens. */ intel_encoder->hot_plug = intel_sdvo_enable_hotplug; - intel_sdvo_enable_hotplug(intel_encoder); } else { intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; } -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
From: Shashank Sharma This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector this probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. v2: Calling set_edid instead of hdmi_probe during init. Also, for platforms having DDI, intel_encoder for DP and HDMI is same (taken from intel_dig_port), so for DP also, hot_plug function gets called which is not intended here. So, check for HDMI in intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV. v3: Dropping the gen < 8 || !VLV check. Now all platforms should rely on hotplug or init for updating the edid.(Daniel) Also, calling hdmi_probe in init instead of set_edid v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug. Also calling this hotplug handler from intel_hpd_init to take care of init resume scenarios. v5: Moved the call to encoder hotplug during init to separate patch(Daniel) v6: Rebased and maintaining authorship. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 58 ++- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index bdd462e..16dd2a7 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force) return connected; } -static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector, bool force) +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder) { - enum drm_connector_status status; - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); bool live_status = false; unsigned int retry = 3; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); while (!live_status && --retry) { @@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) hdmi_to_dig_port(intel_hdmi)); mdelay(10); } + intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); if (!live_status) DRM_DEBUG_KMS("Live status not up!"); - intel_hdmi_unset_edid(connector); + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base, live_status)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + +static enum drm_connector_status +intel_hdmi_detect(struct drm_connector *connector, bool force) +{ + enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); - if (intel_hdmi_set_edid(connector, live_status)) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + + /* +* There are many userspace calls wh
[Intel-gfx] [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder
This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector this probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. v2: Calling set_edid instead of hdmi_probe during init. Also, for platforms having DDI, intel_encoder for DP and HDMI is same (taken from intel_dig_port), so for DP also, hot_plug function gets called which is not intended here. So, check for HDMI in intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV. v3: Dropping the gen < 8 || !VLV check. Now all platforms should rely on hotplug or init for updating the edid.(Daniel) Also, calling hdmi_probe in init instead of set_edid v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug. Also calling this hotplug handler from intel_hpd_init to take care of init resume scenarios. v5: Moved the call to encoder hotplug during init to separate patch(Daniel) v6: Rebased. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 58 ++- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index bdd462e..16dd2a7 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1381,18 +1381,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force) return connected; } -static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector, bool force) +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder) { - enum drm_connector_status status; - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); bool live_status = false; unsigned int retry = 3; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); while (!live_status && --retry) { @@ -1400,21 +1398,53 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) hdmi_to_dig_port(intel_hdmi)); mdelay(10); } + intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); if (!live_status) DRM_DEBUG_KMS("Live status not up!"); - intel_hdmi_unset_edid(connector); + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base, live_status)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + +static enum drm_connector_status +intel_hdmi_detect(struct drm_connector *connector, bool force) +{ + enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); - if (intel_hdmi_set_edid(connector, live_status)) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + + /* +* There are many userspace calls which probe EDID from +* detect path. In
[Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
Call the encoders, call the hot_plug if it is registered. This is required for connected boot and resume cases to generate fake hpd resulting in reading of edid. Removing the initial sdvo hot_plug call too so that it will be called just once from this loop. v2: Schedule a work function to call hot_plug Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_hotplug.c | 26 ++ drivers/gpu/drm/i915/intel_sdvo.c| 1 - 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bc865e23..4f037b9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -228,6 +228,7 @@ enum hpd_pin { struct i915_hotplug { struct work_struct hotplug_work; + struct work_struct edid_work; struct { unsigned long last_jiffies; diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index b177857..72d8fe8 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -442,6 +442,24 @@ void intel_hpd_irq_handler(struct drm_device *dev, schedule_work(&dev_priv->hotplug.hotplug_work); } +static void i915_edid_work_func(struct work_struct *work) +{ + struct drm_i915_private *dev_priv = + container_of(work, struct drm_i915_private, hotplug.edid_work); + struct drm_device *dev = dev_priv->dev; + struct drm_mode_config *mode_config = &dev->mode_config; + struct intel_encoder *encoder; + + mutex_lock(&mode_config->mutex); + list_for_each_entry(encoder, &mode_config->encoder_list, + base.head) { + if (encoder->hot_plug) + encoder->hot_plug(encoder); + } + mutex_unlock(&mode_config->mutex); + drm_helper_hpd_irq_event(dev); +} + /** * intel_hpd_init - initializes and enables hpd support * @dev_priv: i915 device instance @@ -482,12 +500,19 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) if (dev_priv->display.hpd_irq_setup) dev_priv->display.hpd_irq_setup(dev); spin_unlock_irq(&dev_priv->irq_lock); + + /* +* Connected boot / resume scenarios can't generate new hot plug. +* So, probe it manually. +*/ + schedule_work(&dev_priv->hotplug.edid_work); } void intel_hpd_init_work(struct drm_i915_private *dev_priv) { INIT_WORK(&dev_priv->hotplug.hotplug_work, i915_hotplug_work_func); INIT_WORK(&dev_priv->hotplug.dig_port_work, i915_digport_work_func); + INIT_WORK(&dev_priv->hotplug.edid_work, i915_edid_work_func); INIT_DELAYED_WORK(&dev_priv->hotplug.reenable_work, intel_hpd_irq_storm_reenable_work); } @@ -504,5 +529,6 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) cancel_work_sync(&dev_priv->hotplug.dig_port_work); cancel_work_sync(&dev_priv->hotplug.hotplug_work); + cancel_work_sync(&dev_priv->hotplug.edid_work); cancel_delayed_work_sync(&dev_priv->hotplug.reenable_work); } diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 06679f1..4238a02 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2466,7 +2466,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) * Ensure that they get re-enabled when an interrupt happens. */ intel_encoder->hot_plug = intel_sdvo_enable_hotplug; - intel_sdvo_enable_hotplug(intel_encoder); } else { intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; } -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: Update Uninit sequence for DDI PHYs
Un-initialize DDI PHYs as per the bspec update Cc: Sivakumar Thulasimani Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index a65bf81..ba8327f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2723,6 +2723,10 @@ static void broxton_phy_uninit(struct drm_i915_private *dev_priv, val = I915_READ(BXT_PHY_CTL_FAMILY(phy)); val &= ~COMMON_RESET_DIS; I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val); + + val = I915_READ(BXT_P_CR_GT_DISP_PWRON); + val &= ~GT_DISPLAY_POWER_ON(phy); + I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); } void broxton_ddi_phy_uninit(struct drm_device *dev) @@ -2731,9 +2735,6 @@ void broxton_ddi_phy_uninit(struct drm_device *dev) broxton_phy_uninit(dev_priv, DPIO_PHY1); broxton_phy_uninit(dev_priv, DPIO_PHY0); - - /* FIXME: do this in broxton_phy_uninit per phy */ - I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0); } static const char * const bxt_ddi_pll_names[] = { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915: Call encoder hotplug for init and resume cases
For all the encoders, call the hot_plug if it is registered. This is required for connected boot and resume cases to generate fake hpd resulting in reading of edid. Removing the initial sdvo hot_plug call too so that it will be called just once from this loop. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hotplug.c | 11 +++ drivers/gpu/drm/i915/intel_sdvo.c|1 - 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index 53c0173..eac4757 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -458,6 +458,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; struct drm_mode_config *mode_config = &dev->mode_config; + struct intel_encoder *encoder; struct drm_connector *connector; int i; @@ -482,6 +483,16 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) if (dev_priv->display.hpd_irq_setup) dev_priv->display.hpd_irq_setup(dev); spin_unlock_irq(&dev_priv->irq_lock); + + /* +* Connected boot / resume scenarios can't generate new hot plug. +* So, probe it manually. +*/ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, + base.head) { + if (encoder->hot_plug) + encoder->hot_plug(encoder); + } } void intel_hpd_init_work(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 05521b5..55859e9 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2433,7 +2433,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) * Ensure that they get re-enabled when an interrupt happens. */ intel_encoder->hot_plug = intel_sdvo_enable_hotplug; - intel_sdvo_enable_hotplug(intel_encoder); } else { intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915: Add hot_plug hook for hdmi encoder
This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector this probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. v2: Calling set_edid instead of hdmi_probe during init. Also, for platforms having DDI, intel_encoder for DP and HDMI is same (taken from intel_dig_port), so for DP also, hot_plug function gets called which is not intended here. So, check for HDMI in intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV. v3: Dropping the gen < 8 || !VLV check. Now all platforms should rely on hotplug or init for updating the edid.(Daniel) Also, calling hdmi_probe in init instead of set_edid v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug. Also calling this hotplug handler from intel_hpd_init to take care of init resume scenarios. v5: Moved the call to encoder hotplug during init to separate patch(Daniel) Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 54 + 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index bb33c66..9c1a308 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1369,18 +1369,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force) return connected; } -static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector, bool force) +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder) { - enum drm_connector_status status; - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); bool live_status = false; unsigned int retry = 3; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - while (!live_status && --retry) { live_status = intel_digital_port_connected(dev_priv, hdmi_to_dig_port(intel_hdmi)); @@ -1390,15 +1388,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) if (!live_status) DRM_DEBUG_KMS("Live status not up!"); - intel_hdmi_unset_edid(connector); + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base, live_status)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} - if (intel_hdmi_set_edid(connector, live_status)) { +static enum drm_connector_status +intel_hdmi_detect(struct drm_connector *connector, bool force) +{ + enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + + /* +* There are many userspace calls which probe EDID from +* detect path. In case of multiple hotplug/unplug, these +* can cause race conditions while probing EDID. Also its +*
[Intel-gfx] [PATCH] drm/i915: Add hot_plug hook for hdmi encoder
This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector this probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. v2: Calling set_edid instead of hdmi_probe during init. Also, for platforms having DDI, intel_encoder for DP and HDMI is same (taken from intel_dig_port), so for DP also, hot_plug function gets called which is not intended here. So, check for HDMI in intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV. v3: Dropping the gen < 8 || !VLV check. Now all platforms should rely on hotplug or init for updating the edid.(Daniel) Also, calling hdmi_probe in init instead of set_edid v4: Renaming intel_hdmi_probe to intel_hdmi_hot_plug and changing the patch subject. Also calling this hotplug handler from intel_hpd_init to take care of init resume scenarios. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c| 54 +++--- drivers/gpu/drm/i915/intel_hotplug.c | 11 +++ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index bb33c66..9c1a308 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1369,18 +1369,16 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force) return connected; } -static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector, bool force) +void intel_hdmi_hot_plug(struct intel_encoder *intel_encoder) { - enum drm_connector_status status; - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = to_i915(connector->dev); + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); bool live_status = false; unsigned int retry = 3; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); - while (!live_status && --retry) { live_status = intel_digital_port_connected(dev_priv, hdmi_to_dig_port(intel_hdmi)); @@ -1390,15 +1388,48 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) if (!live_status) DRM_DEBUG_KMS("Live status not up!"); - intel_hdmi_unset_edid(connector); + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base, live_status)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} - if (intel_hdmi_set_edid(connector, live_status)) { +static enum drm_connector_status +intel_hdmi_detect(struct drm_connector *connector, bool force) +{ + enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + + /* +* There are many userspace calls which probe EDID from +* detect path. In case of multiple hotplug/unplug, these +* can cause race conditions while probing EDID. Also its +
[Intel-gfx] [PATCH] drm/i915/bxt: eDP low vswing support
Adding voltage swing table for edp to support low vswings. v2: Rebased. Signed-off-by: Sonika Jindal Reviewed-by: Sivakumar Thulasimani --- drivers/gpu/drm/i915/intel_ddi.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 7705bc9..4be1c2b 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -256,9 +256,6 @@ struct bxt_ddi_buf_trans { bool default_index; /* true if the entry represents default value */ }; -/* BSpec does not define separate vswing/pre-emphasis values for eDP. - * Using DP values for eDP as well. - */ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { /* Idx NT mV diff db */ { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */ @@ -273,6 +270,20 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { { 154, 0x9A, 1, 128, false }, /* 9: 12000 */ }; +static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = { + /* Idx NT mV diff db */ + { 26, 0, 0, 128, false }, /* 0: 200 0 */ + { 38, 0, 0, 112, false }, /* 1: 200 1.5 */ + { 48, 0, 0, 96, false }, /* 2: 200 4 */ + { 54, 0, 0, 69, false }, /* 3: 200 6 */ + { 32, 0, 0, 128, false }, /* 4: 250 0 */ + { 48, 0, 0, 104, false }, /* 5: 250 1.5 */ + { 54, 0, 0, 85, false }, /* 6: 250 4 */ + { 43, 0, 0, 128, false }, /* 7: 300 0 */ + { 54, 0, 0, 101, false }, /* 8: 300 1.5 */ + { 48, 0, 0, 128, false }, /* 9: 300 0 */ +}; + /* BSpec has 2 recommended values - entries 0 and 8. * Using the entry with higher vswing. */ @@ -2113,7 +2124,11 @@ static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level, u32 n_entries, i; uint32_t val; - if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { + if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) { + n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); + ddi_translations = bxt_ddi_translations_edp; + } else if (type == INTEL_OUTPUT_DISPLAYPORT + || type == INTEL_OUTPUT_EDP) { n_entries = ARRAY_SIZE(bxt_ddi_translations_dp); ddi_translations = bxt_ddi_translations_dp; } else if (type == INTEL_OUTPUT_HDMI) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: Set oscaledcompmethod to enable scale value
Bspec update tells that we have to enable oscaledcompmethod instead of ouniqetrangenmethod for enabling scale value during swing programming. v2: Adding back 'don't care' values to bxt_ddi_translations_dp and add error message if ouniquetrangemethod was set (Imre) Signed-off-by: Sonika Jindal Reviewed-by: Sivakumar Thulasimani (v1) --- drivers/gpu/drm/i915/i915_reg.h |3 ++- drivers/gpu/drm/i915/intel_ddi.c |8 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 812b7b2..3f2135d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1395,7 +1395,8 @@ enum skl_disp_power_wells { #define BXT_PORT_TX_DW3_LN0(port) _PORT3(port, _PORT_TX_DW3_LN0_A, \ _PORT_TX_DW3_LN0_B, \ _PORT_TX_DW3_LN0_C) -#define UNIQE_TRANGE_EN_METHOD (1 << 27) +#define SCALE_DCOMP_METHOD (1 << 26) +#define UNIQUE_TRANGE_EN_METHOD (1 << 27) #define _PORT_TX_DW4_LN0_A 0x162510 #define _PORT_TX_DW4_LN0_B 0x6C510 diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index fec51df..7705bc9 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2151,9 +2151,13 @@ static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level, I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val); val = I915_READ(BXT_PORT_TX_DW3_LN0(port)); - val &= ~UNIQE_TRANGE_EN_METHOD; + val &= ~SCALE_DCOMP_METHOD; if (ddi_translations[level].enable) - val |= UNIQE_TRANGE_EN_METHOD; + val |= SCALE_DCOMP_METHOD; + + if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD)) + DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set"); + I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val); val = I915_READ(BXT_PORT_TX_DW4_LN0(port)); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] drm/i915/bxt: eDP low vswing support
Adding voltage swing table for edp to support low vswings. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 0d9b304..17281bc 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -256,9 +256,6 @@ struct bxt_ddi_buf_trans { bool default_index; /* true if the entry represents default value */ }; -/* BSpec does not define separate vswing/pre-emphasis values for eDP. - * Using DP values for eDP as well. - */ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { /* Idx NT mV diff db */ { 52, 0, 0, 128, true }, /* 0: 400 0 */ @@ -273,6 +270,20 @@ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { { 154, 0x9A, 1, 128, false }, /* 9: 12000 */ }; +static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = { + /* Idx NT mV diff db */ + { 26, 0, 0, 128, false }, /* 0: 200 0 */ + { 38, 0, 0, 112, false }, /* 1: 200 1.5 */ + { 48, 0, 0, 96, false }, /* 2: 200 4 */ + { 54, 0, 0, 69, false }, /* 3: 200 6 */ + { 32, 0, 0, 128, false }, /* 4: 250 0 */ + { 48, 0, 0, 104, false }, /* 5: 250 1.5 */ + { 54, 0, 0, 85, false }, /* 6: 250 4 */ + { 43, 0, 0, 128, false }, /* 7: 300 0 */ + { 54, 0, 0, 101, false }, /* 8: 300 1.5 */ + { 48, 0, 0, 128, false }, /* 9: 300 0 */ +}; + /* BSpec has 2 recommended values - entries 0 and 8. * Using the entry with higher vswing. */ @@ -2113,7 +2124,11 @@ static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level, u32 n_entries, i; uint32_t val; - if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { + if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) { + n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); + ddi_translations = bxt_ddi_translations_edp; + } else if (type == INTEL_OUTPUT_DISPLAYPORT + || type == INTEL_OUTPUT_EDP) { n_entries = ARRAY_SIZE(bxt_ddi_translations_dp); ddi_translations = bxt_ddi_translations_dp; } else if (type == INTEL_OUTPUT_HDMI) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915/bxt: Set oscaledcompmethod to enable scale value
Bspec update tells that we have to enable oscaledcompmethod instead of ouniqetrangenmethod for enabling scale value during swing programming. Also, scale value is 'don't care' for other levels except the last entry translation table. So, make it 0 instead of 0x9A. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_reg.h |2 +- drivers/gpu/drm/i915/intel_ddi.c | 22 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 812b7b2..cec6546 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1395,7 +1395,7 @@ enum skl_disp_power_wells { #define BXT_PORT_TX_DW3_LN0(port) _PORT3(port, _PORT_TX_DW3_LN0_A, \ _PORT_TX_DW3_LN0_B, \ _PORT_TX_DW3_LN0_C) -#define UNIQE_TRANGE_EN_METHOD (1 << 27) +#define SCALE_DCOMP_METHOD (1 << 26) #define _PORT_TX_DW4_LN0_A 0x162510 #define _PORT_TX_DW4_LN0_B 0x6C510 diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index fec51df..0d9b304 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -261,15 +261,15 @@ struct bxt_ddi_buf_trans { */ static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = { /* Idx NT mV diff db */ - { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */ - { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */ - { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */ - { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */ - { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */ - { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */ - { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */ - { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */ - { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */ + { 52, 0, 0, 128, true }, /* 0: 400 0 */ + { 78, 0, 0, 85, false }, /* 1: 400 3.5 */ + { 104, 0, 0, 64, false }, /* 2: 400 6 */ + { 154, 0, 0, 43, false }, /* 3: 400 9.5 */ + { 77, 0, 0, 128, false }, /* 4: 600 0 */ + { 116, 0, 0, 85, false }, /* 5: 600 3.5 */ + { 154, 0, 0, 64, false }, /* 6: 600 6 */ + { 102, 0, 0, 128, false }, /* 7: 800 0 */ + { 154, 0, 0, 85, false }, /* 8: 800 3.5 */ { 154, 0x9A, 1, 128, false }, /* 9: 12000 */ }; @@ -2151,9 +2151,9 @@ static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level, I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val); val = I915_READ(BXT_PORT_TX_DW3_LN0(port)); - val &= ~UNIQE_TRANGE_EN_METHOD; + val &= ~SCALE_DCOMP_METHOD; if (ddi_translations[level].enable) - val |= UNIQE_TRANGE_EN_METHOD; + val |= SCALE_DCOMP_METHOD; I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val); val = I915_READ(BXT_PORT_TX_DW4_LN0(port)); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Check live status before reading edid
The Bspec is very clear that Live status must be checked about before trying to read EDID over DDC channel. This patch makes sure that HDMI EDID is read only when live status is up. The live status doesn't seem to perform very consistent across various platforms when tested with different monitors. The reason behind that is some monitors are late to provide right voltage to set live_status up. So, after getting the interrupt, for a small duration, live status reg fluctuates, and then settles down showing the correct staus. This is explained here in, in a rough way: HPD line |\ T1 = Monitor Hotplug causing IRQ | \__ | | | | | | T2 = Live status is stable | | _ | | /| Live status _|_|/ | | | | | | | | | | T0 T1 T2 (Between T1 and T2 Live status fluctuates or can be even low, depending on the monitor) After several experiments, we have concluded that a max delay of 30ms is enough to allow the live status to settle down with most of the monitors. This total delay of 30ms has been split into a resolution of 3 retries of 10ms each, for the better cases. This delay is kept at 30ms, keeping in consideration that, HDCP compliance expect the HPD handler to respond a plug out in 100ms, by disabling port. v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions to check digital port status. Adding a separate function to get bxt live status (Daniel) v3: Using intel_encoder->hpd_pin to check the live status (Siva) Moving the live status read to intel_hdmi_probe and passing parameter to read/not to read the edid. (me) v4: * Added live status check for all platforms using intel_digital_port_connected. * Rebased on top of Jani's DP cleanup series * Some monitors take time in setting the live status. So retry for few times if this is a connect HPD v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob which was missed. v6: Drop the (!detect_edid && !live_status check) check because for DDI ports which are enumerated as hdmi as well as DP, we don't have a mechanism to differentiate between DP and hdmi inside the encoder's hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well as hdmi which leads to issues during unplug because of the above check. v7: Make intel_digital_port_connected global in this patch, some reformatting of while loop, adding a print when live status is not up. (Rodrigo) v8: Rebase it on nightly which involved skipping the hot_plug hook for now and letting the live_status check happen in detect until the hpd handling part is finalized (Daniel) Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal Reviewed-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_dp.c |2 +- drivers/gpu/drm/i915/intel_drv.h |2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 28 +--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a687250..a6e22dd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4670,7 +4670,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, * * Return %true if @port is connected, %false otherwise. */ -static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *port) { if (HAS_PCH_IBX(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 08ba362..1e01350 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); void intel_edp_drrs_invalidate(struct drm_device *dev, unsigned frontbuffer_bits); void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +struct intel_digital_port *port); void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config); /* intel_dp_mst.c */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index e978c59..bb33c66 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector) } static bool -intel_hdmi_set_edid(struct drm_connector *connector) +intel_hdmi_set_edid(struct drm_connector *connector, bool force) {
[Intel-gfx] [PATCH] drm/i915/bxt: Use intel_encoder->hpd_pin to check live status
Using intel_encoder's hpd_pin to check the live status because of BXT A0/A1 WA for HPD pins and hpd_pin contains the updated pin for the corresponding port. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c |9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 796f930..bf17030 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv, } static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, - struct intel_digital_port *port) + struct intel_digital_port *intel_dig_port) { + struct intel_encoder *intel_encoder = &intel_dig_port->base; + enum port port; u32 bit; - switch (port->port) { + intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port); + switch (port) { case PORT_A: bit = BXT_DE_PORT_HP_DDIA; break; @@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, bit = BXT_DE_PORT_HP_DDIC; break; default: - MISSING_CASE(port->port); + MISSING_CASE(port); return false; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Check live status before reading edid
The Bspec is very clear that Live status must be checked about before trying to read EDID over DDC channel. This patch makes sure that HDMI EDID is read only when live status is up. The live status doesn't seem to perform very consistent across various platforms when tested with different monitors. The reason behind that is some monitors are late to provide right voltage to set live_status up. So, after getting the interrupt, for a small duration, live status reg fluctuates, and then settles down showing the correct staus. This is explained here in, in a rough way: HPD line |\ T1 = Monitor Hotplug causing IRQ | \__ | | | | | | T2 = Live status is stable | | _ | | /| Live status _|_|/ | | | | | | | | | | T0 T1 T2 (Between T1 and T2 Live status fluctuates or can be even low, depending on the monitor) After several experiments, we have concluded that a max delay of 30ms is enough to allow the live status to settle down with most of the monitors. This total delay of 30ms has been split into a resolution of 3 retries of 10ms each, for the better cases. This delay is kept at 30ms, keeping in consideration that, HDCP compliance expect the HPD handler to respond a plug out in 100ms, by disabling port. v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions to check digital port status. Adding a separate function to get bxt live status (Daniel) v3: Using intel_encoder->hpd_pin to check the live status (Siva) Moving the live status read to intel_hdmi_probe and passing parameter to read/not to read the edid. (me) v4: * Added live status check for all platforms using intel_digital_port_connected. * Rebased on top of Jani's DP cleanup series * Some monitors take time in setting the live status. So retry for few times if this is a connect HPD v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob which was missed. v6: Drop the (!detect_edid && !live_status check) check because for DDI ports which are enumerated as hdmi as well as DP, we don't have a mechanism to differentiate between DP and hdmi inside the encoder's hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well as hdmi which leads to issues during unplug because of the above check. v7: Make intel_digital_port_connected global in this patch, some reformatting of while loop, adding a print when live status is not up. (Rodrigo) Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c |2 +- drivers/gpu/drm/i915/intel_drv.h |2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 26 +++--- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bf17030..fedf6d1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4695,7 +4695,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, * * Return %true if @port is connected, %false otherwise. */ -static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *port) { if (HAS_PCH_IBX(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b6c2c20..ac6d748 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); void intel_edp_drrs_invalidate(struct drm_device *dev, unsigned frontbuffer_bits); void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +struct intel_digital_port *port); /* intel_dp_mst.c */ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1eda71a..d366ca5 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector) } static bool -intel_hdmi_set_edid(struct drm_connector *connector) +intel_hdmi_set_edid(struct drm_connector *connector, bool force) { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *intel_encoder
[Intel-gfx] [PATCH] drm/i915: Check live status before reading edid
The Bspec is very clear that Live status must be checked about before trying to read EDID over DDC channel. This patch makes sure that HDMI EDID is read only when live status us up. The live status doesn't seem to perform very consistent across various platforms when tested with different monitors. The reason behind that is some monitors are late to provide right voltage to set live_status up. So, after getting the interrupt, for a small duration, live status reg fluctuates, and then settles down showing the correct staus. This is explained here in, in a rough way: HPD line |\ T1 = Monitor Hotplug causing IRQ | \__ | | | | | | T2 = Live status is stable | | _ | | /| Live status _|_|/ | | | | | | | | | | T0 T1 T2 (Between T1 and T2 Live status fluctuates or can be even low, depending on the monitor) After several experiments, we have concluded that a max delay of 30ms is enough to allow the live status to settle down with most of the monitors. This total delay of 30ms has been split into a resolution of 3 retries of 10ms each, for the better cases. This delay is kept at 30ms, keeping in consideration that, HDCP compliance expect the HPD handler to respond a plug out in 100ms, by disabling port. v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions to check digital port status. Adding a separate function to get bxt live status (Daniel) v3: Using intel_encoder->hpd_pin to check the live status (Siva) Moving the live status read to intel_hdmi_probe and passing parameter to read/not to read the edid. (me) v4: * Added live status check for all platforms using intel_digital_port_connected. * Rebased on top of Jani's DP cleanup series * Some monitors take time in setting the live status. So retry for few times if this is a connect HPD v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob which was missed. v6: Drop the (!detect_edid && !live_status check) check because for DDI ports which are enumerated as hdmi as well as DP, we don't have a mechanism to differentiate between DP and hdmi inside the encoder's hot_plug. This leads to call to the hdmi's hot_plug hook for DP as well as hdmi which leads to issues during unplug because of the above check. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 26 +++--- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1eda71a..c6e9156 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector) } static bool -intel_hdmi_set_edid(struct drm_connector *connector) +intel_hdmi_set_edid(struct drm_connector *connector, bool force) { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *intel_encoder = &hdmi_to_dig_port(intel_hdmi)->base; enum intel_display_power_domain power_domain; - struct edid *edid; + struct edid *edid = NULL; bool connected = false; power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + if (force) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain); @@ -1374,6 +1375,17 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder) enc_to_intel_hdmi(&intel_encoder->base); struct intel_connector *intel_connector = intel_hdmi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); + bool live_status = false; + unsigned int retry = 3; + + do { + live_status = intel_digital_port_connected(dev_priv, + hdmi_to_dig_port(intel_hdmi)); + if (live_status) + break; + mdelay(10); + } while (retry--); /* * We are here, means there is a hotplug or a force
[Intel-gfx] [PATCH] drm/i915: Call encoder hot_plug hook only for hdmi
If the same port is enumerated as hdmi as well as DP, this will call hot_plug hook for DP as well which is not required here. This splitting of edid read and detect is done only for HDMI with this series. v2: Avoid breaking DP hpd. Also corrected the commit message and description accordingly. (Daniel) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hotplug.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index 53c0173..ff4692a 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -331,7 +331,8 @@ static void i915_hotplug_work_func(struct work_struct *work) if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n", connector->name, intel_encoder->hpd_pin); - if (intel_encoder->hot_plug) + if (intel_encoder->hot_plug + && connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) intel_encoder->hot_plug(intel_encoder); if (intel_hpd_irq_event(dev, connector)) changed = true; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Check live status before reading edid
Adding this for SKL onwards. v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions to check digital port status. Adding a separate function to get bxt live status (Daniel) v3: Using intel_encoder->hpd_pin to check the live status (Siva) Moving the live status read to intel_hdmi_probe and passing parameter to read/not to read the edid. (me) v4: * Added live status check for all platforms using intel_digital_port_connected. * Rebased on top of Jani's DP cleanup series * Some monitors take time in setting the live status. So retry for few times if this is a connect HPD v5: Removed extra "drm/i915" from commit message. Adding Shashank's sob which was missed. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 35 --- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1eda71a..d82887b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector) } static bool -intel_hdmi_set_edid(struct drm_connector *connector) +intel_hdmi_set_edid(struct drm_connector *connector, bool force) { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *intel_encoder = &hdmi_to_dig_port(intel_hdmi)->base; enum intel_display_power_domain power_domain; - struct edid *edid; + struct edid *edid = NULL; bool connected = false; power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + if (force) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain); @@ -1374,6 +1375,26 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder) enc_to_intel_hdmi(&intel_encoder->base); struct intel_connector *intel_connector = intel_hdmi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); + bool live_status = false; + unsigned int retry = 3; + + live_status = intel_digital_port_connected(dev_priv, + hdmi_to_dig_port(intel_hdmi)); + if (!intel_connector->detect_edid && live_status == false) { + /* +* Hotplug had occurred and old status was disconnected, +* so it might be possible that live status is not set, +* so retry for few times +*/ + do { + mdelay(10); + live_status = intel_digital_port_connected(dev_priv, + hdmi_to_dig_port(intel_hdmi)); + if (live_status) + break; + } while (retry--); + } /* * We are here, means there is a hotplug or a force @@ -1381,7 +1402,7 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder) * DDC bus to check the current status of HDMI. */ intel_hdmi_unset_edid(&intel_connector->base); - if (intel_hdmi_set_edid(&intel_connector->base)) + if (intel_hdmi_set_edid(&intel_connector->base, live_status)) DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); else DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); @@ -1432,7 +1453,7 @@ intel_hdmi_force(struct drm_connector *connector) if (connector->status != connector_status_connected) return; - intel_hdmi_set_edid(connector); + intel_hdmi_set_edid(connector, true); hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/6] drm/i915: add attached connector to hdmi container
From: Shashank Sharma This patch adds the intel_connector initialized to intel_hdmi display, during the init phase, just like the other encoders do. This attachment is very useful when we need to extract the connector pointer during the hotplug handler function Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_hdmi.c |1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c61ba47..b6c2c20 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -667,6 +667,7 @@ struct intel_hdmi { enum hdmi_force_audio force_audio; bool rgb_quant_range_selectable; enum hdmi_picture_aspect aspect_ratio; + struct intel_connector *attached_connector; void (*write_infoframe)(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index ed25f64..5bdb386 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2107,6 +2107,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); + intel_hdmi->attached_connector = intel_connector; /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 5/6] drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func
If the same port is enumerated as hdmi as well as DP, this will get called for DP connector as well which is not required because i915_hotplug_work_func is solely to handle hdmi HPD. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hotplug.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index 53c0173..8e1c43e 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -325,7 +325,8 @@ static void i915_hotplug_work_func(struct work_struct *work) list_for_each_entry(connector, &mode_config->connector_list, head) { intel_connector = to_intel_connector(connector); - if (!intel_connector->encoder) + if (!intel_connector->encoder + && connector->connector_type != DRM_MODE_CONNECTOR_HDMIA) continue; intel_encoder = intel_connector->encoder; if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/6] drm/i915: drm/i915: Check live status before reading edid
The Bspec is very clear that Live status must be checked about before trying to read EDID over DDC channel. This patch makes sure that HDMI EDID is read only when live status us up. The live status doesn't seem to perform very consistent across various platforms when tested with different monitors. The reason behind that is some monitors are late to provide right voltage to set live_status up. So, after getting the interrupt, for a small duration, live status reg fluctuates, and then settles down showing the correct staus. This is explained here in, in a rough way: HPD line |\ T1 = Monitor Hotplug causing IRQ | \__ | | | | | | T2 = Live status is stable | | _ | | /| Live status _|_|/ | | | | | | | | | | T0 T1 T2 (Between T1 and T2 Live status fluctuates or can be even low, depending on the monitor) After several experiments, we have concluded that a max delay of 30ms is enough to allow the live status to settle down with most of the monitors. This total delay of 30ms has been split into a resolution of 3 retries of 10ms each, for the better cases. This delay is kept at 30ms, keeping in consideration that, HDCP compliance expect the HPD handler to respond a plug out in 100ms, by disabling the port. v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions to check digital port status. Adding a separate function to get bxt live status (Daniel) v3: Using intel_encoder->hpd_pin to check the live status (Siva) Moving the live status read to intel_hdmi_probe and passing parameter to read/not to read the edid. (me) v4: * Added live status check for all platforms using intel_digital_port_connected. * Rebased on top of Jani's DP cleanup series * Some monitors take time in setting the live status. So retry for few times if this is a connect HPD Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 35 --- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1eda71a..d82887b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1329,22 +1329,23 @@ intel_hdmi_unset_edid(struct drm_connector *connector) } static bool -intel_hdmi_set_edid(struct drm_connector *connector) +intel_hdmi_set_edid(struct drm_connector *connector, bool force) { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *intel_encoder = &hdmi_to_dig_port(intel_hdmi)->base; enum intel_display_power_domain power_domain; - struct edid *edid; + struct edid *edid = NULL; bool connected = false; power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + if (force) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain); @@ -1374,6 +1375,26 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder) enc_to_intel_hdmi(&intel_encoder->base); struct intel_connector *intel_connector = intel_hdmi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); + bool live_status = false; + unsigned int retry = 3; + + live_status = intel_digital_port_connected(dev_priv, + hdmi_to_dig_port(intel_hdmi)); + if (!intel_connector->detect_edid && live_status == false) { + /* +* Hotplug had occurred and old status was disconnected, +* so it might be possible that live status is not set, +* so retry for few times +*/ + do { + mdelay(10); + live_status = intel_digital_port_connected(dev_priv, + hdmi_to_dig_port(intel_hdmi)); + if (live_status) + break; + } while (retry--); + } /* * We are here, means the
[Intel-gfx] [PATCH 2/6] drm/i915: Add HDMI probe function
From: Shashank Sharma This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector his probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. v2: Calling set_edid instead of hdmi_probe during init. Also, for platforms having DDI, intel_encoder for DP and HDMI is same (taken from intel_dig_port), so for DP also, hot_plug function gets called which is not intended here. So, check for HDMI in intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV. v3: Dropping the gen < 8 || !VLV check. Now all platforms should rely on hotplug or init for updating the edid.(Daniel) Also, calling hdmi_probe in init instead of set_edid Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 46 - 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 5bdb386..1eda71a 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1368,23 +1368,53 @@ intel_hdmi_set_edid(struct drm_connector *connector) return connected; } +void intel_hdmi_probe(struct intel_encoder *intel_encoder) +{ + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); + /* +* There are many userspace calls which probe EDID from +* detect path. In case of multiple hotplug/unplug, these +* can cause race conditions while probing EDID. Also its +* waste of CPU cycles to read the EDID again and again +* unless there is a real hotplug. +* So, rely on hotplugs and init to read edid. +* Check connector status based on availability of cached EDID. +*/ - intel_hdmi_unset_edid(connector); - - if (intel_hdmi_set_edid(connector)) { + if (intel_connector->detect_edid) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; status = connector_status_connected; - } else + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + DRM_DEBUG_DRIVER("hdmi status = connected\n"); + } else { status = connector_status_disconnected; + DRM_DEBUG_DRIVER("hdmi status = disconnected\n"); + } return status; } @@ -2104,11 +2134,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector->unregister = intel_connector_unregister; intel_hdmi_add_properties(intel_hdmi, connector); + intel_encoder->hot_plug = intel_hdmi_probe; in
[Intel-gfx] [PATCH 6/6] drm/i915/bxt: Fix irq_port for eDP
From: Durgadoss R Currently, HDMI hotplug with eDP as local panel is failing because the HDMI hpd is detected as a long hpd for eDP; and is thus rightfully ignored. But, it should really be handled as an interrupt on port B for HDMI (due to BXT A1 platform having HPD pins A and B swapped). This patch sets the irq_port[PORT_A] to NULL in case eDP is on port A so that irq handler does not treat it as a 'dig_port' interrupt. Signed-off-by: Durgadoss R --- drivers/gpu/drm/i915/intel_ddi.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 4823184..fec51df 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3218,15 +3218,20 @@ void intel_ddi_init(struct drm_device *dev, enum port port) goto err; intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; + dev_priv->hotplug.irq_port[port] = intel_dig_port; /* * On BXT A0/A1, sw needs to activate DDIA HPD logic and * interrupts to check the external panel connection. +* If eDP is connected on port A, set irq_port to NULL +* so that we do not assume an interrupt here as a +* 'dig_port' interrupt. */ - if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0) -&& port == PORT_B) - dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port; - else - dev_priv->hotplug.irq_port[port] = intel_dig_port; + if (IS_BROXTON(dev) && (INTEL_REVID(dev) < BXT_REVID_B0)) { + if (port == PORT_B) + dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port; + else if (intel_encoder->type == INTEL_OUTPUT_EDP) + dev_priv->hotplug.irq_port[port] = NULL; + } } /* In theory we don't need the encoder->type check, but leave it just in -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/6] HDMI optimization series
This series adds changes in HDMI detection methods and also afew optimization. The overview of changes are: 1. HDMI EDID is read only at the hot-plug time. 2. EDID is cached in connectoer on hotplug,and released from cache only on the hot-unplug. 3. In between, for all detetct calls, only cached EDID is used. 4. HDMI EDID is read, only when live status is up. 5. HDMI is force probed during the connector init time, for connected boot scenarios. v2: Some refactoring is with this series. Also, right now this is done for platforms gen7 and above because we couldn't test with older platforms. For newer platforms it works reliably. For HPD and live status to work on SKL, following patch is required: "drm/i915: Handle HPD when it has actually occurred" v3: Added retrial for live_status. Relying on HPD fpr edid detection onlyfrom gen 8 onwards and VLV v4: *Also, including durga's patch for fixing irq_port for edp. Without this fix, hdmi hpd breaks with hdmi and edp connected on bxt. *Taking off the check for older platforms and now rely on init and hotplug to get the edid updated *Some other cleanups. Durgadoss R (1): drm/i915/bxt: Fix irq_port for eDP Shashank Sharma (2): drm/i915: add attached connector to hdmi container drm/i915: Add HDMI probe function Sonika Jindal (3): drm/i915: Make intel_digital_port_connected global drm/i915: drm/i915: Check live status before reading edid drm/i915: drm/i915: Process hpd only for hdmi inside hotplug_work_func drivers/gpu/drm/i915/intel_ddi.c | 15 --- drivers/gpu/drm/i915/intel_dp.c | 11 +++-- drivers/gpu/drm/i915/intel_drv.h |3 ++ drivers/gpu/drm/i915/intel_hdmi.c| 80 +- drivers/gpu/drm/i915/intel_hotplug.c |3 +- 5 files changed, 90 insertions(+), 22 deletions(-) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/6] drm/i915: Make intel_digital_port_connected global
This is to allow live status check for HDMI as well. Also, using intel_encoder->hpd_pin to check the live status for bxt because of BXT A0/A1 WA for HPD pins. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c | 11 +++ drivers/gpu/drm/i915/intel_drv.h |2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 796f930..fedf6d1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4663,11 +4663,14 @@ static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv, } static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, - struct intel_digital_port *port) + struct intel_digital_port *intel_dig_port) { + struct intel_encoder *intel_encoder = &intel_dig_port->base; + enum port port; u32 bit; - switch (port->port) { + intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port); + switch (port) { case PORT_A: bit = BXT_DE_PORT_HP_DDIA; break; @@ -4678,7 +4681,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, bit = BXT_DE_PORT_HP_DDIC; break; default: - MISSING_CASE(port->port); + MISSING_CASE(port); return false; } @@ -4692,7 +4695,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, * * Return %true if @port is connected, %false otherwise. */ -static bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *port) { if (HAS_PCH_IBX(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b6c2c20..ac6d748 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1210,6 +1210,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); void intel_edp_drrs_invalidate(struct drm_device *dev, unsigned frontbuffer_bits); void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, +struct intel_digital_port *port); /* intel_dp_mst.c */ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: Fix irq_port for eDP
From: Durgadoss R Currently, HDMI hotplug with eDP as local panel is failing because the HDMI hpd is detected as a long hpd for eDP; and is thus rightfully ignored. But, it should really be handled as an interrupt on port B for HDMI (due to BXT A1 platform having HPD pins A and B swapped). This patch sets the irq_port[PORT_A] to NULL in case eDP is on port A so that irq handler does not treat it as a 'dig_port' interrupt. v2 (Sonika): Moving the setting of irq_port for BXT WA outside so that this can be set for both hdmi or dp ports. For HDMI this is required because we get interrupts for portB on the hpd line of portA for BXT A0/A1. This issue occurred because hpd on edp was not disabled which was done as part of "drm/i915: Dont enable hpd for eDP" from the series: http://lists.freedesktop.org/archives/intel-gfx/2015-August/073266.html This patch can be squashed to : commit cf1d58833f07afbb4534b15caa3fd48baa313b2c Author: Sonika Jindal Date: Mon Aug 10 10:35:36 2015 +0530 drm/i915/bxt: WA for swapped HPD pins in A stepping Signed-off-by: Durgadoss R Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 56d778f..bba0cb6 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3242,15 +3242,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) goto err; intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; - /* -* On BXT A0/A1, sw needs to activate DDIA HPD logic and -* interrupts to check the external panel connection. -*/ - if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0) -&& port == PORT_B) - dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port; - else - dev_priv->hotplug.irq_port[port] = intel_dig_port; + dev_priv->hotplug.irq_port[port] = intel_dig_port; } /* In theory we don't need the encoder->type check, but leave it just in @@ -3259,6 +3251,17 @@ void intel_ddi_init(struct drm_device *dev, enum port port) if (!intel_ddi_init_hdmi_connector(intel_dig_port)) goto err; } + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) { + if (port == PORT_B) { + dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port; + intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; + } else if (intel_encoder->type == INTEL_OUTPUT_EDP) + dev_priv->hotplug.irq_port[port] = NULL; + } return; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/4] HDMI optimization series
This series adds some optimization related to reading of edid only when required and when live status says so. The comments in the patches explain more. v2: Some refactoring is with this series. Also, right now this is done for platforms gen7 and above because we couldn't test with older platforms. For newer platforms it works reliably. For HPD and live status to work on SKL, following patch is required: "drm/i915: Handle HPD when it has actually occurred" v3: Added retrial for live_status. Relying on HPD fpr edid detection onlyfrom gen 8 onwards and VLV Shashank Sharma (2): drm/i915: add attached connector to hdmi container drm/i915: Add HDMI probe function Sonika Jindal (2): drm/i915: Check live status before reading edid drm/i915: Retry for live status drivers/gpu/drm/i915/intel_dp.c |4 +- drivers/gpu/drm/i915/intel_drv.h |3 + drivers/gpu/drm/i915/intel_hdmi.c | 130 + 3 files changed, 123 insertions(+), 14 deletions(-) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/4] drm/i915: Retry for live status
Some monitors take time in setting the live status. So retry for few times if this is a connect HPD Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 59518b4..239d70d 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1415,6 +1415,7 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder) struct intel_connector *intel_connector = intel_hdmi->attached_connector; bool live_status = false; + unsigned int retry = 3; /* * Sometimes DDI ports are enumerated as DP as well as HDMI and @@ -1425,6 +1426,20 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder) return; live_status = intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi)); + if (!intel_connector->detect_edid && live_status == false) { + /* +* Hotplug had occurred and old status was disconnected, +* so it might be possible that live status is not set, +* so retry for few times +*/ + do { + mdelay(10); + live_status = intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi)); + if (live_status) + break; + } while (retry--); + } + /* * We are here, means there is a hotplug or a force * detection. Clear the cached EDID and probe the -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/4] drm/i915: Add HDMI probe function
From: Shashank Sharma This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector his probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. v2: Calling set_edid instead of hdmi_probe during init. Also, for platforms having DDI, intel_encoder for DP and HDMI is same (taken from intel_dig_port), so for DP also, hot_plug function gets called which is not intended here. So, check for HDMI in intel_hdmi_probe Rely on HPD for updating edid only for platforms gen > 8 and also for VLV. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 56 + 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 3825507..68886c0 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1368,23 +1368,63 @@ intel_hdmi_set_edid(struct drm_connector *connector) return connected; } +void intel_hdmi_probe(struct intel_encoder *intel_encoder) +{ + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + /* +* Sometimes DDI ports are enumerated as DP as well as HDMI and +* detection is left for runtime. Since DP's detection method already +* takes care of live status checks, do this only for HDMI. +*/ + if (intel_connector->base.connector_type != DRM_MODE_CONNECTOR_HDMIA) + return; + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); + struct drm_device *dev = connector->dev; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); + /* +* There are many userspace calls which probe EDID from +* detect path. In case of multiple hotplug/unplug, these +* can cause race conditions while probing EDID. Also its +* waste of CPU cycles to read the EDID again and again +* unless there is a real hotplug. +* So, reading edid in detect only for older platforms (< gen8) +* Letting the newer platforms rely on hotplugs and init to read edid. +* Check connector status based on availability of cached EDID. +*/ + if (INTEL_INFO(dev)->gen < 8 && !IS_VALLEYVIEW(dev)) + intel_hdmi_probe(intel_connector->encoder); - intel_hdmi_unset_edid(connector); - - if (intel_hdmi_set_edid(connector)) { + if (intel_connector->detect_edid) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; status = connector_status_connected; - } else + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + DRM_DEBUG_DRIVER("hdmi status = connected\n"); + } else {
[Intel-gfx] [PATCH 3/4] drm/i915: Check live status before reading edid
Adding this for SKL onwards. v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions to check digital port status. Adding a separate function to get bxt live status (Daniel) v3: Using intel_encoder->hpd_pin to check the live status (Siva) Moving the live status read to intel_hdmi_probe and passing parameter to read/not to read the edid. (me) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c |4 +-- drivers/gpu/drm/i915/intel_drv.h |2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 62 - 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b905c19..8f2eba2 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4477,8 +4477,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) return intel_dp_detect_dpcd(intel_dp); } -static int g4x_digital_port_connected(struct drm_device *dev, - struct intel_digital_port *intel_dig_port) +int g4x_digital_port_connected(struct drm_device *dev, + struct intel_digital_port *intel_dig_port) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t bit; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 232b814..b07e141 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1192,6 +1192,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); void intel_edp_drrs_invalidate(struct drm_device *dev, unsigned frontbuffer_bits); void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +int g4x_digital_port_connected(struct drm_device *dev, + struct intel_digital_port *intel_dig_port); /* intel_dp_mst.c */ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 68886c0..59518b4 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1328,23 +1328,63 @@ intel_hdmi_unset_edid(struct drm_connector *connector) to_intel_connector(connector)->detect_edid = NULL; } +static bool bxt_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *intel_dig_port) +{ + struct intel_encoder *intel_encoder = &intel_dig_port->base; + enum port port; + u32 temp = I915_READ(GEN8_DE_PORT_ISR); + + intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port); + switch (port) { + case PORT_A: + return temp & BXT_DE_PORT_HP_DDIA; + + case PORT_B: + return temp & BXT_DE_PORT_HP_DDIB; + + case PORT_C: + return temp & BXT_DE_PORT_HP_DDIC; + + default: + return false; + + } +} + +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) +{ + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + + if (IS_VALLEYVIEW(dev)) + return g4x_digital_port_connected(dev, intel_dig_port); + else if (IS_SKYLAKE(dev) || IS_BROADWELL(dev)) + return ibx_digital_port_connected(dev_priv, intel_dig_port); + else if (IS_BROXTON(dev)) + return bxt_port_connected(dev_priv, intel_dig_port); + + return true; +} + static bool -intel_hdmi_set_edid(struct drm_connector *connector) +intel_hdmi_set_edid(struct drm_connector *connector, bool force) { struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *intel_encoder = &hdmi_to_dig_port(intel_hdmi)->base; enum intel_display_power_domain power_domain; - struct edid *edid; + struct edid *edid = NULL; bool connected = false; power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + if (force) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain); @@ -1374,6 +1414,8 @@ void intel_hdmi_probe(struct intel_encoder *intel_encoder) enc_to_intel_hdmi(&intel_encoder->base); struct intel_connector *intel_connector = intel_hdmi->attached_connector; + bool live_status = false; +
[Intel-gfx] [PATCH 1/4] drm/i915: add attached connector to hdmi container
From: Shashank Sharma This patch adds the intel_connector initialized to intel_hdmi display, during the init phase, just like the other encoders do. This attachment is very useful when we need to extract the connector pointer during the hotplug handler function Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_hdmi.c |1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 81b7d77..232b814 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -666,6 +666,7 @@ struct intel_hdmi { enum hdmi_force_audio force_audio; bool rgb_quant_range_selectable; enum hdmi_picture_aspect aspect_ratio; + struct intel_connector *attached_connector; void (*write_infoframe)(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 7185062..3825507 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2035,6 +2035,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); + intel_hdmi->attached_connector = intel_connector; /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/3] Add BXT A0/A1 WA for HPD swap in generic way
This series adds BXT HPD pin swap WA for A0/A1 by setting right hpd_pin and irq_port for PORT_B. Sonika Jindal (3): drm/i915: Dont enable hpd for eDP drm/i915/bxt: Add HPD support for DDIA drm/i915/bxt: WA for swapped HPD pins in A stepping drivers/gpu/drm/i915/i915_irq.c | 10 +++--- drivers/gpu/drm/i915/intel_ddi.c | 10 +- drivers/gpu/drm/i915/intel_dp.c |4 +++- drivers/gpu/drm/i915/intel_hdmi.c |9 - 4 files changed, 23 insertions(+), 10 deletions(-) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/3] drm/i915: Dont enable hpd for eDP
With HPD support added for all ports including PORT_A, setting hpd_pin will result in enabling of hpd to edp as well. There is no need to enable HPD on PORT_A hence this patch removes hpd_pin update for PORT_A, where edp will be connected. it can be added back when required Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index fcc64e5..5a614c9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5784,7 +5784,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, /* Set up the hotplug pin. */ switch (port) { case PORT_A: - intel_encoder->hpd_pin = HPD_PORT_A; + /* Not enabling edp interrupts */ break; case PORT_B: intel_encoder->hpd_pin = HPD_PORT_B; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/3] drm/i915/bxt: WA for swapped HPD pins in A stepping
WA for BXT A0/A1, where DDIB's HPD pin is swapped to DDIA, so enabling DDIA HPD pin in place of DDIB. v2: For DP, irq_port is used to determine the encoder instead of hpd_pin and removing the edp HPD logic because port A HPD is not present(Imre) v3: Rebased on top of Imre's patchset for enabling HPD on PORT A. Added hpd_pin swapping for intel_dp_init_connector, setting encoder for PORT_A as per the WA in irq_port (Imre) v4: Dont enable interrupt for edp, also reframe the description (Siva) v5: Don’t check for PORT_A in intel_ddi_init to update dig_port, instead avoid setting hpd_pin itself (Imre) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 10 +- drivers/gpu/drm/i915/intel_dp.c |2 ++ drivers/gpu/drm/i915/intel_hdmi.c |9 - 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e2c6f73..777e3a3 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3225,7 +3225,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port) goto err; intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; - dev_priv->hotplug.irq_port[port] = intel_dig_port; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0) +&& port == PORT_B) + dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port; + else + dev_priv->hotplug.irq_port[port] = intel_dig_port; } /* In theory we don't need the encoder->type check, but leave it just in diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5a614c9..7fab3e5 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5788,6 +5788,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, break; case PORT_B: intel_encoder->hpd_pin = HPD_PORT_B; + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; break; case PORT_C: intel_encoder->hpd_pin = HPD_PORT_C; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 70bad5b..94fa716 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1973,7 +1973,14 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT; else intel_hdmi->ddc_bus = GMBUS_PIN_DPB; - intel_encoder->hpd_pin = HPD_PORT_B; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; + else + intel_encoder->hpd_pin = HPD_PORT_B; break; case PORT_C: if (IS_BROXTON(dev_priv)) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/3] drm/i915/bxt: Add HPD support for DDIA
Also remove redundant comments. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_irq.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 02b9e73..9b9533a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -90,6 +90,7 @@ static const u32 hpd_status_i915[HPD_NUM_PINS] = { /* BXT hpd list */ static const u32 hpd_bxt[HPD_NUM_PINS] = { + [HPD_PORT_A] = BXT_DE_PORT_HP_DDIA, [HPD_PORT_B] = BXT_DE_PORT_HP_DDIB, [HPD_PORT_C] = BXT_DE_PORT_HP_DDIC }; @@ -3018,30 +3019,25 @@ static void bxt_hpd_irq_setup(struct drm_device *dev) u32 hotplug_port = 0; u32 hotplug_ctrl; - /* Now, enable HPD */ for_each_intel_encoder(dev, intel_encoder) { if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED) hotplug_port |= hpd_bxt[intel_encoder->hpd_pin]; } - /* Mask all HPD control bits */ hotplug_ctrl = I915_READ(BXT_HOTPLUG_CTL) & ~BXT_HOTPLUG_CTL_MASK; - /* Enable requested port in hotplug control */ - /* TODO: implement (short) HPD support on port A */ - WARN_ON_ONCE(hotplug_port & BXT_DE_PORT_HP_DDIA); + if (hotplug_port & BXT_DE_PORT_HP_DDIA) + hotplug_ctrl |= BXT_DDIA_HPD_ENABLE; if (hotplug_port & BXT_DE_PORT_HP_DDIB) hotplug_ctrl |= BXT_DDIB_HPD_ENABLE; if (hotplug_port & BXT_DE_PORT_HP_DDIC) hotplug_ctrl |= BXT_DDIC_HPD_ENABLE; I915_WRITE(BXT_HOTPLUG_CTL, hotplug_ctrl); - /* Unmask DDI hotplug in IMR */ hotplug_ctrl = I915_READ(GEN8_DE_PORT_IMR) & ~hotplug_port; I915_WRITE(GEN8_DE_PORT_IMR, hotplug_ctrl); - /* Enable DDI hotplug in IER */ hotplug_ctrl = I915_READ(GEN8_DE_PORT_IER) | hotplug_port; I915_WRITE(GEN8_DE_PORT_IER, hotplug_ctrl); POSTING_READ(GEN8_DE_PORT_IER); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: WA for swapped HPD pins in A stepping
WA for BXT A0/A1, where DDIB's HPD pin is swapped to DDIA, so enabling DDIA HPD pin in place of DDIB. v2: For DP, irq_port is used to determine the encoder instead of hpd_pin and removing the edp HPD logic because port A HPD is not present(Imre) v3: Rebased on top of Imre's patchset for enabling HPD on PORT A. Added hpd_pin swapping for intel_dp_init_connector, setting encoder for PORT_A as per the WA in irq_port (Imre) v4: Dont enable interrupt for edp, also reframe the description (Siva) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 11 ++- drivers/gpu/drm/i915/intel_dp.c |4 drivers/gpu/drm/i915/intel_hdmi.c |9 - 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e2c6f73..8d7ffe0 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3225,7 +3225,16 @@ void intel_ddi_init(struct drm_device *dev, enum port port) goto err; intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; - dev_priv->hotplug.irq_port[port] = intel_dig_port; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0) +&& port == PORT_B) + dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port; + /* Dont enable interrupts for edp*/ + else if (port != PORT_A) + dev_priv->hotplug.irq_port[port] = intel_dig_port; } /* In theory we don't need the encoder->type check, but leave it just in diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index fcc64e5..71679ef 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5785,9 +5785,13 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, switch (port) { case PORT_A: intel_encoder->hpd_pin = HPD_PORT_A; + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_C; break; case PORT_B: intel_encoder->hpd_pin = HPD_PORT_B; + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; break; case PORT_C: intel_encoder->hpd_pin = HPD_PORT_C; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 70bad5b..94fa716 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1973,7 +1973,14 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT; else intel_hdmi->ddc_bus = GMBUS_PIN_DPB; - intel_encoder->hpd_pin = HPD_PORT_B; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; + else + intel_encoder->hpd_pin = HPD_PORT_B; break; case PORT_C: if (IS_BROXTON(dev_priv)) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: WA for swapped HPD pins in A stepping
As per bspec, on BXT A0/A1, sw needs to activate DDIA HPD logic and interrupts to check the external panel connection and DDIC HPD logic for edp panel. v2: For DP, irq_port is used to determine the encoder instead of hpd_pin and removing the edp HPD logic because port A HPD is not present(Imre) v3: Rebased on top of Imre's patchset for enabling HPD on PORT A. Added hpd_pin swapping for intel_dp_init_connector, setting encoder for PORT_A as per the WA in irq_port (Imre) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 12 +++- drivers/gpu/drm/i915/intel_dp.c |4 drivers/gpu/drm/i915/intel_hdmi.c |9 - 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e2c6f73..d5745e2 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3225,7 +3225,17 @@ void intel_ddi_init(struct drm_device *dev, enum port port) goto err; intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; - dev_priv->hotplug.irq_port[port] = intel_dig_port; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) { + if (port == PORT_B) + dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port; + else if (port == PORT_A) + dev_priv->hotplug.irq_port[PORT_C] = intel_dig_port; + } else + dev_priv->hotplug.irq_port[port] = intel_dig_port; } /* In theory we don't need the encoder->type check, but leave it just in diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index fcc64e5..71679ef 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5785,9 +5785,13 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, switch (port) { case PORT_A: intel_encoder->hpd_pin = HPD_PORT_A; + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_C; break; case PORT_B: intel_encoder->hpd_pin = HPD_PORT_B; + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; break; case PORT_C: intel_encoder->hpd_pin = HPD_PORT_C; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 70bad5b..94fa716 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1973,7 +1973,14 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT; else intel_hdmi->ddc_bus = GMBUS_PIN_DPB; - intel_encoder->hpd_pin = HPD_PORT_B; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; + else + intel_encoder->hpd_pin = HPD_PORT_B; break; case PORT_C: if (IS_BROXTON(dev_priv)) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: Update HAS_PSR macro to include all gen>=8 platforms
This is to get PSR support for bxt. v2: Adding bxt prefix in title (Damien) Signed-off-by: Sonika Jindal Reviewed-by: Damien Lespiau --- drivers/gpu/drm/i915/i915_drv.h |5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 718170c..54d2729 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2537,9 +2537,8 @@ struct drm_i915_cmd_table { #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) #define HAS_FPGA_DBG_UNCLAIMED(dev)(INTEL_INFO(dev)->has_fpga_dbg) -#define HAS_PSR(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev) || \ -IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || \ -IS_SKYLAKE(dev)) +#define HAS_PSR(dev) (IS_HASWELL(dev) || IS_VALLEYVIEW(dev) || \ +INTEL_INFO(dev)->gen >= 8) #define HAS_RUNTIME_PM(dev)(IS_GEN6(dev) || IS_HASWELL(dev) || \ IS_BROADWELL(dev) || IS_VALLEYVIEW(dev) || \ IS_SKYLAKE(dev)) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Update HAS_PSR macro to include all gen>=8 platforms
This is to get PSR support for bxt. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_drv.h |5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 718170c..54d2729 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2537,9 +2537,8 @@ struct drm_i915_cmd_table { #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) #define HAS_FPGA_DBG_UNCLAIMED(dev)(INTEL_INFO(dev)->has_fpga_dbg) -#define HAS_PSR(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev) || \ -IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || \ -IS_SKYLAKE(dev)) +#define HAS_PSR(dev) (IS_HASWELL(dev) || IS_VALLEYVIEW(dev) || \ +INTEL_INFO(dev)->gen >= 8) #define HAS_RUNTIME_PM(dev)(IS_GEN6(dev) || IS_HASWELL(dev) || \ IS_BROADWELL(dev) || IS_VALLEYVIEW(dev) || \ IS_SKYLAKE(dev)) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: WA for swapped HPD pins in A stepping
As per bspec, on BXT A0/A1, sw needs to activate DDIA HPD logic and interrupts to check the external panel connection and DDIC HPD logic for edp panel. v2: For DP, irq_port is used to determine the encoder instead of hpd_pin and removing the edp HPD logic because port A HPD is not present(Imre) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 10 +- drivers/gpu/drm/i915/intel_hdmi.c |9 - 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e2c6f73..777e3a3 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3225,7 +3225,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port) goto err; intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; - dev_priv->hotplug.irq_port[port] = intel_dig_port; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0) +&& port == PORT_B) + dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port; + else + dev_priv->hotplug.irq_port[port] = intel_dig_port; } /* In theory we don't need the encoder->type check, but leave it just in diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 70bad5b..94fa716 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1973,7 +1973,14 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT; else intel_hdmi->ddc_bus = GMBUS_PIN_DPB; - intel_encoder->hpd_pin = HPD_PORT_B; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; + else + intel_encoder->hpd_pin = HPD_PORT_B; break; case PORT_C: if (IS_BROXTON(dev_priv)) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/3] drm/i915: add attached connector to hdmi container
From: Shashank Sharma This patch adds the intel_connector initialized to intel_hdmi display, during the init phase, just like the other encoders do. This attachment is very useful when we need to extract the connector pointer during the hotplug handler function Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_hdmi.c |1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e90c743..a47fbc3 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -659,6 +659,7 @@ struct intel_hdmi { enum hdmi_force_audio force_audio; bool rgb_quant_range_selectable; enum hdmi_picture_aspect aspect_ratio; + struct intel_connector *attached_connector; void (*write_infoframe)(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 00c4b40..af4d1e6 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2000,6 +2000,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); + intel_hdmi->attached_connector = intel_connector; /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/3] drm/i915: Check live status before reading edid
Adding this for SKL onwards. v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions to check digital port status. Adding a separate function to get bxt live status (Daniel) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c |4 ++-- drivers/gpu/drm/i915/intel_drv.h |2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 43 + 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4ebfc3a..7b54b9d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4443,8 +4443,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) return intel_dp_detect_dpcd(intel_dp); } -static int g4x_digital_port_connected(struct drm_device *dev, - struct intel_digital_port *intel_dig_port) +int g4x_digital_port_connected(struct drm_device *dev, + struct intel_digital_port *intel_dig_port) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t bit; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a47fbc3..30c8dd6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1187,6 +1187,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); void intel_edp_drrs_invalidate(struct drm_device *dev, unsigned frontbuffer_bits); void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +int g4x_digital_port_connected(struct drm_device *dev, + struct intel_digital_port *intel_dig_port); /* intel_dp_mst.c */ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index c4b82ce..402be54 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1300,6 +1300,40 @@ intel_hdmi_unset_edid(struct drm_connector *connector) to_intel_connector(connector)->detect_edid = NULL; } +static bool bxt_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + u32 temp = I915_READ(GEN8_DE_PORT_ISR); + + /* TODO: Add bxt A0/A1 wa related to hpd pin swap */ + switch (port->port) { + case PORT_B: + return temp & BXT_DE_PORT_HP_DDIB; + + case PORT_C: + return temp & BXT_DE_PORT_HP_DDIC; + + default: + return false; + + } +} + +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) +{ + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + + if (IS_VALLEYVIEW(dev)) + return g4x_digital_port_connected(dev, intel_dig_port); + else if (IS_SKYLAKE(dev)) + return ibx_digital_port_connected(dev_priv, intel_dig_port); + else if (IS_BROXTON(dev)) + return bxt_port_connected(dev_priv, intel_dig_port); + + return true; +} + static bool intel_hdmi_set_edid(struct drm_connector *connector) { @@ -1308,15 +1342,16 @@ intel_hdmi_set_edid(struct drm_connector *connector) struct intel_encoder *intel_encoder = &hdmi_to_dig_port(intel_hdmi)->base; enum intel_display_power_domain power_domain; - struct edid *edid; + struct edid *edid = NULL; bool connected = false; power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + if (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/3] HDMI optimization series
This series adds some optimization related to reading of edid only when required and when live status says so. The comments in the patches explain more. v2: Some refactoring is with this series. Also, right now this is done for platforms gen7 and above because we couldn't test with older platforms. For newer platforms it works reliably. For HPD and live status to work on SKL, following patch is required: "drm/i915: Handle HPD when it has actually occurred" Shashank Sharma (2): drm/i915: add attached connector to hdmi container drm/i915: Add HDMI probe function Sonika Jindal (1): drm/i915: Check live status before reading edid drivers/gpu/drm/i915/intel_dp.c |4 +- drivers/gpu/drm/i915/intel_drv.h |3 ++ drivers/gpu/drm/i915/intel_hdmi.c | 93 + 3 files changed, 88 insertions(+), 12 deletions(-) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/3] drm/i915: Add HDMI probe function
From: Shashank Sharma This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. During init_connector this probe will be called to read the edid 3. Reuse the cached EDID in hdmi_detect() function. The "< gen7" check is there because this was tested only for >=gen7 platforms. For older platforms the hotplug/reading edid path remains same. Signed-off-by: Shashank Sharma Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 49 - 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index af4d1e6..c4b82ce 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1340,23 +1340,56 @@ intel_hdmi_set_edid(struct drm_connector *connector) return connected; } +void intel_hdmi_probe(struct intel_encoder *intel_encoder) +{ + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); + struct drm_device *dev = connector->dev; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); + /* +* There are many userspace calls which probe EDID from +* detect path. In case of multiple hotplug/unplug, these +* can cause race conditions while probing EDID. Also its +* waste of CPU cycles to read the EDID again and again +* unless there is a real hotplug. +* So, reading edid in detect only for older platforms (< gen7) +* Letting the newer platforms rely on hotplugs and init to read edid. +* Check connector status based on availability of cached EDID. +*/ + if (INTEL_INFO(dev)->gen < 7) + intel_hdmi_probe(intel_connector->encoder); - intel_hdmi_unset_edid(connector); - - if (intel_hdmi_set_edid(connector)) { + if (intel_connector->detect_edid) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; status = connector_status_connected; - } else + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + DRM_DEBUG_DRIVER("hdmi status = connected\n"); + } else { status = connector_status_disconnected; + DRM_DEBUG_DRIVER("hdmi status = disconnected\n"); + } return status; } @@ -1997,11 +2030,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector->unregister = intel_connector_unregister; intel_hdmi_add_properties(intel_hdmi, connector); + intel_encoder->hot_plug = intel_hdmi_probe; intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); intel_hdmi->attached_connector = intel_connector; + /* Set edid during init */ + intel_hdmi_probe(intel_encoder); + /* For G
[Intel-gfx] [PATCH 2/2] drm/i915/bxt: WA for swapped HPD pins in A stepping
As per bspec, on BXT A0/A1, sw needs to activate DDIA HPD logic and interrupts to check the external panel connection and DDIC HPD logic for edp panel. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c | 18 -- drivers/gpu/drm/i915/intel_hdmi.c |9 - 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7b54b9d..c32f3d3 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5869,10 +5869,24 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, /* Set up the hotplug pin. */ switch (port) { case PORT_A: - intel_encoder->hpd_pin = HPD_PORT_A; + /* +* On BXT A0/A1, sw needs to activate DDIC HPD logic and +* interrupts to check the eDP panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_C; + else + intel_encoder->hpd_pin = HPD_PORT_A; break; case PORT_B: - intel_encoder->hpd_pin = HPD_PORT_B; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; + else + intel_encoder->hpd_pin = HPD_PORT_B; break; case PORT_C: intel_encoder->hpd_pin = HPD_PORT_C; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 44e7160..121e626 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2011,7 +2011,14 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT; else intel_hdmi->ddc_bus = GMBUS_PIN_DPB; - intel_encoder->hpd_pin = HPD_PORT_B; + /* +* On BXT A0/A1, sw needs to activate DDIA HPD logic and +* interrupts to check the external panel connection. +*/ + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; + else + intel_encoder->hpd_pin = HPD_PORT_B; break; case PORT_C: if (IS_BROXTON(dev_priv)) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915/bxt: Add HPD support for DDIA
Also remove redundant comments. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_irq.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a897f68..63137dd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -90,6 +90,7 @@ static const u32 hpd_status_i915[HPD_NUM_PINS] = { /* BXT hpd list */ static const u32 hpd_bxt[HPD_NUM_PINS] = { + [HPD_PORT_A] = BXT_DE_PORT_HP_DDIA, [HPD_PORT_B] = BXT_DE_PORT_HP_DDIB, [HPD_PORT_C] = BXT_DE_PORT_HP_DDIC }; @@ -3022,30 +3023,25 @@ static void bxt_hpd_irq_setup(struct drm_device *dev) u32 hotplug_port = 0; u32 hotplug_ctrl; - /* Now, enable HPD */ for_each_intel_encoder(dev, intel_encoder) { if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED) hotplug_port |= hpd_bxt[intel_encoder->hpd_pin]; } - /* Mask all HPD control bits */ hotplug_ctrl = I915_READ(BXT_HOTPLUG_CTL) & ~BXT_HOTPLUG_CTL_MASK; - /* Enable requested port in hotplug control */ - /* TODO: implement (short) HPD support on port A */ - WARN_ON_ONCE(hotplug_port & BXT_DE_PORT_HP_DDIA); + if (hotplug_port & BXT_DE_PORT_HP_DDIA) + hotplug_ctrl |= BXT_DDIA_HPD_ENABLE; if (hotplug_port & BXT_DE_PORT_HP_DDIB) hotplug_ctrl |= BXT_DDIB_HPD_ENABLE; if (hotplug_port & BXT_DE_PORT_HP_DDIC) hotplug_ctrl |= BXT_DDIC_HPD_ENABLE; I915_WRITE(BXT_HOTPLUG_CTL, hotplug_ctrl); - /* Unmask DDI hotplug in IMR */ hotplug_ctrl = I915_READ(GEN8_DE_PORT_IMR) & ~hotplug_port; I915_WRITE(GEN8_DE_PORT_IMR, hotplug_ctrl); - /* Enable DDI hotplug in IER */ hotplug_ctrl = I915_READ(GEN8_DE_PORT_IER) | hotplug_port; I915_WRITE(GEN8_DE_PORT_IER, hotplug_ctrl); POSTING_READ(GEN8_DE_PORT_IER); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Check live status before reading edid
Adding this for SKL onwards. v2: Adding checks for VLV/CHV as well. Reusing old ibx and g4x functions to check digital port status. Adding a separate function to get bxt live status (Daniel) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c |4 ++-- drivers/gpu/drm/i915/intel_drv.h |2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 42 + 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4ebfc3a..7b54b9d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4443,8 +4443,8 @@ ironlake_dp_detect(struct intel_dp *intel_dp) return intel_dp_detect_dpcd(intel_dp); } -static int g4x_digital_port_connected(struct drm_device *dev, - struct intel_digital_port *intel_dig_port) +int g4x_digital_port_connected(struct drm_device *dev, + struct intel_digital_port *intel_dig_port) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t bit; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a47fbc3..30c8dd6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1187,6 +1187,8 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp); void intel_edp_drrs_invalidate(struct drm_device *dev, unsigned frontbuffer_bits); void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); +int g4x_digital_port_connected(struct drm_device *dev, + struct intel_digital_port *intel_dig_port); /* intel_dp_mst.c */ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1fb6919..7eb0d0e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1300,6 +1300,39 @@ intel_hdmi_unset_edid(struct drm_connector *connector) to_intel_connector(connector)->detect_edid = NULL; } +static bool bxt_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + u32 temp = I915_READ(GEN8_DE_PORT_ISR); + + switch (port->port) { + case PORT_B: + return temp & BXT_DE_PORT_HP_DDIB; + + case PORT_C: + return temp & BXT_DE_PORT_HP_DDIC; + + default: + return false; + + } +} + +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) +{ + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + + if (IS_VALLEYVIEW(dev)) + return g4x_digital_port_connected(dev, intel_dig_port); + else if (IS_SKYLAKE(dev)) + return ibx_digital_port_connected(dev_priv, intel_dig_port); + else if (IS_BROXTON(dev)) + return bxt_port_connected(dev_priv, intel_dig_port); + + return true; +} + static bool intel_hdmi_set_edid(struct drm_connector *connector) { @@ -1308,15 +1341,16 @@ intel_hdmi_set_edid(struct drm_connector *connector) struct intel_encoder *intel_encoder = &hdmi_to_dig_port(intel_hdmi)->base; enum intel_display_power_domain power_domain; - struct edid *edid; + struct edid *edid = NULL; bool connected = false; power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + if (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Set edid from init and not from detect
During init_connector set the edid, then edid will be set/unset only during hotplug. For the sake of older platforms where HPD is not stable, let edid read happen from detect as well only if it is forced to do so. v2: Removing the 'force' check, instead let detect call read the edid for platforms older than gen 7 (Shashank) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c |6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 66af388..44e7160 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1399,6 +1399,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) enum drm_connector_status status; struct intel_connector *intel_connector = to_intel_connector(connector); + struct drm_device *dev = connector->dev; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -1412,7 +1413,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) * based on availability of cached EDID. This will avoid many of * these race conditions and timing problems. */ - if (force) + if (INTEL_INFO(dev)->gen < 7) intel_hdmi_probe(intel_connector->encoder); if (intel_connector->detect_edid) { @@ -2070,6 +2071,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, drm_connector_register(connector); intel_hdmi->attached_connector = intel_connector; + /* Set edid during init */ + intel_hdmi_probe(intel_encoder); + /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being * generated on the port when a cable is not attached. -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: WA for swapped HPD pins in A stepping
As per bspec, on BXT A0/A1, sw needs to activate DDIA HPD logic and interrupts to check the external panel connection. And remove the redundant comment. v2: Remove redundant IS_BROXTON check, Add comment about port C not connected, and rephrase the commit message to include only what we are doing here (Imre) v3: Add comment about the WA, move 'hpd' initialization outside for loop (Siva) Also, remove few redundant comments from hpd handler (me) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_irq.c | 46 ++- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a897f68..13cabca 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -88,7 +88,14 @@ static const u32 hpd_status_i915[HPD_NUM_PINS] = { [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS }; -/* BXT hpd list */ +/* + * On BXT A0/A1, sw needs to activate DDIA HPD logic and interrupts to check + * the external panel connection. Port C is not connected on bxt A0/A1 + */ +static const u32 hpd_bxt_a0[HPD_NUM_PINS] = { + [HPD_PORT_B] = BXT_DE_PORT_HP_DDIA +}; + static const u32 hpd_bxt[HPD_NUM_PINS] = { [HPD_PORT_B] = BXT_DE_PORT_HP_DDIB, [HPD_PORT_C] = BXT_DE_PORT_HP_DDIC @@ -1967,6 +1974,7 @@ static void bxt_hpd_handler(struct drm_device *dev, uint32_t iir_status) struct drm_i915_private *dev_priv = dev->dev_private; u32 hp_control, hp_trigger; u32 pin_mask, long_mask; + const u32 *hpd; /* Get the status */ hp_trigger = iir_status & BXT_DE_PORT_HOTPLUG_MASK; @@ -1981,7 +1989,12 @@ static void bxt_hpd_handler(struct drm_device *dev, uint32_t iir_status) /* Clear sticky bits in hpd status */ I915_WRITE(BXT_HOTPLUG_CTL, hp_control); - pch_get_hpd_pins(&pin_mask, &long_mask, hp_trigger, hp_control, hpd_bxt); + if (INTEL_REVID(dev) < BXT_REVID_B0) + hpd = hpd_bxt_a0; + else + hpd = hpd_bxt; + + pch_get_hpd_pins(&pin_mask, &long_mask, hp_trigger, hp_control, hpd); intel_hpd_irq_handler(dev, pin_mask, long_mask); } @@ -3021,31 +3034,34 @@ static void bxt_hpd_irq_setup(struct drm_device *dev) struct intel_encoder *intel_encoder; u32 hotplug_port = 0; u32 hotplug_ctrl; + const u32 *hpd; - /* Now, enable HPD */ - for_each_intel_encoder(dev, intel_encoder) { + if (INTEL_REVID(dev) < BXT_REVID_B0) + hpd = hpd_bxt_a0; + else + hpd = hpd_bxt; + + for_each_intel_encoder(dev, intel_encoder) if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state == HPD_ENABLED) - hotplug_port |= hpd_bxt[intel_encoder->hpd_pin]; - } + hotplug_port |= hpd[intel_encoder->hpd_pin]; - /* Mask all HPD control bits */ hotplug_ctrl = I915_READ(BXT_HOTPLUG_CTL) & ~BXT_HOTPLUG_CTL_MASK; - /* Enable requested port in hotplug control */ /* TODO: implement (short) HPD support on port A */ - WARN_ON_ONCE(hotplug_port & BXT_DE_PORT_HP_DDIA); - if (hotplug_port & BXT_DE_PORT_HP_DDIB) - hotplug_ctrl |= BXT_DDIB_HPD_ENABLE; - if (hotplug_port & BXT_DE_PORT_HP_DDIC) - hotplug_ctrl |= BXT_DDIC_HPD_ENABLE; + if (INTEL_REVID(dev) < BXT_REVID_B0 && (hotplug_port & BXT_DE_PORT_HP_DDIA)) + hotplug_ctrl |= BXT_DDIA_HPD_ENABLE; + else { + if (hotplug_port & BXT_DE_PORT_HP_DDIB) + hotplug_ctrl |= BXT_DDIB_HPD_ENABLE; + if (hotplug_port & BXT_DE_PORT_HP_DDIC) + hotplug_ctrl |= BXT_DDIC_HPD_ENABLE; + } I915_WRITE(BXT_HOTPLUG_CTL, hotplug_ctrl); - /* Unmask DDI hotplug in IMR */ hotplug_ctrl = I915_READ(GEN8_DE_PORT_IMR) & ~hotplug_port; I915_WRITE(GEN8_DE_PORT_IMR, hotplug_ctrl); - /* Enable DDI hotplug in IER */ hotplug_ctrl = I915_READ(GEN8_DE_PORT_IER) | hotplug_port; I915_WRITE(GEN8_DE_PORT_IER, hotplug_ctrl); POSTING_READ(GEN8_DE_PORT_IER); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: WA for swapped HPD pins in A stepping
As per bspec, on BXT A0/A1, sw needs to activate DDIA HPD logic and interrupts to check the external panel connection. And remove the redundant comment. v2: Remove redundant IS_BROXTON check, Add comment about port C not connected, and rephrase the commit message to include only what we are doing here (Imre) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_irq.c | 38 +- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index eb52a03..760539c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -88,7 +88,11 @@ static const u32 hpd_status_i915[HPD_NUM_PINS] = { [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS }; -/* BXT hpd list */ +/* Port C is not connected on bxt A0/A1 */ +static const u32 hpd_bxt_a0[HPD_NUM_PINS] = { + [HPD_PORT_B] = BXT_DE_PORT_HP_DDIA +}; + static const u32 hpd_bxt[HPD_NUM_PINS] = { [HPD_PORT_B] = BXT_DE_PORT_HP_DDIB, [HPD_PORT_C] = BXT_DE_PORT_HP_DDIC @@ -2257,6 +2261,7 @@ static void bxt_hpd_handler(struct drm_device *dev, uint32_t iir_status) struct drm_i915_private *dev_priv = dev->dev_private; u32 hp_control, hp_trigger; u32 pin_mask, long_mask; + const u32 *hpd; /* Get the status */ hp_trigger = iir_status & BXT_DE_PORT_HOTPLUG_MASK; @@ -2271,7 +2276,12 @@ static void bxt_hpd_handler(struct drm_device *dev, uint32_t iir_status) /* Clear sticky bits in hpd status */ I915_WRITE(BXT_HOTPLUG_CTL, hp_control); - pch_get_hpd_pins(&pin_mask, &long_mask, hp_trigger, hp_control, hpd_bxt); + if (INTEL_REVID(dev) < BXT_REVID_B0) + hpd = hpd_bxt_a0; + else + hpd = hpd_bxt; + + pch_get_hpd_pins(&pin_mask, &long_mask, hp_trigger, hp_control, hpd); intel_hpd_irq_handler(dev, pin_mask, long_mask); } @@ -3315,8 +3325,15 @@ static void bxt_hpd_irq_setup(struct drm_device *dev) /* Now, enable HPD */ for_each_intel_encoder(dev, intel_encoder) { if (dev_priv->hotplug.stats[intel_encoder->hpd_pin].state - == HPD_ENABLED) - hotplug_port |= hpd_bxt[intel_encoder->hpd_pin]; + == HPD_ENABLED) { + const u32 *hpd; + + if (INTEL_REVID(dev) < BXT_REVID_B0) + hpd = hpd_bxt_a0; + else + hpd = hpd_bxt; + hotplug_port |= hpd[intel_encoder->hpd_pin]; + } } /* Mask all HPD control bits */ @@ -3324,11 +3341,14 @@ static void bxt_hpd_irq_setup(struct drm_device *dev) /* Enable requested port in hotplug control */ /* TODO: implement (short) HPD support on port A */ - WARN_ON_ONCE(hotplug_port & BXT_DE_PORT_HP_DDIA); - if (hotplug_port & BXT_DE_PORT_HP_DDIB) - hotplug_ctrl |= BXT_DDIB_HPD_ENABLE; - if (hotplug_port & BXT_DE_PORT_HP_DDIC) - hotplug_ctrl |= BXT_DDIC_HPD_ENABLE; + if (INTEL_REVID(dev) < BXT_REVID_B0 && (hotplug_port & BXT_DE_PORT_HP_DDIA)) + hotplug_ctrl |= BXT_DDIA_HPD_ENABLE; + else { + if (hotplug_port & BXT_DE_PORT_HP_DDIB) + hotplug_ctrl |= BXT_DDIB_HPD_ENABLE; + if (hotplug_port & BXT_DE_PORT_HP_DDIC) + hotplug_ctrl |= BXT_DDIC_HPD_ENABLE; + } I915_WRITE(BXT_HOTPLUG_CTL, hotplug_ctrl); /* Unmask DDI hotplug in IMR */ -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 5/5] drm/i915: Set edid from detect only if forced
During init_connector set the edid, then edid will be set/unset only during hotplug. For the sake of older platforms where HPD is not stable, let edid read happen from detect as well only if it is forced to do so. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c |6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 769cf4f..0111ac0a 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1405,6 +1405,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) enum drm_connector_status status; struct intel_connector *intel_connector = to_intel_connector(connector); + struct drm_device *dev = connector->dev; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -1418,7 +1419,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) * based on availability of cached EDID. This will avoid many of * these race conditions and timing problems. */ - if (force) + if (force && INTEL_INFO(dev)->gen < 9) intel_hdmi_probe(intel_connector->encoder); if (intel_connector->detect_edid) { @@ -2076,6 +2077,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, drm_connector_register(connector); intel_hdmi->attached_connector = intel_connector; + /* Set edid during init */ + intel_hdmi_probe(intel_encoder); + /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being * generated on the port when a cable is not attached. -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 4/5] drm/i915: Check live status before reading edid
Adding this for SKL onwards. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_hdmi.c | 49 ++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1fb6919..769cf4f 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1300,6 +1300,46 @@ intel_hdmi_unset_edid(struct drm_connector *connector) to_intel_connector(connector)->detect_edid = NULL; } +static bool intel_hdmi_live_status(struct intel_digital_port *intel_dig_port) +{ + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + enum port port = intel_dig_port->port; + + if (IS_SKYLAKE(dev)) { + u32 temp = I915_READ(SDEISR); + + switch (port) { + case PORT_B: + return temp & SDE_PORTB_HOTPLUG_CPT; + + case PORT_C: + return temp & SDE_PORTC_HOTPLUG_CPT; + + case PORT_D: + return temp & SDE_PORTD_HOTPLUG_CPT; + + default: + return false; + } + } else if (IS_BROXTON(dev)) { + u32 temp = I915_READ(GEN8_DE_PORT_ISR); + + switch (port) { + case PORT_B: + return temp & BXT_DE_PORT_HP_DDIB; + + case PORT_C: + return temp & BXT_DE_PORT_HP_DDIC; + + default: + return false; + + } + } + return true; +} + static bool intel_hdmi_set_edid(struct drm_connector *connector) { @@ -1308,15 +1348,16 @@ intel_hdmi_set_edid(struct drm_connector *connector) struct intel_encoder *intel_encoder = &hdmi_to_dig_port(intel_hdmi)->base; enum intel_display_power_domain power_domain; - struct edid *edid; + struct edid *edid = NULL; bool connected = false; power_domain = intel_display_port_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); - edid = drm_get_edid(connector, - intel_gmbus_get_adapter(dev_priv, - intel_hdmi->ddc_bus)); + if (intel_hdmi_live_status(hdmi_to_dig_port(intel_hdmi))) + edid = drm_get_edid(connector, + intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus)); intel_display_power_put(dev_priv, power_domain); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/5] drm/i915: Add HDMI probe function
From: Shashank Sharma This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The reason behind addition of this separate function needs brief explaination. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. Reuse the cached EDID in hdmi_detect() function UNLESS we are forced to probe the EDID by the force=1 variable.The next patch in the series does this. 3. Make sure that we are using this force variable properly. Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_hdmi.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index af4d1e6..064ddd8 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1340,6 +1340,24 @@ intel_hdmi_set_edid(struct drm_connector *connector) return connected; } +void intel_hdmi_probe(struct intel_encoder *intel_encoder) +{ + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { @@ -1997,6 +2015,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector->unregister = intel_connector_unregister; intel_hdmi_add_properties(intel_hdmi, connector); + intel_encoder->hot_plug = intel_hdmi_probe; intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/5] drm/i915: add attached connector to hdmi container
From: Shashank Sharma This patch adds the intel_connector initialized to intel_hdmi display, during the init phase, just like the other encoders do. This attachment is very useful when we need to extract the connector pointer during the hotplug handler function Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_hdmi.c |1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e90c743..a47fbc3 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -659,6 +659,7 @@ struct intel_hdmi { enum hdmi_force_audio force_audio; bool rgb_quant_range_selectable; enum hdmi_picture_aspect aspect_ratio; + struct intel_connector *attached_connector; void (*write_infoframe)(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 00c4b40..af4d1e6 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2000,6 +2000,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); + intel_hdmi->attached_connector = intel_connector; /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 0/5] HDMI optimization series
This series adds some optimization related to reading of edid only when required and when live status says so. The comments in the patches explain more. First 3 patches were posted earlier(last week) too. Sending them again along with the live status patch as part of the series. Shashank Sharma (3): drm/i915: add attached connector to hdmi container drm/i915: Add HDMI probe function drm/i915: Read HDMI EDID only when required Sonika Jindal (2): drm/i915: Check live status before reading edid drm/i915: Set edid from detect only if forced drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_hdmi.c | 99 + 2 files changed, 90 insertions(+), 10 deletions(-) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/5] drm/i915: Read HDMI EDID only when required
From: Shashank Sharma This patch makes sure that the HDMI detect function reads EDID only when its forced to do it. All the other times, it uses the connector->detect_edid which was cached during hotplug handling in the hdmi_probe() function. As the probe function gets called before detect in the interrupt handler and handles the EDID cacheing part, its absolutely safe to assume that presence of EDID reflects monitor connected and viceversa. This will save us from many race conditions between hotplug/unplug detect call handler threads and userspace calls for the same. The previous patch in this patch series explains this in detail. Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_hdmi.c | 26 -- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 064ddd8..1fb6919 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1362,19 +1362,33 @@ static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); + /* +* There are many userspace calls which probe EDID from +* detect path. In case on multiple hotplug/unplug, these +* can cause race conditions while probing EDID. Also its +* waste of CPU cycles to read the EDID again and again +* unless there is a real hotplug. +* So until we are forced, check connector status +* based on availability of cached EDID. This will avoid many of +* these race conditions and timing problems. +*/ + if (force) + intel_hdmi_probe(intel_connector->encoder); - intel_hdmi_unset_edid(connector); - - if (intel_hdmi_set_edid(connector)) { + if (intel_connector->detect_edid) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; status = connector_status_connected; - } else + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + DRM_DEBUG_DRIVER("hdmi status = connected\n"); + } else { status = connector_status_disconnected; + DRM_DEBUG_DRIVER("hdmi status = disconnected\n"); + } return status; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Handle HPD when it has actually occurred
Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. v2: Make few variables local to if block (Ville) v3: Add check for ibx/cpt both (Ville). While at it, remove the redundant check for hotplug_trigger from pch_get_hpd_pins v4: Indentation (Ville) Reviewed-by: Ville Syrjälä Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_irq.c | 32 +--- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..a897f68 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1266,9 +1266,6 @@ static void pch_get_hpd_pins(u32 *pin_mask, u32 *long_mask, *pin_mask = 0; *long_mask = 0; - if (!hotplug_trigger) - return; - for_each_hpd_pin(i) { if ((hpd[i] & hotplug_trigger) == 0) continue; @@ -1658,14 +1655,17 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) struct drm_i915_private *dev_priv = dev->dev_private; int pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; - u32 dig_hotplug_reg; - u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + if (hotplug_trigger) { + u32 dig_hotplug_reg, pin_mask, long_mask; - pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd_ibx); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + + pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, +dig_hotplug_reg, hpd_ibx); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir & SDE_AUDIO_POWER_MASK) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >> @@ -1757,14 +1757,16 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) struct drm_i915_private *dev_priv = dev->dev_private; int pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; - u32 dig_hotplug_reg; - u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + if (hotplug_trigger) { + u32 dig_hotplug_reg, pin_mask, long_mask; - pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, +dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Handle HPD when it has actually occurred
Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. v2: Make few variables local to if block (Ville) v3: Add check for ibx/cpt both (Ville). While at it, remove the redundant check for hotplug_trigger from pch_get_hpd_pins Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_irq.c | 32 +--- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..ba2c27c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1266,9 +1266,6 @@ static void pch_get_hpd_pins(u32 *pin_mask, u32 *long_mask, *pin_mask = 0; *long_mask = 0; - if (!hotplug_trigger) - return; - for_each_hpd_pin(i) { if ((hpd[i] & hotplug_trigger) == 0) continue; @@ -1658,14 +1655,17 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir) struct drm_i915_private *dev_priv = dev->dev_private; int pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; - u32 dig_hotplug_reg; - u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + if (hotplug_trigger) { + u32 dig_hotplug_reg, pin_mask, long_mask; - pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd_ibx); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + + pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, + dig_hotplug_reg, hpd_ibx); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir & SDE_AUDIO_POWER_MASK) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >> @@ -1757,14 +1757,16 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) struct drm_i915_private *dev_priv = dev->dev_private; int pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; - u32 dig_hotplug_reg; - u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + if (hotplug_trigger) { + u32 dig_hotplug_reg, pin_mask, long_mask; - pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, + dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Handle HPD when it has actually occurred
Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. v2: Make few variables local to if block (Ville) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_irq.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..cd504dc 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1757,14 +1757,16 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) struct drm_i915_private *dev_priv = dev->dev_private; int pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; - u32 dig_hotplug_reg; - u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + if (hotplug_trigger) { + u32 dig_hotplug_reg, pin_mask, long_mask; - pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, + dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] [RFC] drm/i915: Handle HPD when it has actually occurred
Writing to PCH_PORT_HOTPLUG for each interrupt is not required. Handle it only if hpd has actually occurred like we handle other interrupts. Signed-off-by: Sonika Jindal --- Hi, I see we don't check for hotplug_trigger before processing the HPD for any of the platform. Is there any reason for this? For SKL, if I let write to PCH_PORT_HOTPLUG happen for all interrupts, somehow this register gets an invalid value at one point and it zeroes it out. If I put this check before handling HPD, hotplug behaves fine. Please let me know if you see any issue with this approach. Thanks, Sonika drivers/gpu/drm/i915/i915_irq.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a6fbe64..2d47372 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1760,11 +1760,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) u32 dig_hotplug_reg; u32 pin_mask, long_mask; - dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); - I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); - - pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); - intel_hpd_irq_handler(dev, pin_mask, long_mask); + if (hotplug_trigger) { + dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); + I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); + pch_get_hpd_pins(&pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, hpd_cpt); + intel_hpd_irq_handler(dev, pin_mask, long_mask); + } if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/3] drm/i915: Read HDMI EDID only when required
From: Shashank Sharma This patch makes sure that the HDMI detect function reads EDID only when its forced to do it. All the other times, it uses the connector->detect_edid which was cached during hotplug handling in the hdmi_probe() function. As the probe function gets called before detect in the interrupt handler and handles the EDID cacheing part, its absolutely safe to assume that presence of EDID reflects monitor connected and viceversa. This will save us from many race conditions between hotplug/unplug detect call handler threads and userspace calls for the same. The previous patch in this patch series explains this in detail. Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_hdmi.c | 26 -- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 064ddd8..1fb6919 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1362,19 +1362,33 @@ static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { enum drm_connector_status status; + struct intel_connector *intel_connector = + to_intel_connector(connector); DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); + /* +* There are many userspace calls which probe EDID from +* detect path. In case on multiple hotplug/unplug, these +* can cause race conditions while probing EDID. Also its +* waste of CPU cycles to read the EDID again and again +* unless there is a real hotplug. +* So until we are forced, check connector status +* based on availability of cached EDID. This will avoid many of +* these race conditions and timing problems. +*/ + if (force) + intel_hdmi_probe(intel_connector->encoder); - intel_hdmi_unset_edid(connector); - - if (intel_hdmi_set_edid(connector)) { + if (intel_connector->detect_edid) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; status = connector_status_connected; - } else + hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + DRM_DEBUG_DRIVER("hdmi status = connected\n"); + } else { status = connector_status_disconnected; + DRM_DEBUG_DRIVER("hdmi status = disconnected\n"); + } return status; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/3] drm/i915: Add HDMI probe function
From: Shashank Sharma This patch adds a separate probe function for HDMI EDID read over DDC channel. This function has been registered as a .hot_plug handler for HDMI encoder. The reason behind addition of this separate function needs brief explaination. The current implementation of hdmi_detect() function re-sets the cached HDMI edid (in connector->detect_edid) in every detect call.This function gets called many times, sometimes directly from userspace probes, forcing drivers to read EDID every detect function call.This causes several problems like: 1. Race conditions in multiple hot_plug / unplug cases, between interrupts bottom halves and userspace detections. 2. Many Un-necessary EDID reads for single hotplug/unplug 3. HDMI complaince failures which expects only one EDID read per hotplug This function will be serving the purpose of really reading the EDID by really probing the DDC channel, and updating the cached EDID. The plan is to: 1. i915 IRQ handler bottom half function already calls intel_encoder->hotplug() function. Adding This probe function which will read the EDID only in case of a hotplug / unplug. 2. Reuse the cached EDID in hdmi_detect() function UNLESS we are forced to probe the EDID by the force=1 variable.The next patch in the series does this. 3. Make sure that we are using this force variable properly. Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_hdmi.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index af4d1e6..064ddd8 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1340,6 +1340,24 @@ intel_hdmi_set_edid(struct drm_connector *connector) return connected; } +void intel_hdmi_probe(struct intel_encoder *intel_encoder) +{ + struct intel_hdmi *intel_hdmi = + enc_to_intel_hdmi(&intel_encoder->base); + struct intel_connector *intel_connector = + intel_hdmi->attached_connector; + /* +* We are here, means there is a hotplug or a force +* detection. Clear the cached EDID and probe the +* DDC bus to check the current status of HDMI. +*/ + intel_hdmi_unset_edid(&intel_connector->base); + if (intel_hdmi_set_edid(&intel_connector->base)) + DRM_DEBUG_DRIVER("DDC probe: got EDID\n"); + else + DRM_DEBUG_DRIVER("DDC probe: no EDID\n"); +} + static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { @@ -1997,6 +2015,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector->unregister = intel_connector_unregister; intel_hdmi_add_properties(intel_hdmi, connector); + intel_encoder->hot_plug = intel_hdmi_probe; intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/3] drm/i915: add attached connector to hdmi container
From: Shashank Sharma This patch adds the intel_connector initialized to intel_hdmi display, during the init phase, just like the other encoders do. This attachment is very useful when we need to extract the connector pointer during the hotplug handler function Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/intel_drv.h |1 + drivers/gpu/drm/i915/intel_hdmi.c |1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e90c743..a47fbc3 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -659,6 +659,7 @@ struct intel_hdmi { enum hdmi_force_audio force_audio; bool rgb_quant_range_selectable; enum hdmi_picture_aspect aspect_ratio; + struct intel_connector *attached_connector; void (*write_infoframe)(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 00c4b40..af4d1e6 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -2000,6 +2000,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_connector_attach_encoder(intel_connector, intel_encoder); drm_connector_register(connector); + intel_hdmi->attached_connector = intel_connector; /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] Documentation/drm: Update rotation property
Moving rotation property to "Drm" and removing from i915 and omap. Also, adding description to the property Cc: DRI Development Suggested-by: Ville Syrjälä Signed-off-by: Sonika Jindal --- Documentation/DocBook/drm.tmpl | 41 ++-- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 109fde8..c0312cb 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2585,7 +2585,22 @@ void intel_crt_init(struct drm_device *dev) Description/Restrictions - DRM + DRM + Generic + “rotation” + BITMASK + { 0, "rotate-0" }, + { 1, "rotate-90" }, + { 2, "rotate-180" }, + { 3, "rotate-270" }, + { 4, "reflect-x" }, + { 5, "reflect-y" } + CRTC, Plane + rotate-(degrees) rotates the image by the specified amount in degrees + in counter clockwise direction. reflect-x and reflect-y reflects the + image along the specified axis prior to rotation + + Connector “EDID” BLOB | IMMUTABLE @@ -2846,7 +2861,7 @@ void intel_crt_init(struct drm_device *dev) TBD - i915 + i915 Generic "Broadcast RGB" ENUM @@ -2862,14 +2877,6 @@ void intel_crt_init(struct drm_device *dev) TBD - Plane - “rotation” - BITMASK - { 0, "rotate-0" }, { 2, "rotate-180" } - Plane - TBD - - SDVO-TV “mode” ENUM @@ -3377,19 +3384,7 @@ void intel_crt_init(struct drm_device *dev) omap - Generic - “rotation” - BITMASK - { 0, "rotate-0" }, - { 1, "rotate-90" }, - { 2, "rotate-180" }, - { 3, "rotate-270" }, - { 4, "reflect-x" }, - { 5, "reflect-y" } - CRTC, Plane - TBD - - + Generic “zorder” RANGE Min=0, Max=3 -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: edp1.4 Intermediate Freq support
BXT supports following intermediate link rates for edp: 2.16GHz, 2.43GHz, 3.24GHz, 4.32GHz. Adding support for programming the intermediate rates. v2: Adding clock in bxt_clk_div struct and then look for the entry with required rate (Ville) v3: 'clock' has the selected value, no need to use link_bw or rate_select for selecting pll(Ville) v4: Make bxt_dp_clk_val const and remove size (Ville) v5: Rebased v6: Removed setting of vco while rebasing in v5, adding it back Signed-off-by: Sonika Jindal Reviewed-by: Ville Syrjälä (v4) --- drivers/gpu/drm/i915/intel_ddi.c | 39 -- drivers/gpu/drm/i915/intel_dp.c |7 ++- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index cacb07b..2a2518d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1334,6 +1334,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, /* bxt clock parameters */ struct bxt_clk_div { + int clock; uint32_t p1; uint32_t p2; uint32_t m2_int; @@ -1343,14 +1344,14 @@ struct bxt_clk_div { }; /* pre-calculated values for DP linkrates */ -static struct bxt_clk_div bxt_dp_clk_val[7] = { - /* 162 */ {4, 2, 32, 1677722, 1, 1}, - /* 270 */ {4, 1, 27, 0, 0, 1}, - /* 540 */ {2, 1, 27, 0, 0, 1}, - /* 216 */ {3, 2, 32, 1677722, 1, 1}, - /* 243 */ {4, 1, 24, 1258291, 1, 1}, - /* 324 */ {4, 1, 32, 1677722, 1, 1}, - /* 432 */ {3, 1, 32, 1677722, 1, 1} +static const struct bxt_clk_div bxt_dp_clk_val[] = { + {162000, 4, 2, 32, 1677722, 1, 1}, + {27, 4, 1, 27, 0, 0, 1}, + {54, 2, 1, 27, 0, 0, 1}, + {216000, 3, 2, 32, 1677722, 1, 1}, + {243000, 4, 1, 24, 1258291, 1, 1}, + {324000, 4, 1, 32, 1677722, 1, 1}, + {432000, 3, 1, 32, 1677722, 1, 1} }; static bool @@ -1390,22 +1391,14 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, vco = best_clock.vco; } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || intel_encoder->type == INTEL_OUTPUT_EDP) { - struct drm_encoder *encoder = &intel_encoder->base; - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + int i; - switch (intel_dp->link_bw) { - case DP_LINK_BW_1_62: - clk_div = bxt_dp_clk_val[0]; - break; - case DP_LINK_BW_2_7: - clk_div = bxt_dp_clk_val[1]; - break; - case DP_LINK_BW_5_4: - clk_div = bxt_dp_clk_val[2]; - break; - default: - clk_div = bxt_dp_clk_val[0]; - DRM_ERROR("Unknown link rate\n"); + clk_div = bxt_dp_clk_val[0]; + for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) { + if (bxt_dp_clk_val[i].clock == clock) { + clk_div = bxt_dp_clk_val[i]; + break; + } } vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2; } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index abd442a..bd0f958 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -91,6 +91,8 @@ static const struct dp_link_dpll chv_dpll[] = { { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } } }; +static const int bxt_rates[] = { 162000, 216000, 243000, 27, + 324000, 432000, 54 }; static const int skl_rates[] = { 162000, 216000, 27, 324000, 432000, 54 }; static const int chv_rates[] = { 162000, 202500, 21, 216000, @@ -1170,7 +1172,10 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) static int intel_dp_source_rates(struct drm_device *dev, const int **source_rates) { - if (IS_SKYLAKE(dev)) { + if (IS_BROXTON(dev)) { + *source_rates = bxt_rates; + return ARRAY_SIZE(bxt_rates); + } else if (IS_SKYLAKE(dev)) { *source_rates = skl_rates; return ARRAY_SIZE(skl_rates); } else if (IS_CHERRYVIEW(dev)) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: edp1.4 Intermediate Freq support
BXT supports following intermediate link rates for edp: 2.16GHz, 2.43GHz, 3.24GHz, 4.32GHz. Adding support for programming the intermediate rates. v2: Adding clock in bxt_clk_div struct and then look for the entry with required rate (Ville) v3: 'clock' has the selected value, no need to use link_bw or rate_select for selecting pll(Ville) v4: Make bxt_dp_clk_val const and remove size (Ville) v5: Rebased Signed-off-by: Sonika Jindal Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_ddi.c | 40 +++--- drivers/gpu/drm/i915/intel_dp.c |7 ++- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index cacb07b..eb3238a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1334,6 +1334,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, /* bxt clock parameters */ struct bxt_clk_div { + int clock; uint32_t p1; uint32_t p2; uint32_t m2_int; @@ -1343,14 +1344,14 @@ struct bxt_clk_div { }; /* pre-calculated values for DP linkrates */ -static struct bxt_clk_div bxt_dp_clk_val[7] = { - /* 162 */ {4, 2, 32, 1677722, 1, 1}, - /* 270 */ {4, 1, 27, 0, 0, 1}, - /* 540 */ {2, 1, 27, 0, 0, 1}, - /* 216 */ {3, 2, 32, 1677722, 1, 1}, - /* 243 */ {4, 1, 24, 1258291, 1, 1}, - /* 324 */ {4, 1, 32, 1677722, 1, 1}, - /* 432 */ {3, 1, 32, 1677722, 1, 1} +static const struct bxt_clk_div bxt_dp_clk_val[] = { + {162000, 4, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {27, 4, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0xd}, + {54, 2, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0x18}, + {216000, 3, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {243000, 4, 1, 24, 1258291, 1, 1, 5, 11, 2, 9, 0xd}, + {324000, 4, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {432000, 3, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0x18} }; static bool @@ -1390,24 +1391,15 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, vco = best_clock.vco; } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || intel_encoder->type == INTEL_OUTPUT_EDP) { - struct drm_encoder *encoder = &intel_encoder->base; - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + int i; - switch (intel_dp->link_bw) { - case DP_LINK_BW_1_62: - clk_div = bxt_dp_clk_val[0]; - break; - case DP_LINK_BW_2_7: - clk_div = bxt_dp_clk_val[1]; - break; - case DP_LINK_BW_5_4: - clk_div = bxt_dp_clk_val[2]; - break; - default: - clk_div = bxt_dp_clk_val[0]; - DRM_ERROR("Unknown link rate\n"); + clk_div = bxt_dp_clk_val[0]; + for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) { + if (bxt_dp_clk_val[i].clock == clock) { + clk_div = bxt_dp_clk_val[i]; + break; + } } - vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2; } dco_amp = 15; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index abd442a..bd0f958 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -91,6 +91,8 @@ static const struct dp_link_dpll chv_dpll[] = { { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } } }; +static const int bxt_rates[] = { 162000, 216000, 243000, 27, + 324000, 432000, 54 }; static const int skl_rates[] = { 162000, 216000, 27, 324000, 432000, 54 }; static const int chv_rates[] = { 162000, 202500, 21, 216000, @@ -1170,7 +1172,10 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) static int intel_dp_source_rates(struct drm_device *dev, const int **source_rates) { - if (IS_SKYLAKE(dev)) { + if (IS_BROXTON(dev)) { + *source_rates = bxt_rates; + return ARRAY_SIZE(bxt_rates); + } else if (IS_SKYLAKE(dev)) { *source_rates = skl_rates; return ARRAY_SIZE(skl_rates); } else if (IS_CHERRYVIEW(dev)) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Swapping 90 and 270 to be compliant with Xrandr
Since DRM_ROTATE is counter clockwise (which is compliant with Xrandr), and HW rotation is clockwise, swapping 90/270 to work as expected from userspace. v2: Rebased Suggested-by: Ville Syrjälä Cc: Ville Syrjälä Signed-off-by: Sonika Jindal Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c |8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9d2d6fb..a583422 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3010,12 +3010,16 @@ u32 skl_plane_ctl_rotation(unsigned int rotation) switch (rotation) { case BIT(DRM_ROTATE_0): break; + /* +* DRM_ROTATE_ is counter clockwise to stay compatible with Xrandr +* while i915 HW rotation is clockwise, thats why this swapping. +*/ case BIT(DRM_ROTATE_90): - return PLANE_CTL_ROTATE_90; + return PLANE_CTL_ROTATE_270; case BIT(DRM_ROTATE_180): return PLANE_CTL_ROTATE_180; case BIT(DRM_ROTATE_270): - return PLANE_CTL_ROTATE_270; + return PLANE_CTL_ROTATE_90; default: MISSING_CASE(rotation); } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: edp1.4 Intermediate Freq support
BXT supports following intermediate link rates for edp: 2.16GHz, 2.43GHz, 3.24GHz, 4.32GHz. Adding support for programming the intermediate rates. v2: Adding clock in bxt_clk_div struct and then look for the entry with required rate (Ville) v3: 'clock' has the selected value, no need to use link_bw or rate_select for selecting pll(Ville) v4: Make bxt_dp_clk_val const and remove size (Ville) Signed-off-by: Sonika Jindal Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_ddi.c | 39 -- drivers/gpu/drm/i915/intel_dp.c |7 ++- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9c1e74a..c648289 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1327,6 +1327,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, /* bxt clock parameters */ struct bxt_clk_div { + int clock; uint32_t p1; uint32_t p2; uint32_t m2_int; @@ -1341,14 +1342,14 @@ struct bxt_clk_div { }; /* pre-calculated values for DP linkrates */ -static struct bxt_clk_div bxt_dp_clk_val[7] = { - /* 162 */ {4, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 270 */ {4, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0xd}, - /* 540 */ {2, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0x18}, - /* 216 */ {3, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 243 */ {4, 1, 24, 1258291, 1, 1, 5, 11, 2, 9, 0xd}, - /* 324 */ {4, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 432 */ {3, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0x18} +static const struct bxt_clk_div bxt_dp_clk_val[] = { + {162000, 4, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {27, 4, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0xd}, + {54, 2, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0x18}, + {216000, 3, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {243000, 4, 1, 24, 1258291, 1, 1, 5, 11, 2, 9, 0xd}, + {324000, 4, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {432000, 3, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0x18} }; static bool @@ -1399,22 +1400,14 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, clk_div.lanestagger = 0x02; } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || intel_encoder->type == INTEL_OUTPUT_EDP) { - struct drm_encoder *encoder = &intel_encoder->base; - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + int i; - switch (intel_dp->link_bw) { - case DP_LINK_BW_1_62: - clk_div = bxt_dp_clk_val[0]; - break; - case DP_LINK_BW_2_7: - clk_div = bxt_dp_clk_val[1]; - break; - case DP_LINK_BW_5_4: - clk_div = bxt_dp_clk_val[2]; - break; - default: - clk_div = bxt_dp_clk_val[0]; - DRM_ERROR("Unknown link rate\n"); + clk_div = bxt_dp_clk_val[0]; + for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) { + if (bxt_dp_clk_val[i].clock == clock) { + clk_div = bxt_dp_clk_val[i]; + break; + } } } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c9d50d1..e6ee7c6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -85,6 +85,8 @@ static const struct dp_link_dpll chv_dpll[] = { { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } } }; +static const int bxt_rates[] = { 162000, 216000, 243000, 27, + 324000, 432000, 54 }; static const int skl_rates[] = { 162000, 216000, 27, 324000, 432000, 54 }; static const int chv_rates[] = { 162000, 202500, 21, 216000, @@ -1161,7 +1163,10 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) static int intel_dp_source_rates(struct drm_device *dev, const int **source_rates) { - if (IS_SKYLAKE(dev)) { + if (IS_BROXTON(dev)) { + *source_rates = bxt_rates; + return ARRAY_SIZE(bxt_rates); + } else if (IS_SKYLAKE(dev)) { *source_rates = skl_rates; return ARRAY_SIZE(skl_rates); } else if (IS_CHERRYVIEW(dev)) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: edp1.4 Intermediate Freq support
BXT supports following intermediate link rates for edp: 2.16GHz, 2.43GHz, 3.24GHz, 4.32GHz. Adding support for programming the intermediate rates. v2: Adding clock in bxt_clk_div struct and then look for the entry with required rate (Ville) v3: 'clock' has the selected value, no need to use link_bw or rate_select for selecting pll(Ville) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 37 +++-- drivers/gpu/drm/i915/intel_dp.c |7 ++- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9c1e74a..83bb04d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1327,6 +1327,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, /* bxt clock parameters */ struct bxt_clk_div { + int clock; uint32_t p1; uint32_t p2; uint32_t m2_int; @@ -1342,13 +1343,13 @@ struct bxt_clk_div { /* pre-calculated values for DP linkrates */ static struct bxt_clk_div bxt_dp_clk_val[7] = { - /* 162 */ {4, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 270 */ {4, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0xd}, - /* 540 */ {2, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0x18}, - /* 216 */ {3, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 243 */ {4, 1, 24, 1258291, 1, 1, 5, 11, 2, 9, 0xd}, - /* 324 */ {4, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 432 */ {3, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0x18} + {162000, 4, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {27, 4, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0xd}, + {54, 2, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0x18}, + {216000, 3, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {243000, 4, 1, 24, 1258291, 1, 1, 5, 11, 2, 9, 0xd}, + {324000, 4, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {432000, 3, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0x18} }; static bool @@ -1399,22 +1400,14 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, clk_div.lanestagger = 0x02; } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || intel_encoder->type == INTEL_OUTPUT_EDP) { - struct drm_encoder *encoder = &intel_encoder->base; - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + int i; - switch (intel_dp->link_bw) { - case DP_LINK_BW_1_62: - clk_div = bxt_dp_clk_val[0]; - break; - case DP_LINK_BW_2_7: - clk_div = bxt_dp_clk_val[1]; - break; - case DP_LINK_BW_5_4: - clk_div = bxt_dp_clk_val[2]; - break; - default: - clk_div = bxt_dp_clk_val[0]; - DRM_ERROR("Unknown link rate\n"); + clk_div = bxt_dp_clk_val[0]; + for (i = 0; i < 7; ++i) { + if (bxt_dp_clk_val[i].clock == clock) { + clk_div = bxt_dp_clk_val[i]; + break; + } } } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c9d50d1..e6ee7c6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -85,6 +85,8 @@ static const struct dp_link_dpll chv_dpll[] = { { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } } }; +static const int bxt_rates[] = { 162000, 216000, 243000, 27, + 324000, 432000, 54 }; static const int skl_rates[] = { 162000, 216000, 27, 324000, 432000, 54 }; static const int chv_rates[] = { 162000, 202500, 21, 216000, @@ -1161,7 +1163,10 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) static int intel_dp_source_rates(struct drm_device *dev, const int **source_rates) { - if (IS_SKYLAKE(dev)) { + if (IS_BROXTON(dev)) { + *source_rates = bxt_rates; + return ARRAY_SIZE(bxt_rates); + } else if (IS_SKYLAKE(dev)) { *source_rates = skl_rates; return ARRAY_SIZE(skl_rates); } else if (IS_CHERRYVIEW(dev)) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/bxt: edp1.4 Intermediate Freq support
BXT supports following intermediate link rates for edp: 2.16GHz, 2.43GHz, 3.24GHz, 4.32GHz. Adding support for programming the intermediate rates. v2: Adding clock in bxt_clk_div struct and then look for the entry with required rate (Ville) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 45 +- drivers/gpu/drm/i915/intel_dp.c |7 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9c1e74a..7b9d226 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1327,6 +1327,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc, /* bxt clock parameters */ struct bxt_clk_div { + int clock; uint32_t p1; uint32_t p2; uint32_t m2_int; @@ -1342,13 +1343,13 @@ struct bxt_clk_div { /* pre-calculated values for DP linkrates */ static struct bxt_clk_div bxt_dp_clk_val[7] = { - /* 162 */ {4, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 270 */ {4, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0xd}, - /* 540 */ {2, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0x18}, - /* 216 */ {3, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 243 */ {4, 1, 24, 1258291, 1, 1, 5, 11, 2, 9, 0xd}, - /* 324 */ {4, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, - /* 432 */ {3, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0x18} + {162000, 4, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {27, 4, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0xd}, + {54, 2, 1, 27, 0, 0, 1, 3, 8, 1, 9, 0x18}, + {216000, 3, 2, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {243000, 4, 1, 24, 1258291, 1, 1, 5, 11, 2, 9, 0xd}, + {324000, 4, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0xd}, + {432000, 3, 1, 32, 1677722, 1, 1, 5, 11, 2, 9, 0x18} }; static bool @@ -1401,20 +1402,24 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, intel_encoder->type == INTEL_OUTPUT_EDP) { struct drm_encoder *encoder = &intel_encoder->base; struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + int link_rate; + int i; - switch (intel_dp->link_bw) { - case DP_LINK_BW_1_62: - clk_div = bxt_dp_clk_val[0]; - break; - case DP_LINK_BW_2_7: - clk_div = bxt_dp_clk_val[1]; - break; - case DP_LINK_BW_5_4: - clk_div = bxt_dp_clk_val[2]; - break; - default: - clk_div = bxt_dp_clk_val[0]; - DRM_ERROR("Unknown link rate\n"); + /* +* If edp1.4 intermediate frequency support is present, we set +* link_bw to 0 and a valid rate index in rate_select. +*/ + if (intel_dp->link_bw) + link_rate = clock; + else + link_rate = intel_dp->sink_rates[intel_dp->rate_select]; + + clk_div = bxt_dp_clk_val[0]; + for (i = 0; i < 7; ++i) { + if (bxt_dp_clk_val[i].clock == link_rate) { + clk_div = bxt_dp_clk_val[i]; + break; + } } } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c9d50d1..e6ee7c6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -85,6 +85,8 @@ static const struct dp_link_dpll chv_dpll[] = { { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } } }; +static const int bxt_rates[] = { 162000, 216000, 243000, 27, + 324000, 432000, 54 }; static const int skl_rates[] = { 162000, 216000, 27, 324000, 432000, 54 }; static const int chv_rates[] = { 162000, 202500, 21, 216000, @@ -1161,7 +1163,10 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) static int intel_dp_source_rates(struct drm_device *dev, const int **source_rates) { - if (IS_SKYLAKE(dev)) { + if (IS_BROXTON(dev)) { + *source_rates = bxt_rates; + return ARRAY_SIZE(bxt_rates); + } else if (IS_SKYLAKE(dev)) { *source_rates = skl_rates; return ARRAY_SIZE(skl_rates); } else if (IS_CHERRYVIEW(dev)) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: Sink rate read should be saved in deca-kHz
The sink rate read from supported link rate table is in KHz as per spec while in drm, the saved clock is in deca-KHz. So divide the link rate by 10 before storing. Reading of rates was added by: commit fc0f8e25318f ("drm/i915/skl: Read sink supported rates from edp panel") Cc: Ville Syrjälä Signed-off-by: Sonika Jindal Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_dp.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bacdec5..6bd5afb 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3906,7 +3906,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) if (val == 0) break; - intel_dp->sink_rates[i] = val * 200; + /* Value read is in kHz while drm clock is saved in deca-kHz */ + intel_dp->sink_rates[i] = (val * 200) / 10; } intel_dp->num_sink_rates = i; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] Removing redundant is_edp_psr
Since we already store the sink's psr status in dev_priv, use it. Without this we were ignoring the case where sink supports psr2. Cc: Durgadoss R Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_psr.c |7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 27608ce..406d3ac 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -56,11 +56,6 @@ #include "intel_drv.h" #include "i915_drv.h" -static bool is_edp_psr(struct intel_dp *intel_dp) -{ - return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; -} - static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -365,7 +360,7 @@ void intel_psr_enable(struct intel_dp *intel_dp) return; } - if (!is_edp_psr(intel_dp)) { + if (!dev_priv->psr.sink_support) { DRM_DEBUG_KMS("PSR not supported by this panel\n"); return; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/3] drm/i915/bxt: edp1.4 Intermediate Freq support
BXT supports following intermediate link rates for edp: 2.16GHz, 2.43GHz, 3.24GHz, 4.32GHz. Adding support for programming the intermediate rates. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 44 -- drivers/gpu/drm/i915/intel_dp.c |7 +- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9c1e74a..c0cb5f7 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1397,8 +1397,7 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, clk_div.lanestagger = 0x04; else clk_div.lanestagger = 0x02; - } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || - intel_encoder->type == INTEL_OUTPUT_EDP) { + } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { struct drm_encoder *encoder = &intel_encoder->base; struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -1416,8 +1415,49 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc, clk_div = bxt_dp_clk_val[0]; DRM_ERROR("Unknown link rate\n"); } + } else if (intel_encoder->type == INTEL_OUTPUT_EDP) { + struct drm_encoder *encoder = &intel_encoder->base; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + int link_rate; + + /* +* If edp1.4 intermediate frequency support is present, we set +* link_bw to 0 and a valid rate index in rate_select. +*/ + if (intel_dp->link_bw) + link_rate = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); + else + link_rate = intel_dp->sink_rates[intel_dp->rate_select]; + + switch (link_rate) { + case 162000: + clk_div = bxt_dp_clk_val[0]; + break; + case 216000: + clk_div = bxt_dp_clk_val[3]; + break; + case 243000: + clk_div = bxt_dp_clk_val[4]; + break; + case 27: + clk_div = bxt_dp_clk_val[1]; + break; + case 324000: + clk_div = bxt_dp_clk_val[5]; + break; + case 432000: + clk_div = bxt_dp_clk_val[6]; + break; + case 54: + clk_div = bxt_dp_clk_val[2]; + break; + default: + clk_div = bxt_dp_clk_val[0]; + DRM_ERROR("Unknown link rate\n"); + } } + crtc_state->dpll_hw_state.ebb0 = PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2); crtc_state->dpll_hw_state.pll0 = clk_div.m2_int; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c9d50d1..e6ee7c6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -85,6 +85,8 @@ static const struct dp_link_dpll chv_dpll[] = { { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } } }; +static const int bxt_rates[] = { 162000, 216000, 243000, 27, + 324000, 432000, 54 }; static const int skl_rates[] = { 162000, 216000, 27, 324000, 432000, 54 }; static const int chv_rates[] = { 162000, 202500, 21, 216000, @@ -1161,7 +1163,10 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) static int intel_dp_source_rates(struct drm_device *dev, const int **source_rates) { - if (IS_SKYLAKE(dev)) { + if (IS_BROXTON(dev)) { + *source_rates = bxt_rates; + return ARRAY_SIZE(bxt_rates); + } else if (IS_SKYLAKE(dev)) { *source_rates = skl_rates; return ARRAY_SIZE(skl_rates); } else if (IS_CHERRYVIEW(dev)) { -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/3] drm/i915: Sink rate read should be saved in deca-kHz
The sink rate read from supported link rate table is in KHz as per spec while in drm, the saved clock is in deca-KHz. So divide the link rate by 10 before storing. Cc: Ville Syrjälä Signed-off-by: Sonika Jindal --- Just resending it along with the other intermediate link rate patches (It was posted orginally on 21st April) Thanks, Sonika drivers/gpu/drm/i915/intel_dp.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bacdec5..6bd5afb 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3906,7 +3906,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) if (val == 0) break; - intel_dp->sink_rates[i] = val * 200; + /* Value read is in kHz while drm clock is saved in deca-kHz */ + intel_dp->sink_rates[i] = (val * 200) / 10; } intel_dp->num_sink_rates = i; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/3] drm/i915: Rename dp rates array as per platform
Renaming gen9_rates to skl_rates because other platforms may have different supported rates. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6bd5afb..c9d50d1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -84,8 +84,8 @@ static const struct dp_link_dpll chv_dpll[] = { { DP_LINK_BW_5_4, /* m2_int = 27, m2_fraction = 0 */ { .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } } }; -/* Skylake supports following rates */ -static const int gen9_rates[] = { 162000, 216000, 27, + +static const int skl_rates[] = { 162000, 216000, 27, 324000, 432000, 54 }; static const int chv_rates[] = { 162000, 202500, 21, 216000, 243000, 27, 324000, 405000, @@ -1161,9 +1161,9 @@ intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) static int intel_dp_source_rates(struct drm_device *dev, const int **source_rates) { - if (INTEL_INFO(dev)->gen >= 9) { - *source_rates = gen9_rates; - return ARRAY_SIZE(gen9_rates); + if (IS_SKYLAKE(dev)) { + *source_rates = skl_rates; + return ARRAY_SIZE(skl_rates); } else if (IS_CHERRYVIEW(dev)) { *source_rates = chv_rates; return ARRAY_SIZE(chv_rates); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/skl: Add module parameter to select edp vswing table
This provides an option to override the value set by VBT for selecting edp Vswing Pre-emph setting table. v2: Adding comment about this being a temporary workaround and making the parameter read-only (Jani) v3: Changing mode to 0400 instead of 0 (Jani) https://bugs.freedesktop.org/show_bug.cgi?id=89554 Signed-off-by: Sonika Jindal Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h|4 +++- drivers/gpu/drm/i915/i915_params.c |8 drivers/gpu/drm/i915/intel_bios.c |9 +++-- drivers/gpu/drm/i915/intel_ddi.c |2 +- drivers/gpu/drm/i915/intel_dp.c|2 +- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 136d42a..1c3ee66 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1364,7 +1364,6 @@ struct intel_vbt_data { bool edp_initialized; bool edp_support; int edp_bpp; - bool edp_low_vswing; struct edp_power_seq edp_pps; struct { @@ -1846,6 +1845,8 @@ struct drm_i915_private { void (*stop_ring)(struct intel_engine_cs *ring); } gt; + bool edp_low_vswing; + /* * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch * will be rejected. Instead look for a better place. @@ -2515,6 +2516,7 @@ struct i915_params { int mmio_debug; bool verbose_state_checks; bool nuclear_pageflip; + int edp_vswing; }; extern struct i915_params i915 __read_mostly; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index bb64415..8ac5a1b 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -53,6 +53,7 @@ struct i915_params i915 __read_mostly = { .mmio_debug = 0, .verbose_state_checks = 1, .nuclear_pageflip = 0, + .edp_vswing = 0, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -184,3 +185,10 @@ MODULE_PARM_DESC(verbose_state_checks, module_param_named_unsafe(nuclear_pageflip, i915.nuclear_pageflip, bool, 0600); MODULE_PARM_DESC(nuclear_pageflip, "Force atomic modeset functionality; only planes work for now (default: false)."); + +/* WA to get away with the default setting in VBT for early platforms.Will be removed */ +module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0400); +MODULE_PARM_DESC(edp_vswing, +"Ignore/Override vswing pre-emph table selection from VBT " +"(0=use value from vbt [default], 1=low power swing(200mV)," +"2=default swing(400mV))"); diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index c08368c..cee596d 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -672,8 +672,13 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) if (bdb->version >= 173) { uint8_t vswing; - vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; - dev_priv->vbt.edp_low_vswing = vswing == 0; + /* Don't read from VBT if module parameter has valid value*/ + if (i915.edp_vswing) { + dev_priv->edp_low_vswing = i915.edp_vswing == 1; + } else { + vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; + dev_priv->edp_low_vswing = vswing == 0; + } } } diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9c1e74a..2539f22 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -282,7 +282,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, ddi_translations_fdi = NULL; ddi_translations_dp = skl_ddi_translations_dp; n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp); - if (dev_priv->vbt.edp_low_vswing) { + if (dev_priv->edp_low_vswing) { ddi_translations_edp = skl_ddi_translations_edp; n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp); } else { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bacdec5..5f53666 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2894,7 +2894,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) if (IS_BROXTON(dev)) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; else if (INTEL_INFO(dev)->gen >= 9) { - if (dev_priv->vbt.edp_low_vswing && port == PORT_A) + if (dev_priv->edp_low_vswing && port == PORT_A) retur
[Intel-gfx] [PATCH] drm/i915/skl: Add module parameter to select edp vswing table
This provides an option to override the value set by VBT for selecting edp Vswing Pre-emph setting table. v2: Adding comment about this being a temporary workaround and making the parameter read-only (Jani) https://bugs.freedesktop.org/show_bug.cgi?id=89554 Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_drv.h|4 +++- drivers/gpu/drm/i915/i915_params.c |8 drivers/gpu/drm/i915/intel_bios.c |9 +++-- drivers/gpu/drm/i915/intel_ddi.c |2 +- drivers/gpu/drm/i915/intel_dp.c|2 +- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 136d42a..1c3ee66 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1364,7 +1364,6 @@ struct intel_vbt_data { bool edp_initialized; bool edp_support; int edp_bpp; - bool edp_low_vswing; struct edp_power_seq edp_pps; struct { @@ -1846,6 +1845,8 @@ struct drm_i915_private { void (*stop_ring)(struct intel_engine_cs *ring); } gt; + bool edp_low_vswing; + /* * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch * will be rejected. Instead look for a better place. @@ -2515,6 +2516,7 @@ struct i915_params { int mmio_debug; bool verbose_state_checks; bool nuclear_pageflip; + int edp_vswing; }; extern struct i915_params i915 __read_mostly; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index bb64415..e32d3ca 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -53,6 +53,7 @@ struct i915_params i915 __read_mostly = { .mmio_debug = 0, .verbose_state_checks = 1, .nuclear_pageflip = 0, + .edp_vswing = 0, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -184,3 +185,10 @@ MODULE_PARM_DESC(verbose_state_checks, module_param_named_unsafe(nuclear_pageflip, i915.nuclear_pageflip, bool, 0600); MODULE_PARM_DESC(nuclear_pageflip, "Force atomic modeset functionality; only planes work for now (default: false)."); + +/* WA to get away with the default setting in VBT for early platforms.Will be removed */ +module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0); +MODULE_PARM_DESC(edp_vswing, +"Ignore/Override vswing pre-emph table selection from VBT " +"(0=use value from vbt [default], 1=low power swing(200mV)," +"2=default swing(400mV))"); diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index c08368c..cee596d 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -672,8 +672,13 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) if (bdb->version >= 173) { uint8_t vswing; - vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; - dev_priv->vbt.edp_low_vswing = vswing == 0; + /* Don't read from VBT if module parameter has valid value*/ + if (i915.edp_vswing) { + dev_priv->edp_low_vswing = i915.edp_vswing == 1; + } else { + vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; + dev_priv->edp_low_vswing = vswing == 0; + } } } diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9c1e74a..2539f22 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -282,7 +282,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, ddi_translations_fdi = NULL; ddi_translations_dp = skl_ddi_translations_dp; n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp); - if (dev_priv->vbt.edp_low_vswing) { + if (dev_priv->edp_low_vswing) { ddi_translations_edp = skl_ddi_translations_edp; n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp); } else { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bacdec5..5f53666 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2894,7 +2894,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) if (IS_BROXTON(dev)) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; else if (INTEL_INFO(dev)->gen >= 9) { - if (dev_priv->vbt.edp_low_vswing && port == PORT_A) + if (dev_priv->edp_low_vswing && port == PORT_A) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; return DP_TRAIN_VOLTAGE_SWING_LEVEL_2
[Intel-gfx] [PATCH] drm/i915/skl: Add module parameter to select edp vswing table
This provides an option to override the value set by VBT for selecting edp Vswing Pre-emph setting table. https://bugs.freedesktop.org/show_bug.cgi?id=89554 Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_drv.h|4 +++- drivers/gpu/drm/i915/i915_params.c |7 +++ drivers/gpu/drm/i915/intel_bios.c |9 +++-- drivers/gpu/drm/i915/intel_ddi.c |2 +- drivers/gpu/drm/i915/intel_dp.c|2 +- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 136d42a..1c3ee66 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1364,7 +1364,6 @@ struct intel_vbt_data { bool edp_initialized; bool edp_support; int edp_bpp; - bool edp_low_vswing; struct edp_power_seq edp_pps; struct { @@ -1846,6 +1845,8 @@ struct drm_i915_private { void (*stop_ring)(struct intel_engine_cs *ring); } gt; + bool edp_low_vswing; + /* * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch * will be rejected. Instead look for a better place. @@ -2515,6 +2516,7 @@ struct i915_params { int mmio_debug; bool verbose_state_checks; bool nuclear_pageflip; + int edp_vswing; }; extern struct i915_params i915 __read_mostly; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index bb64415..d245ac5 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -53,6 +53,7 @@ struct i915_params i915 __read_mostly = { .mmio_debug = 0, .verbose_state_checks = 1, .nuclear_pageflip = 0, + .edp_vswing = 0, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -184,3 +185,9 @@ MODULE_PARM_DESC(verbose_state_checks, module_param_named_unsafe(nuclear_pageflip, i915.nuclear_pageflip, bool, 0600); MODULE_PARM_DESC(nuclear_pageflip, "Force atomic modeset functionality; only planes work for now (default: false)."); + +module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0600); +MODULE_PARM_DESC(edp_vswing, +"Ignore/Override vswing pre-emph table selection from VBT " +"(0=use value from vbt [default], 1=low power swing(200mV)," +"2=default swing(400mV))"); diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index c08368c..cee596d 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -672,8 +672,13 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) if (bdb->version >= 173) { uint8_t vswing; - vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; - dev_priv->vbt.edp_low_vswing = vswing == 0; + /* Don't read from VBT if module parameter has valid value*/ + if (i915.edp_vswing) { + dev_priv->edp_low_vswing = i915.edp_vswing == 1; + } else { + vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; + dev_priv->edp_low_vswing = vswing == 0; + } } } diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9c1e74a..2539f22 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -282,7 +282,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port, ddi_translations_fdi = NULL; ddi_translations_dp = skl_ddi_translations_dp; n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp); - if (dev_priv->vbt.edp_low_vswing) { + if (dev_priv->edp_low_vswing) { ddi_translations_edp = skl_ddi_translations_edp; n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp); } else { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bacdec5..5f53666 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2894,7 +2894,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) if (IS_BROXTON(dev)) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; else if (INTEL_INFO(dev)->gen >= 9) { - if (dev_priv->vbt.edp_low_vswing && port == PORT_A) + if (dev_priv->edp_low_vswing && port == PORT_A) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; } else if (IS_VALLEYVIEW(dev)) -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/skl: Select DDIA lane capability based upon vbt
Currently, if bios fails to drive an edp panel due to any reason, the ddi buffer will not be enabled. And the DDIA lane capability will remain 0. This leads to assumption of DDIA x2 which means DDIA supports 2 lanes and DDIE supports 2 lanes. For some higher resolution panel which needs 4 lanes, we end up using only 2 lanes which doesn't let the modeset go through because of limited data rate avalaible. So, set the DDIA lane capability correctly if port E is being used by any child device or not. Cc: Sivakumar Thulasimani Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_drv.h |1 + drivers/gpu/drm/i915/intel_bios.c |4 drivers/gpu/drm/i915/intel_bios.h |1 + drivers/gpu/drm/i915/intel_ddi.c |8 4 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 79da7f3..9aad54b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1384,6 +1384,7 @@ struct intel_vbt_data { union child_device_config *child_dev; struct ddi_vbt_port_info ddi_port_info[I915_MAX_PORTS]; + unsigned int ddi_e_used; }; enum intel_ddb_partitioning { diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index c08368c..16c5885 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1119,6 +1119,9 @@ parse_device_mapping(struct drm_i915_private *dev_priv, dev_priv->vbt.dsi.port = p_child->common.dvo_port; } + if (p_child->common.dvo_port == DVO_PORT_DPE) + dev_priv->vbt.ddi_e_used = 1; + child_dev_ptr = dev_priv->vbt.child_dev + count; count++; memcpy((void *)child_dev_ptr, (void *)p_child, @@ -1169,6 +1172,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) info->supports_hdmi = info->supports_dvi; info->supports_dp = (port != PORT_E); } + dev_priv->vbt.ddi_e_used = 0; } static int intel_no_opregion_vbt_callback(const struct dmi_system_id *id) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index af0b476..dd85812 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -764,6 +764,7 @@ int intel_parse_bios(struct drm_device *dev); #define DVO_PORT_DPC 8 #define DVO_PORT_DPD 9 #define DVO_PORT_DPA 10 +#define DVO_PORT_DPE 11 #define DVO_PORT_MIPIA 21 #define DVO_PORT_MIPIB 22 #define DVO_PORT_MIPIC 23 diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b974f8e..c8e370a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2139,6 +2139,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port) struct intel_encoder *intel_encoder; struct drm_encoder *encoder; bool init_hdmi, init_dp; + int val; init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi || dev_priv->vbt.ddi_port_info[port].supports_hdmi); @@ -2169,6 +2170,13 @@ void intel_ddi_init(struct drm_device *dev, enum port port) intel_encoder->get_config = intel_ddi_get_config; intel_dig_port->port = port; + + val = I915_READ(DDI_BUF_CTL(port)); + if (IS_SKYLAKE(dev) && port == PORT_A + && !(val & DDI_BUF_CTL_ENABLE) + && !dev_priv->vbt.ddi_e_used) + I915_WRITE(DDI_BUF_CTL(port), val | DDI_A_4_LANES); + intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & (DDI_BUF_PORT_REVERSAL | DDI_A_4_LANES); -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] kms_rotation_crc: Adding test for 90/270 rotation
Adding 90/270 rotation testcase for primary and sprite planes. v2: Added position test for sprite. Checking for gen > 9 for 90/270. Some cleanup and rebase. v3: Added test for unsupported tiling and unsupported pixel format for 90/270 v4: Added the legacy commit to initiate modeset in the negative test(Tvrtko) Signed-off-by: Sonika Jindal --- tests/kms_rotation_crc.c | 250 -- 1 file changed, 217 insertions(+), 33 deletions(-) diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c index e11d7a9..eda66de 100644 --- a/tests/kms_rotation_crc.c +++ b/tests/kms_rotation_crc.c @@ -28,14 +28,21 @@ #include "igt_debugfs.h" #include "igt_kms.h" #include "igt_core.h" +#include "intel_chipset.h" typedef struct { int gfx_fd; igt_display_t display; struct igt_fb fb; struct igt_fb fb_cursor; + struct igt_fb fb_full; + struct igt_fb fb_565; + struct igt_fb fb_tiling; igt_crc_t ref_crc; igt_pipe_crc_t *pipe_crc; + igt_rotation_t rotation; + int pos_x; + int pos_y; } data_t; static void @@ -63,18 +70,46 @@ paint_squares(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode, w = mode->hdisplay; h = mode->vdisplay; - cr = igt_get_cairo_ctx(data->gfx_fd, &data->fb); + cr = igt_get_cairo_ctx(data->gfx_fd, fb); if (rotation == IGT_ROTATION_180) { cairo_translate(cr, w, h); cairo_rotate(cr, M_PI); } - /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ - igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + /* +* "rotation" is used for creating ref rotated fb and +* "data->rotation" is used to determine the required size +* while creating unrotated fb. +*/ + if (rotation == IGT_ROTATION_90) { + /* Paint 4 squares with width == height in Blue, Red, + Green, White Clockwise order to look like 90 degree rotated*/ + w = h = mode->vdisplay; + igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, 1.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 1.0, 0.0); + + } else if (rotation == IGT_ROTATION_270) { + /* Paint 4 squares with width == height in Green, White, + Blue, Red Clockwise order to look like 270 degree rotated*/ + w = h = mode->vdisplay; + igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 1.0, 0.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 1.0, 1.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); + + } else { + if (data->rotation == IGT_ROTATION_90 || + data->rotation == IGT_ROTATION_270) + w = h = mode->vdisplay; + /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ + igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + } } cairo_destroy(cr); } @@ -84,7 +119,12 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, { drmModeModeInfo *mode; igt_display_t *display = &data->display; - int fb_id, fb_cursor_id; + int fb_id, fb_cursor_id, fb_full_id; + int w, h; + uint64_t tiling = LOCAL_DRM_FORMAT_MOD_NONE; + enum igt_commit_style commit = COMMIT_LEGACY; + int old_rotation; + igt_plane_t *primary; igt_output_set_pipe(output, pipe); @@ -94,10 +134,45 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, mode = igt_output_get_mode(output); + w = mode->hdisplay; + h = mode->vdisplay; + + fb_full_id = igt_create_fb(data-&
[Intel-gfx] [PATCH] drm/i915: Sink rate read should be saved in deca-kHz
The sink rate read from supported link rate table is in KHz as per spec while in drm, the saved clock is in deca-KHz. So divide the link rate by 10 before storing. Cc: Ville Syrjälä Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_dp.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 14cdd00..ae2cfc3 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3833,7 +3833,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) if (val == 0) break; - intel_dp->sink_rates[i] = val * 200; + /* Value read is in kHz while drm clock is saved in deca-kHz */ + intel_dp->sink_rates[i] = (val * 200) / 10; } intel_dp->num_sink_rates = i; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] Documentation/drm: Update rotation property with 90/270 and description
Cc: dri-de...@lists.freedesktop.org Signed-off-by: Sonika Jindal --- Documentation/DocBook/drm.tmpl |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index f4976cd..266d50a 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2853,9 +2853,12 @@ void intel_crt_init(struct drm_device *dev) Plane “rotation” BITMASK - { 0, "rotate-0" }, { 2, "rotate-180" } + { 0, "rotate-0" }, { 1, "rotate-90" }, + { 2, "rotate-180" }, { 3, "rotate-270" } Plane - TBD + To set plane HW rotation. This rotation property does + the plane rotation in counter clockwise direction which is + inline with the way XRandr works. SDVO-TV -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] kms_rotation_crc: Changing as per DRM rotation
DRM rotation is counter clockwise. So changing the test accordingly. Signed-off-by: Sonika Jindal --- tests/kms_rotation_crc.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c index 48afaa1..1054a75 100644 --- a/tests/kms_rotation_crc.c +++ b/tests/kms_rotation_crc.c @@ -81,19 +81,20 @@ paint_squares(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode, * "rotation" is used for creating ref rotated fb and * "data->rotation" is used to determine the required size * while creating unrotated fb. +* Also, drm rotation is counter clockwise. */ - if (rotation == IGT_ROTATION_90) { + if (rotation == IGT_ROTATION_270) { /* Paint 4 squares with width == height in Blue, Red, - Green, White Clockwise order to look like 90 degree rotated*/ + Green, White Clockwise order to look like 270 degree rotated*/ w = h = mode->vdisplay; igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, 1.0); igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 0.0, 0.0); igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 1.0, 0.0); - } else if (rotation == IGT_ROTATION_270) { + } else if (rotation == IGT_ROTATION_90) { /* Paint 4 squares with width == height in Green, White, - Blue, Red Clockwise order to look like 270 degree rotated*/ + Blue, Red Clockwise order to look like 90 degree rotated*/ w = h = mode->vdisplay; igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 1.0, 0.0); igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 1.0, 1.0); @@ -389,6 +390,7 @@ igt_main test_plane_rotation(&data, IGT_PLANE_CURSOR); } + /* Rotation is counter clockwise */ igt_subtest_f("primary-rotation-90") { igt_require(gen >= 9); data.rotation = IGT_ROTATION_90; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] Documentation/drm: Update rotation property with 90/270 and description
Signed-off-by: Sonika Jindal --- Documentation/DocBook/drm.tmpl |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index f4976cd..266d50a 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2853,9 +2853,12 @@ void intel_crt_init(struct drm_device *dev) Plane “rotation” BITMASK - { 0, "rotate-0" }, { 2, "rotate-180" } + { 0, "rotate-0" }, { 1, "rotate-90" }, + { 2, "rotate-180" }, { 3, "rotate-270" } Plane - TBD + To set plane HW rotation. This rotation property does + the plane rotation in counter clockwise direction which is + inline with the way XRandr works. SDVO-TV -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 1/2] drm/i915: Swapping 90 and 270 to be compliant with Xrandr
Since DRM_ROTATE is counter clockwise (which is compliant with Xrandr), and HW rotation is clockwise, swapping 90/270 to work as expected from userspace. Suggested-by: Ville Syrjälä Cc: Ville Syrjälä Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_display.c |8 ++-- drivers/gpu/drm/i915/intel_sprite.c |8 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 97922fb..0d7da3f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3039,8 +3039,12 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, plane = crtc->primary; rotation = plane->state->rotation; switch (rotation) { + /* +* DRM_ROTATE_ is counter clockwise to stay compatible with Xrandr +* while i915 HW rotation is clockwise, thats why this swapping. +*/ case BIT(DRM_ROTATE_90): - plane_ctl |= PLANE_CTL_ROTATE_90; + plane_ctl |= PLANE_CTL_ROTATE_270; break; case BIT(DRM_ROTATE_180): @@ -3048,7 +3052,7 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, break; case BIT(DRM_ROTATE_270): - plane_ctl |= PLANE_CTL_ROTATE_270; + plane_ctl |= PLANE_CTL_ROTATE_90; break; } diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index e3d41c0..765095e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -259,8 +259,12 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, rotation = drm_plane->state->rotation; switch (rotation) { + /* +* DRM_ROTATE_ is counter clockwise to stay compatible with Xrandr +* while i915 HW rotation is clockwise, thats why this swapping. +*/ case BIT(DRM_ROTATE_90): - plane_ctl |= PLANE_CTL_ROTATE_90; + plane_ctl |= PLANE_CTL_ROTATE_270; break; case BIT(DRM_ROTATE_180): @@ -268,7 +272,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, break; case BIT(DRM_ROTATE_270): - plane_ctl |= PLANE_CTL_ROTATE_270; + plane_ctl |= PLANE_CTL_ROTATE_90; break; } -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/skl: Add back HDMI translation table
The HDMI translation table is added back to bspec, so adding it, and defaulting the 800mV+0dB entry. The HDMI translation table was removed by following commit as per HW team's recommendation: commit 7ff446708bd1 ("drm/i915/skl: Only use the 800mV+2bB HDMI translation entry") v2: Adding reference to commit which removed this table (Jani) Cc: Damien Lespiau Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5b50484..b974f8e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -155,8 +155,17 @@ static const struct ddi_buf_trans skl_ddi_translations_edp[] = { static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = { - /* Idx NT mV T mVdb */ - { 0x4014, 0x0087 }, /* 0: 800 10002 */ + { 0x0018, 0x00ac }, + { 0x5012, 0x009d }, + { 0x7011, 0x0088 }, + { 0x0018, 0x00a1 }, + { 0x0018, 0x0098 }, + { 0x4013, 0x0088 }, + { 0x6012, 0x0087 }, + { 0x0018, 0x00df }, + { 0x3015, 0x0087 }, + { 0x3015, 0x00c7 }, + { 0x0018, 0x00c7 }, }; enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) @@ -214,16 +223,9 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) n_edp_entries = ARRAY_SIZE(skl_ddi_translations_dp); } - /* -* On SKL, the recommendation from the hw team is to always use -* a certain type of level shifter (and thus the corresponding -* 800mV+2dB entry). Given that's the only validated entry, we -* override what is in the VBT, at least until further notice. -*/ - hdmi_level = 0; ddi_translations_hdmi = skl_ddi_translations_hdmi; n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi); - hdmi_default_entry = 0; + hdmi_default_entry = 7; } else if (IS_BROADWELL(dev)) { ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/skl: Add back HDMI translation table
The HDMI translation table is added back to bspec, so adding it, and defaulting the 800mV+0dB entry. Cc: Damien Lespiau Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_ddi.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5b50484..b974f8e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -155,8 +155,17 @@ static const struct ddi_buf_trans skl_ddi_translations_edp[] = { static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = { - /* Idx NT mV T mVdb */ - { 0x4014, 0x0087 }, /* 0: 800 10002 */ + { 0x0018, 0x00ac }, + { 0x5012, 0x009d }, + { 0x7011, 0x0088 }, + { 0x0018, 0x00a1 }, + { 0x0018, 0x0098 }, + { 0x4013, 0x0088 }, + { 0x6012, 0x0087 }, + { 0x0018, 0x00df }, + { 0x3015, 0x0087 }, + { 0x3015, 0x00c7 }, + { 0x0018, 0x00c7 }, }; enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) @@ -214,16 +223,9 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) n_edp_entries = ARRAY_SIZE(skl_ddi_translations_dp); } - /* -* On SKL, the recommendation from the hw team is to always use -* a certain type of level shifter (and thus the corresponding -* 800mV+2dB entry). Given that's the only validated entry, we -* override what is in the VBT, at least until further notice. -*/ - hdmi_level = 0; ddi_translations_hdmi = skl_ddi_translations_hdmi; n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi); - hdmi_default_entry = 0; + hdmi_default_entry = 7; } else if (IS_BROADWELL(dev)) { ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 2/2] kms_rotation_crc: Adding test for 90/270 rotation
Adding 90/270 rotation testcase for primary and sprite planes. v2: Added position test for sprite. Checking for gen > 9 for 90/270. Some cleanup and rebase. v3: Added test for unsupported tiling and unsupported pixel format for 90/270 Signed-off-by: Sonika Jindal --- tests/kms_rotation_crc.c | 248 -- 1 file changed, 215 insertions(+), 33 deletions(-) diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c index e11d7a9..48afaa1 100644 --- a/tests/kms_rotation_crc.c +++ b/tests/kms_rotation_crc.c @@ -28,14 +28,21 @@ #include "igt_debugfs.h" #include "igt_kms.h" #include "igt_core.h" +#include "intel_chipset.h" typedef struct { int gfx_fd; igt_display_t display; struct igt_fb fb; struct igt_fb fb_cursor; + struct igt_fb fb_full; + struct igt_fb fb_565; + struct igt_fb fb_tiling; igt_crc_t ref_crc; igt_pipe_crc_t *pipe_crc; + igt_rotation_t rotation; + int pos_x; + int pos_y; } data_t; static void @@ -63,18 +70,46 @@ paint_squares(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode, w = mode->hdisplay; h = mode->vdisplay; - cr = igt_get_cairo_ctx(data->gfx_fd, &data->fb); + cr = igt_get_cairo_ctx(data->gfx_fd, fb); if (rotation == IGT_ROTATION_180) { cairo_translate(cr, w, h); cairo_rotate(cr, M_PI); } - /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ - igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + /* +* "rotation" is used for creating ref rotated fb and +* "data->rotation" is used to determine the required size +* while creating unrotated fb. +*/ + if (rotation == IGT_ROTATION_90) { + /* Paint 4 squares with width == height in Blue, Red, + Green, White Clockwise order to look like 90 degree rotated*/ + w = h = mode->vdisplay; + igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, 1.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 1.0, 0.0); + + } else if (rotation == IGT_ROTATION_270) { + /* Paint 4 squares with width == height in Green, White, + Blue, Red Clockwise order to look like 270 degree rotated*/ + w = h = mode->vdisplay; + igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 1.0, 0.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 1.0, 1.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); + + } else { + if (data->rotation == IGT_ROTATION_90 || + data->rotation == IGT_ROTATION_270) + w = h = mode->vdisplay; + /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ + igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + } } cairo_destroy(cr); } @@ -84,7 +119,12 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, { drmModeModeInfo *mode; igt_display_t *display = &data->display; - int fb_id, fb_cursor_id; + int fb_id, fb_cursor_id, fb_full_id; + int w, h; + uint64_t tiling = LOCAL_DRM_FORMAT_MOD_NONE; + enum igt_commit_style commit = COMMIT_LEGACY; + int old_rotation; + igt_plane_t *primary; igt_output_set_pipe(output, pipe); @@ -94,10 +134,45 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, mode = igt_output_get_mode(output); + w = mode->hdisplay; + h = mode->vdisplay; + + fb_full_id = igt_create_fb(data->gfx_fd, + w, h, + DRM_FOR
[Intel-gfx] [PATCH 1/2] lib/igt_kms: Let set_property return the result
Return the return value of the set_property ioctl and add check for the failure. Signed-off-by: Sonika Jindal --- lib/igt_kms.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 6cb1f08..14abae8 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -927,13 +927,13 @@ get_plane_property(int drm_fd, uint32_t plane_id, const char *name, name, prop_id, value, prop); } -static void +static int igt_plane_set_property(igt_plane_t *plane, uint32_t prop_id, uint64_t value) { igt_pipe_t *pipe = plane->pipe; igt_display_t *display = pipe->display; - drmModeObjectSetProperty(display->drm_fd, plane->drm_plane->plane_id, + return drmModeObjectSetProperty(display->drm_fd, plane->drm_plane->plane_id, DRM_MODE_OBJECT_PLANE, prop_id, value); } @@ -1338,10 +1338,11 @@ static int igt_drm_plane_commit(igt_plane_t *plane, plane->position_changed = false; if (plane->rotation_changed) { - igt_plane_set_property(plane, plane->rotation_property, + ret = igt_plane_set_property(plane, plane->rotation_property, plane->rotation); plane->rotation_changed = false; + CHECK_RETURN(ret, fail_on_error); } return 0; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/skl: Support for 90/270 rotation
v2: Moving creation of property in a function, checking for 90/270 rotation simultaneously (Chris) Letting primary plane to be positioned v3: Adding if/else for 90/270 and rest params programming, adding check for pixel_format, some cleanup (review comments) v4: Adding right pixel_formats, using src_* params instead of crtc_* for offset and size programming (Ville) v5: Rebased on -nightly and Tvrtko's series for gtt remapping. v6: Rebased on -nightly (Tvrtko's series merged) v7: Moving pixel_format check to intel_atomic_plane_check (Matt) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_reg.h |2 + drivers/gpu/drm/i915/intel_atomic_plane.c | 23 drivers/gpu/drm/i915/intel_display.c | 88 - drivers/gpu/drm/i915/intel_drv.h |6 ++ drivers/gpu/drm/i915/intel_sprite.c | 52 - 5 files changed, 130 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b522eb6..564bbd5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4854,7 +4854,9 @@ enum skl_disp_power_wells { #define PLANE_CTL_ALPHA_HW_PREMULTIPLY ( 3 << 4) #define PLANE_CTL_ROTATE_MASK0x3 #define PLANE_CTL_ROTATE_0 0x0 +#define PLANE_CTL_ROTATE_90 0x1 #define PLANE_CTL_ROTATE_180 0x2 +#define PLANE_CTL_ROTATE_270 0x3 #define _PLANE_STRIDE_1_A 0x70188 #define _PLANE_STRIDE_2_A 0x70288 #define _PLANE_STRIDE_3_A 0x70388 diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 976b891..ef8c291 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -162,6 +162,29 @@ static int intel_plane_atomic_check(struct drm_plane *plane, (1 << drm_plane_index(plane)); } + if (state->fb && intel_rotation_90_or_270(state->rotation)) { + if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || + state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) { + DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n"); + return -EINVAL; + } + + /* +* 90/270 is not allowed with RGB64 16:16:16:16, +* RGB 16-bit 5:6:5, and Indexed 8-bit. +*/ + switch (state->fb->pixel_format) { + case DRM_FORMAT_C8: + case DRM_FORMAT_RGB565: + DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", + drm_get_format_name(state->fb->pixel_format)); + return -EINVAL; + + default: + break; + } + } + return intel_plane->check_plane(plane, intel_state); } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f0bbc22..4de544c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2311,13 +2311,6 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, info->pitch = fb->pitches[0]; info->fb_modifier = fb->modifier[0]; - if (!(info->fb_modifier == I915_FORMAT_MOD_Y_TILED || - info->fb_modifier == I915_FORMAT_MOD_Yf_TILED)) { - DRM_DEBUG_KMS( - "Y or Yf tiling is needed for 90/270 rotation!\n"); - return -EINVAL; - } - return 0; } @@ -2919,8 +2912,12 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_i915_gem_object *obj; int pipe = intel_crtc->pipe; - u32 plane_ctl, stride_div; + u32 plane_ctl, stride_div, stride; + u32 tile_height, plane_offset, plane_size; + unsigned int rotation; + int x_offset, y_offset; unsigned long surf_addr; + struct drm_plane *plane; if (!intel_crtc->primary_enabled) { I915_WRITE(PLANE_CTL(pipe, 0), 0); @@ -2981,21 +2978,51 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, } plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; - if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) + + plane = crtc->primary; + rotation = plane->state->rotation; + switch (rotation) { + case BIT(DRM_ROTATE_90): + plane_ctl |= PLANE_CTL_ROTATE_90; + break; + + case BIT(DRM_ROTATE_180): plane_ct
[Intel-gfx] [PATCH] drm/i915/skl: Enabling PSR2 SU with frame sync
We make use of HW tracking for Selective update region and enable frame sync on sink. We use hardware's hardcoded data values for frame sync and GTC. v2: Add 3200x2000 resolution restriction with PSR2, move psr2_support to i915_psr struct, add aux_frame_sync to independently control aux frame sync, rename the TP2 TIME macro for 2500us (Rodrigo, Siva) v3: Moving the resolution restriction to intel_psr_enable so that we check it only once(Durga) Cc: Durgadoss R Cc: Rodrigo Vivi Signed-off-by: Sonika Jindal Reviewed-by: Durgadoss R --- Hi Daniel, It applies cleanly for me. Still I created new patch. Please try, if it works for you. Regards, Sonika drivers/gpu/drm/i915/i915_drv.h |2 ++ drivers/gpu/drm/i915/i915_reg.h | 14 ++ drivers/gpu/drm/i915/intel_dp.c | 15 +++ drivers/gpu/drm/i915/intel_psr.c | 38 +- 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b13c552..f0e1f2e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -881,6 +881,8 @@ struct i915_psr { struct delayed_work work; unsigned busy_frontbuffer_bits; bool link_standby; + bool psr2_support; + bool aux_frame_sync; }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b134fa3..59e9b2d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2748,6 +2748,20 @@ enum skl_disp_power_wells { #define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) #define EDP_PSR_DEBUG_MASK_HPD (1<<25) +#define EDP_PSR2_CTL 0x6f900 +#define EDP_PSR2_ENABLE (1<<31) +#define EDP_SU_TRACK_ENABLE (1<<30) +#define EDP_MAX_SU_DISABLE_TIME(t) ((t)<<20) +#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f<<20) +#define EDP_PSR2_TP2_TIME_500(0<<8) +#define EDP_PSR2_TP2_TIME_100(1<<8) +#define EDP_PSR2_TP2_TIME_2500 (2<<8) +#define EDP_PSR2_TP2_TIME_50 (3<<8) +#define EDP_PSR2_TP2_TIME_MASK (3<<8) +#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 +#define EDP_PSR2_FRAME_BEFORE_SU_MASK(0xf<<4) +#define EDP_PSR2_IDLE_MASK 0xf + /* VGA port control */ #define ADPA 0x61100 #define PCH_ADPA0xe1100 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7936155..a651dba 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3785,6 +3785,21 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) dev_priv->psr.sink_support = true; DRM_DEBUG_KMS("Detected EDP PSR Panel.\n"); } + + if (INTEL_INFO(dev)->gen >= 9 && + (intel_dp->psr_dpcd[0] & DP_PSR2_IS_SUPPORTED)) { + uint8_t frame_sync_cap; + + dev_priv->psr.sink_support = true; + intel_dp_dpcd_read_wake(&intel_dp->aux, + DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP, + &frame_sync_cap, 1); + dev_priv->psr.aux_frame_sync = frame_sync_cap ? true : false; + /* PSR2 needs frame sync as well */ + dev_priv->psr.psr2_support = dev_priv->psr.aux_frame_sync; + DRM_DEBUG_KMS("PSR2 %s on sink", + dev_priv->psr.psr2_support ? "supported" : "not supported"); + } } /* Training Pattern 3 support, both source and sink */ diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 9668735..27608ce 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -117,6 +117,19 @@ static void vlv_psr_setup_vsc(struct intel_dp *intel_dp) I915_WRITE(VLV_VSCSDP(pipe), val); } +static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp) +{ + struct edp_vsc_psr psr_vsc; + + /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */ + memset(&psr_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x3; + psr_vsc.sdp_header.HB3 = 0xb; + intel_psr_write_vsc(intel_dp, &psr_vsc); +} + static void hsw_psr_setup_vsc(struct intel_dp *intel_dp) { struct edp_vsc_psr psr_vsc; @@ -165,6 +178,12 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
[Intel-gfx] [PATCH] drm/i915/skl: Enabling PSR2 SU with frame sync
We make use of HW tracking for Selective update region and enable frame sync on sink. We use hardware's hardcoded data values for frame sync and GTC. v2: Add 3200x2000 resolution restriction with PSR2, move psr2_support to i915_psr struct, add aux_frame_sync to independently control aux frame sync, rename the TP2 TIME macro for 2500us (Rodrigo, Siva) v3: Moving the resolution restriction to intel_psr_enable so that we check it only once(Durga) Cc: Durgadoss R Cc: Rodrigo Vivi Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_drv.h |2 ++ drivers/gpu/drm/i915/i915_reg.h | 14 ++ drivers/gpu/drm/i915/intel_dp.c | 15 +++ drivers/gpu/drm/i915/intel_psr.c | 38 +- 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index eb38cd1..65d3dae 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -879,6 +879,8 @@ struct i915_psr { struct delayed_work work; unsigned busy_frontbuffer_bits; bool link_standby; + bool psr2_support; + bool aux_frame_sync; }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5b84ee6..0b42ef3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2745,6 +2745,20 @@ enum skl_disp_power_wells { #define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) #define EDP_PSR_DEBUG_MASK_HPD (1<<25) +#define EDP_PSR2_CTL 0x6f900 +#define EDP_PSR2_ENABLE (1<<31) +#define EDP_SU_TRACK_ENABLE (1<<30) +#define EDP_MAX_SU_DISABLE_TIME(t) ((t)<<20) +#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f<<20) +#define EDP_PSR2_TP2_TIME_500(0<<8) +#define EDP_PSR2_TP2_TIME_100(1<<8) +#define EDP_PSR2_TP2_TIME_2500 (2<<8) +#define EDP_PSR2_TP2_TIME_50 (3<<8) +#define EDP_PSR2_TP2_TIME_MASK (3<<8) +#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 +#define EDP_PSR2_FRAME_BEFORE_SU_MASK(0xf<<4) +#define EDP_PSR2_IDLE_MASK 0xf + /* VGA port control */ #define ADPA 0x61100 #define PCH_ADPA0xe1100 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3967af1..b0ae45e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3786,6 +3786,21 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) dev_priv->psr.sink_support = true; DRM_DEBUG_KMS("Detected EDP PSR Panel.\n"); } + + if (INTEL_INFO(dev)->gen >= 9 && + (intel_dp->psr_dpcd[0] & DP_PSR2_IS_SUPPORTED)) { + uint8_t frame_sync_cap; + + dev_priv->psr.sink_support = true; + intel_dp_dpcd_read_wake(&intel_dp->aux, + DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP, + &frame_sync_cap, 1); + dev_priv->psr.aux_frame_sync = frame_sync_cap ? true : false; + /* PSR2 needs frame sync as well */ + dev_priv->psr.psr2_support = dev_priv->psr.aux_frame_sync; + DRM_DEBUG_KMS("PSR2 %s on sink", + dev_priv->psr.psr2_support ? "supported" : "not supported"); + } } /* Training Pattern 3 support, both source and sink */ diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index b9f40c2..8d9ae0b 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -117,6 +117,19 @@ static void vlv_psr_setup_vsc(struct intel_dp *intel_dp) I915_WRITE(VLV_VSCSDP(pipe), val); } +static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp) +{ + struct edp_vsc_psr psr_vsc; + + /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */ + memset(&psr_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x3; + psr_vsc.sdp_header.HB3 = 0xb; + intel_psr_write_vsc(intel_dp, &psr_vsc); +} + static void hsw_psr_setup_vsc(struct intel_dp *intel_dp) { struct edp_vsc_psr psr_vsc; @@ -165,6 +178,12 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE); + /* Enable AUX frame sync at sink */ + if (dev_priv->psr.aux_frame_sync) + drm_dp_dpcd_writeb(&
[Intel-gfx] [PATCH] kms_rotation_crc: Adding test for 90/270 rotation
Adding 90/270 rotation testcase for primary and sprite planes. v2: Added position test for sprite. Checking for gen > 9 for 90/270. Some cleanup and rebase. Signed-off-by: Sonika Jindal --- tests/kms_rotation_crc.c | 175 +- 1 file changed, 142 insertions(+), 33 deletions(-) diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c index e11d7a9..cf946ea 100644 --- a/tests/kms_rotation_crc.c +++ b/tests/kms_rotation_crc.c @@ -28,14 +28,19 @@ #include "igt_debugfs.h" #include "igt_kms.h" #include "igt_core.h" +#include "intel_chipset.h" typedef struct { int gfx_fd; igt_display_t display; struct igt_fb fb; struct igt_fb fb_cursor; + struct igt_fb fb_full; igt_crc_t ref_crc; igt_pipe_crc_t *pipe_crc; + igt_rotation_t rotation; + int pos_x; + int pos_y; } data_t; static void @@ -63,18 +68,46 @@ paint_squares(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode, w = mode->hdisplay; h = mode->vdisplay; - cr = igt_get_cairo_ctx(data->gfx_fd, &data->fb); + cr = igt_get_cairo_ctx(data->gfx_fd, fb); if (rotation == IGT_ROTATION_180) { cairo_translate(cr, w, h); cairo_rotate(cr, M_PI); } - /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ - igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + /* +* "rotation" is used for creating ref rotated fb and +* "data->rotation" is used to determine the required size +* while creating unrotated fb. +*/ + if (rotation == IGT_ROTATION_90) { + /* Paint 4 squares with width == height in Blue, Red, + Green, White Clockwise order to look like 90 degree rotated*/ + w = h = mode->vdisplay; + igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, 1.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 1.0, 0.0); + + } else if (rotation == IGT_ROTATION_270) { + /* Paint 4 squares with width == height in Green, White, + Blue, Red Clockwise order to look like 270 degree rotated*/ + w = h = mode->vdisplay; + igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 1.0, 0.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 1.0, 1.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); + + } else { + if (data->rotation == IGT_ROTATION_90 || + data->rotation == IGT_ROTATION_270) + w = h = mode->vdisplay; + /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ + igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + } } cairo_destroy(cr); } @@ -84,7 +117,12 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, { drmModeModeInfo *mode; igt_display_t *display = &data->display; - int fb_id, fb_cursor_id; + int fb_id, fb_cursor_id, fb_full_id; + int w, h; + uint64_t tiling = LOCAL_DRM_FORMAT_MOD_NONE; + enum igt_commit_style commit = COMMIT_LEGACY; + int old_rotation; + igt_plane_t *primary; igt_output_set_pipe(output, pipe); @@ -94,10 +132,45 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, mode = igt_output_get_mode(output); + w = mode->hdisplay; + h = mode->vdisplay; + + fb_full_id = igt_create_fb(data->gfx_fd, + w, h, + DRM_FORMAT_XRGB, + tiling, + &data->fb_full); + igt_assert(fb_full_id); + + /* +* Wi
[Intel-gfx] [PATCH 2/2] drm/i915/skl: Support for 90/270 rotation
v2: Moving creation of property in a function, checking for 90/270 rotation simultaneously (Chris) Letting primary plane to be positioned v3: Adding if/else for 90/270 and rest params programming, adding check for pixel_format, some cleanup (review comments) v4: Adding right pixel_formats, using src_* params instead of crtc_* for offset and size programming (Ville) v5: Rebased on -nightly and Tvrtko's series for gtt remapping. v6: Rebased on -nightly (Tvrtko's series merged) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_reg.h |2 + drivers/gpu/drm/i915/intel_display.c | 103 +++--- drivers/gpu/drm/i915/intel_drv.h |6 ++ drivers/gpu/drm/i915/intel_sprite.c | 52 - 4 files changed, 129 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b522eb6..564bbd5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4854,7 +4854,9 @@ enum skl_disp_power_wells { #define PLANE_CTL_ALPHA_HW_PREMULTIPLY ( 3 << 4) #define PLANE_CTL_ROTATE_MASK0x3 #define PLANE_CTL_ROTATE_0 0x0 +#define PLANE_CTL_ROTATE_90 0x1 #define PLANE_CTL_ROTATE_180 0x2 +#define PLANE_CTL_ROTATE_270 0x3 #define _PLANE_STRIDE_1_A 0x70188 #define _PLANE_STRIDE_2_A 0x70288 #define _PLANE_STRIDE_3_A 0x70388 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f0bbc22..86ee0f0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2318,6 +2318,28 @@ intel_fill_fb_ggtt_view(struct i915_ggtt_view *view, struct drm_framebuffer *fb, return -EINVAL; } + switch (fb->pixel_format) { + case DRM_FORMAT_XRGB: + case DRM_FORMAT_ARGB: + case DRM_FORMAT_XBGR: + case DRM_FORMAT_ABGR: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + case DRM_FORMAT_NV12: + break; + + default: + DRM_DEBUG_KMS("Unsupported pixel format:%d for 90/270 rotation!\n", + fb->pixel_format); + return -EINVAL; + } + return 0; } @@ -2919,8 +2941,12 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_i915_gem_object *obj; int pipe = intel_crtc->pipe; - u32 plane_ctl, stride_div; + u32 plane_ctl, stride_div, stride; + u32 tile_height, plane_offset, plane_size; + unsigned int rotation; + int x_offset, y_offset; unsigned long surf_addr; + struct drm_plane *plane; if (!intel_crtc->primary_enabled) { I915_WRITE(PLANE_CTL(pipe, 0), 0); @@ -2981,21 +3007,51 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, } plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; - if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) + + plane = crtc->primary; + rotation = plane->state->rotation; + switch (rotation) { + case BIT(DRM_ROTATE_90): + plane_ctl |= PLANE_CTL_ROTATE_90; + break; + + case BIT(DRM_ROTATE_180): plane_ctl |= PLANE_CTL_ROTATE_180; + break; + + case BIT(DRM_ROTATE_270): + plane_ctl |= PLANE_CTL_ROTATE_270; + break; + } obj = intel_fb_obj(fb); stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], fb->pixel_format); - surf_addr = intel_plane_obj_offset(to_intel_plane(crtc->primary), obj); + surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj); + + if (rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))) { + /* stride = Surface height in tiles */ + tile_height = intel_tile_height(dev, fb->bits_per_pixel, + fb->modifier[0]); + stride = DIV_ROUND_UP(fb->height, tile_height); + x_offset = stride * tile_height - y - (plane->state->src_h >> 16); + y_offset = x; + plane_size = ((plane->state->src_w >> 16) - 1) << 16 | + ((plane->state->src_h >> 16) - 1); + } else { + stride = fb->pitches[0] / stride_div; + x_offset = x; + y_offse
[Intel-gfx] [PATCH 1/2] drm/i915/skl: Allow universal planes to position
Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_display.c |7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ceb2e61..f0bbc22 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12150,16 +12150,21 @@ intel_check_primary_plane(struct drm_plane *plane, struct drm_rect *dest = &state->dst; struct drm_rect *src = &state->src; const struct drm_rect *clip = &state->clip; + bool can_position = false; int ret; crtc = crtc ? crtc : plane->crtc; intel_crtc = to_intel_crtc(crtc); + if (INTEL_INFO(dev)->gen >= 9) + can_position = true; + ret = drm_plane_helper_check_update(plane, crtc, fb, src, dest, clip, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, - false, true, &state->visible); + can_position, true, + &state->visible); if (ret) return ret; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/skl: Enabling PSR2 SU with frame sync
We make use of HW tracking for Selective update region and enable frame sync on sink. We use hardware's hardcoded data values for frame sync and GTC. v2: Add 3200x2000 resolution restriction with PSR2, move psr2_support to i915_psr struct, add aux_frame_sync to independently control aux frame sync, rename the TP2 TIME macro for 2500us (Rodrigo, Siva) Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_drv.h |2 ++ drivers/gpu/drm/i915/i915_reg.h | 14 ++ drivers/gpu/drm/i915/intel_dp.c | 15 +++ drivers/gpu/drm/i915/intel_psr.c | 34 +- 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index eb38cd1..65d3dae 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -879,6 +879,8 @@ struct i915_psr { struct delayed_work work; unsigned busy_frontbuffer_bits; bool link_standby; + bool psr2_support; + bool aux_frame_sync; }; enum intel_pch { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5b84ee6..0b42ef3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2745,6 +2745,20 @@ enum skl_disp_power_wells { #define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) #define EDP_PSR_DEBUG_MASK_HPD (1<<25) +#define EDP_PSR2_CTL 0x6f900 +#define EDP_PSR2_ENABLE (1<<31) +#define EDP_SU_TRACK_ENABLE (1<<30) +#define EDP_MAX_SU_DISABLE_TIME(t) ((t)<<20) +#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f<<20) +#define EDP_PSR2_TP2_TIME_500(0<<8) +#define EDP_PSR2_TP2_TIME_100(1<<8) +#define EDP_PSR2_TP2_TIME_2500 (2<<8) +#define EDP_PSR2_TP2_TIME_50 (3<<8) +#define EDP_PSR2_TP2_TIME_MASK (3<<8) +#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 +#define EDP_PSR2_FRAME_BEFORE_SU_MASK(0xf<<4) +#define EDP_PSR2_IDLE_MASK 0xf + /* VGA port control */ #define ADPA 0x61100 #define PCH_ADPA0xe1100 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3967af1..b0ae45e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3786,6 +3786,21 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) dev_priv->psr.sink_support = true; DRM_DEBUG_KMS("Detected EDP PSR Panel.\n"); } + + if (INTEL_INFO(dev)->gen >= 9 && + (intel_dp->psr_dpcd[0] & DP_PSR2_IS_SUPPORTED)) { + uint8_t frame_sync_cap; + + dev_priv->psr.sink_support = true; + intel_dp_dpcd_read_wake(&intel_dp->aux, + DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP, + &frame_sync_cap, 1); + dev_priv->psr.aux_frame_sync = frame_sync_cap ? true : false; + /* PSR2 needs frame sync as well */ + dev_priv->psr.psr2_support = dev_priv->psr.aux_frame_sync; + DRM_DEBUG_KMS("PSR2 %s on sink", + dev_priv->psr.psr2_support ? "supported" : "not supported"); + } } /* Training Pattern 3 support, both source and sink */ diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index b9f40c2..d52623d 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -117,6 +117,19 @@ static void vlv_psr_setup_vsc(struct intel_dp *intel_dp) I915_WRITE(VLV_VSCSDP(pipe), val); } +static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp) +{ + struct edp_vsc_psr psr_vsc; + + /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */ + memset(&psr_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x3; + psr_vsc.sdp_header.HB3 = 0xb; + intel_psr_write_vsc(intel_dp, &psr_vsc); +} + static void hsw_psr_setup_vsc(struct intel_dp *intel_dp) { struct edp_vsc_psr psr_vsc; @@ -165,6 +178,12 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE); + /* Enable AUX frame sync at sink */ + if (dev_priv->psr.aux_frame_sync) + drm_dp_dpcd_writeb(&intel_dp->aux, + DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF, + DP_AUX_FRAME_SYNC_ENABLE); +
[Intel-gfx] [PATCH] drm/i915/skl: Enabling PSR2 SU with frame sync
We make use of HW tracking for Selective update region and enable frame sync on sink. We use hardware's hardcoded data values for frame sync and GTC. Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/i915_reg.h | 14 ++ drivers/gpu/drm/i915/intel_dp.c | 16 drivers/gpu/drm/i915/intel_drv.h |2 ++ drivers/gpu/drm/i915/intel_psr.c | 30 +- 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5b84ee6..7e4f6f0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2745,6 +2745,20 @@ enum skl_disp_power_wells { #define EDP_PSR_DEBUG_MASK_MEMUP (1<<26) #define EDP_PSR_DEBUG_MASK_HPD (1<<25) +#define EDP_PSR2_CTL 0x6f900 +#define EDP_PSR2_ENABLE (1<<31) +#define EDP_SU_TRACK_ENABLE (1<<30) +#define EDP_MAX_SU_DISABLE_TIME(t) ((t)<<20) +#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f<<20) +#define EDP_PSR2_TP2_TIME_500(0<<8) +#define EDP_PSR2_TP2_TIME_100(1<<8) +#define EDP_PSR2_TP2_TIME_250(2<<8) +#define EDP_PSR2_TP2_TIME_50 (3<<8) +#define EDP_PSR2_TP2_TIME_MASK (3<<8) +#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 +#define EDP_PSR2_FRAME_BEFORE_SU_MASK(0xf<<4) +#define EDP_PSR2_IDLE_MASK 0xf + /* VGA port control */ #define ADPA 0x61100 #define PCH_ADPA0xe1100 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3967af1..dedd8ad 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3786,6 +3786,22 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) dev_priv->psr.sink_support = true; DRM_DEBUG_KMS("Detected EDP PSR Panel.\n"); } + + if (INTEL_INFO(dev)->gen >= 9 && + (intel_dp->psr_dpcd[0] & DP_PSR2_IS_SUPPORTED)) { + uint8_t frame_sync_cap; + + dev_priv->psr.sink_support = true; + intel_dp_dpcd_read_wake(&intel_dp->aux, + DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP, + &frame_sync_cap, 1); + /* PSR2 needs frame sync as well */ + if (frame_sync_cap) { + DRM_DEBUG_KMS("PSR2 supported on sink"); + intel_dp->psr2_support = true; + } else + intel_dp->psr2_support = false; + } } /* Training Pattern 3 support, both source and sink */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8bb18e5..ed1b0a5 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -663,6 +663,8 @@ struct intel_dp { struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES]; struct drm_dp_mst_topology_mgr mst_mgr; + bool psr2_support; + uint32_t (*get_aux_clock_divider)(struct intel_dp *dp, int index); /* * This function returns the value we have to program the AUX_CTL diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index b9f40c2..99dbc73 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -117,6 +117,19 @@ static void vlv_psr_setup_vsc(struct intel_dp *intel_dp) I915_WRITE(VLV_VSCSDP(pipe), val); } +static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp) +{ + struct edp_vsc_psr psr_vsc; + + /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */ + memset(&psr_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x3; + psr_vsc.sdp_header.HB3 = 0xb; + intel_psr_write_vsc(intel_dp, &psr_vsc); +} + static void hsw_psr_setup_vsc(struct intel_dp *intel_dp) { struct edp_vsc_psr psr_vsc; @@ -165,6 +178,12 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE); + /* Enable AUX frame sync at sink */ + if (intel_dp->psr2_support) + drm_dp_dpcd_writeb(&intel_dp->aux, + DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF, + DP_AUX_FRAME_SYNC_ENABLE); + aux_data_reg = (INTEL_INFO(dev)->gen >= 9) ? DPA_AUX_CH_DATA1 : EDP_PSR_AUX_DATA1(dev);
[Intel-gfx] [PATCH] kms_rotation_crc: Adding test for 90/270 rotation
Adding 90/270 rotation testcase for primary and sprite planes. Signed-off-by: Sonika Jindal --- tests/kms_rotation_crc.c | 153 ++ 1 file changed, 128 insertions(+), 25 deletions(-) diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c index 7f09df3..2b2062b 100644 --- a/tests/kms_rotation_crc.c +++ b/tests/kms_rotation_crc.c @@ -34,8 +34,10 @@ typedef struct { igt_display_t display; struct igt_fb fb; struct igt_fb fb_cursor; + struct igt_fb fb_full; igt_crc_t ref_crc; igt_pipe_crc_t *pipe_crc; + igt_rotation_t rotation; } data_t; static void @@ -63,18 +65,46 @@ paint_squares(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode, w = mode->hdisplay; h = mode->vdisplay; - cr = igt_get_cairo_ctx(data->gfx_fd, &data->fb); + cr = igt_get_cairo_ctx(data->gfx_fd, fb); if (rotation == IGT_ROTATION_180) { cairo_translate(cr, w, h); cairo_rotate(cr, M_PI); } - /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ - igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); - igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); - igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); - igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + /* +* "rotation" is used for creating ref rotated fb and +* "data->rotation" is used to determine the required size +* while creating unrotated fb. +*/ + if (rotation == IGT_ROTATION_90) { + /* Paint 4 squares with width == height in Blue, Red, + Green, White Clockwise order to look like 90 degree rotated*/ + w = h = mode->vdisplay; + igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, 1.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 1.0, 0.0); + + } else if (rotation == IGT_ROTATION_270) { + /* Paint 4 squares with width == height in Green, White, + Blue, Red Clockwise order to look like 270 degree rotated*/ + w = h = mode->vdisplay; + igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 1.0, 0.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 1.0, 1.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); + + } else { + if (data->rotation == IGT_ROTATION_90 || + data->rotation == IGT_ROTATION_270) + w = h = mode->vdisplay; + /* Paint with 4 squares of Red, Green, White, Blue Clockwise */ + igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0); + igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, 1.0, 0.0); + igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0); + igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0); + } } cairo_destroy(cr); } @@ -84,7 +114,12 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, { drmModeModeInfo *mode; igt_display_t *display = &data->display; - int fb_id, fb_cursor_id; + int fb_id, fb_cursor_id, fb_full_id; + int w, h; + uint64_t tiling = LOCAL_DRM_FORMAT_MOD_NONE; + enum igt_commit_style commit = COMMIT_LEGACY; + int old_rotation; + igt_plane_t *primary; igt_output_set_pipe(output, pipe); @@ -93,18 +128,51 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO); mode = igt_output_get_mode(output); + w = mode->hdisplay; + h = mode->vdisplay; + + fb_full_id = igt_create_fb(data->gfx_fd, + w, h, + DRM_FORMAT_XRGB, + tiling, + &data->fb_full); + igt_assert(fb_full_id); + + /* +* With igt_display_commit2 and COMMIT_UNIVERSAL, we call just the +* setplane without a modeset. So, to be able to call +* igt_display_commit and ultimately setcrtc to do the first modeset, +* we create an fb co
[Intel-gfx] [PATCH 1/3] drm/i915/skl: Allow universal planes to position
Signed-off-by: Sonika Jindal --- drivers/gpu/drm/i915/intel_display.c |7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 437a679..e1b0c4d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12183,16 +12183,21 @@ intel_check_primary_plane(struct drm_plane *plane, struct drm_rect *dest = &state->dst; struct drm_rect *src = &state->src; const struct drm_rect *clip = &state->clip; + bool can_position = false; int ret; crtc = crtc ? crtc : plane->crtc; intel_crtc = to_intel_crtc(crtc); + if (INTEL_INFO(dev)->gen >= 9) + can_position = true; + ret = drm_plane_helper_check_update(plane, crtc, fb, src, dest, clip, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, - false, true, &state->visible); + can_position, true, + &state->visible); if (ret) return ret; -- 1.7.10.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx