diff mbox

drm/i915: Set alternate aux for DDI-E

Message ID 8082FF9BCB2B054996454E47167FF4EC029ABC50@SHSMSX104.ccr.corp.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Zhang, Xiong Y Aug. 11, 2015, 6:18 a.m. UTC
Reviewed-by: Xiong Zhang <xiong.y.zhang@intel.com>

thanks
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4932d29..3ffd962 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1409,6 +1409,11 @@  enum modeset_restore {
        MODESET_SUSPENDED,
 };

+#define DP_AUX_A 0x40
+#define DP_AUX_B 0x10
+#define DP_AUX_C 0x20
+#define DP_AUX_D 0x30
+
 struct ddi_vbt_port_info {
        /*
         * This is an index in the HDMI/DVI DDI buffer translation table.
@@ -1421,6 +1426,8 @@  struct ddi_vbt_port_info {
        uint8_t supports_dvi:1;
        uint8_t supports_hdmi:1;
        uint8_t supports_dp:1;
+
+       uint8_t alternate_aux_channel;
 };

 enum psr_lines_to_wait {
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 31b1079..990acc2 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -968,13 +968,28 @@  static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
        }

        if (is_dp) {
-               if (aux_channel == 0x40 && port != PORT_A)
+               if (port == PORT_E) {
+                       info->alternate_aux_channel = aux_channel;
+                       /* if DDIE share aux channel with other port, then
+                        * DP couldn't exist on the shared port. Otherwise
+                        * they share the same aux channel and system
+                        * couldn't communicate with them seperately. */
+                       if (aux_channel == DP_AUX_A)
+                               dev_priv->vbt.ddi_port_info[PORT_A].supports_dp = 0;
+                       else if (aux_channel == DP_AUX_B)
+                               dev_priv->vbt.ddi_port_info[PORT_B].supports_dp = 0;
+                       else if (aux_channel == DP_AUX_C)
+                               dev_priv->vbt.ddi_port_info[PORT_C].supports_dp = 0;
+                       else if (aux_channel == DP_AUX_D)
+                               dev_priv->vbt.ddi_port_info[PORT_D].supports_dp = 0;
+               }
+               else if (aux_channel == DP_AUX_A && port != PORT_A)
                        DRM_DEBUG_KMS("Unexpected AUX channel for port A\n");
-               if (aux_channel == 0x10 && port != PORT_B)
+               else if (aux_channel == DP_AUX_B && port != PORT_B)
                        DRM_DEBUG_KMS("Unexpected AUX channel for port B\n");
-               if (aux_channel == 0x20 && port != PORT_C)
+               else if (aux_channel == DP_AUX_C && port != PORT_C)
                        DRM_DEBUG_KMS("Unexpected AUX channel for port C\n");
-               if (aux_channel == 0x30 && port != PORT_D)
+               else if (aux_channel == DP_AUX_D && port != PORT_D)
                        DRM_DEBUG_KMS("Unexpected AUX channel for port D\n");
        }

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 9a40bfb..110d546 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3184,10 +3184,9 @@  void intel_ddi_init(struct drm_device *dev, enum port port)
                     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
        init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
        if (!init_dp && !init_hdmi) {
-               DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
+               DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
                              port_name(port));
-               init_hdmi = true;
-               init_dp = true;
+               return;
        }

        intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 15f0d72..601a12a 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1033,11 +1033,34 @@  static void
 intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
 {
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        enum port port = intel_dig_port->port;
+       struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port];
        const char *name = NULL;
+       uint32_t porte_aux_ctl_reg = DPA_AUX_CH_CTL;
        int ret;

+       /* On SKL we don't have Aux for port E so we rely on VBT to set
+        * a proper alternate aux channel.
+        */
+       if (IS_SKYLAKE(dev) && port == PORT_E) {
+               switch (info->alternate_aux_channel) {
+               case DP_AUX_B:
+                       porte_aux_ctl_reg = DPB_AUX_CH_CTL;
+                       break;
+               case DP_AUX_C:
+                       porte_aux_ctl_reg = DPC_AUX_CH_CTL;
+                       break;
+               case DP_AUX_D:
+                       porte_aux_ctl_reg = DPD_AUX_CH_CTL;
+                       break;
+               case DP_AUX_A:
+               default:
+                       porte_aux_ctl_reg = DPA_AUX_CH_CTL;
+               }
+       }
+
        switch (port) {
        case PORT_A:
                intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL;
@@ -1055,6 +1078,10 @@  intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
                intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL;
                name = "DPDDC-D";
                break;
+       case PORT_E:
+               intel_dp->aux_ch_ctl_reg = porte_aux_ctl_reg;
+               name = "DPDDC-E";
+               break;
        default:
                BUG();
        }
@@ -1068,7 +1095,7 @@  intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
         *
         * Skylake moves AUX_CTL back next to DDI_BUF_CTL, on the CPU.
         */
-       if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
+       if (!IS_HASWELL(dev) && !IS_BROADWELL(dev) && port != PORT_E)
                intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;

        intel_dp->aux.name = name;