OSDN Git Service

Merge tag 'drm-intel-next-2015-04-23-fixed' of git://anongit.freedesktop.org/drm...
[uclinux-h8/linux.git] / drivers / gpu / drm / i915 / intel_hdmi.c
index 995c5b2..65bc386 100644 (file)
@@ -223,10 +223,14 @@ static bool ibx_infoframe_enabled(struct drm_encoder *encoder)
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+       struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
        int reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
        u32 val = I915_READ(reg);
 
-       return val & VIDEO_DIP_ENABLE;
+       if (VIDEO_DIP_PORT(intel_dig_port->port) == (val & VIDEO_DIP_PORT_MASK))
+               return val & VIDEO_DIP_ENABLE;
+
+       return false;
 }
 
 static void cpt_write_infoframe(struct drm_encoder *encoder,
@@ -324,10 +328,14 @@ static bool vlv_infoframe_enabled(struct drm_encoder *encoder)
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+       struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
        int reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
        u32 val = I915_READ(reg);
 
-       return val & VIDEO_DIP_ENABLE;
+       if (VIDEO_DIP_PORT(intel_dig_port->port) == (val & VIDEO_DIP_PORT_MASK))
+               return val & VIDEO_DIP_ENABLE;
+
+       return false;
 }
 
 static void hsw_write_infoframe(struct drm_encoder *encoder,
@@ -951,19 +959,30 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
        return MODE_OK;
 }
 
-static bool hdmi_12bpc_possible(struct intel_crtc *crtc)
+static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->base.dev;
+       struct drm_device *dev = crtc_state->base.crtc->dev;
+       struct drm_atomic_state *state;
        struct intel_encoder *encoder;
+       struct drm_connector_state *connector_state;
        int count = 0, count_hdmi = 0;
+       int i;
 
        if (HAS_GMCH_DISPLAY(dev))
                return false;
 
-       for_each_intel_encoder(dev, encoder) {
-               if (encoder->new_crtc != crtc)
+       state = crtc_state->base.state;
+
+       for (i = 0; i < state->num_connector; i++) {
+               if (!state->connectors[i])
+                       continue;
+
+               connector_state = state->connector_states[i];
+               if (connector_state->crtc != crtc_state->base.crtc)
                        continue;
 
+               encoder = to_intel_encoder(connector_state->best_encoder);
+
                count_hdmi += encoder->type == INTEL_OUTPUT_HDMI;
                count++;
        }
@@ -1020,7 +1039,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
         */
        if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink &&
            clock_12bpc <= portclock_limit &&
-           hdmi_12bpc_possible(encoder->new_crtc)) {
+           hdmi_12bpc_possible(pipe_config)) {
                DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n");
                desired_bpp = 12*3;
 
@@ -1504,11 +1523,6 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
 
        /* Program Tx latency optimal setting */
        for (i = 0; i < 4; i++) {
-               /* Set the latency optimal bit */
-               data = (i == 1) ? 0x0 : 0x6;
-               vlv_dpio_write(dev_priv, pipe, CHV_TX_DW11(ch, i),
-                               data << DPIO_FRC_LATENCY_SHFIT);
-
                /* Set the upar bit */
                data = (i == 1) ? 0x0 : 0x1;
                vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i),
@@ -1618,6 +1632,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
        .atomic_get_property = intel_connector_atomic_get_property,
        .destroy = intel_hdmi_destroy,
        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+       .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
@@ -1669,18 +1684,26 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 
        switch (port) {
        case PORT_B:
-               intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
+               if (IS_BROXTON(dev_priv))
+                       intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT;
+               else
+                       intel_hdmi->ddc_bus = GMBUS_PIN_DPB;
                intel_encoder->hpd_pin = HPD_PORT_B;
                break;
        case PORT_C:
-               intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
+               if (IS_BROXTON(dev_priv))
+                       intel_hdmi->ddc_bus = GMBUS_PIN_2_BXT;
+               else
+                       intel_hdmi->ddc_bus = GMBUS_PIN_DPC;
                intel_encoder->hpd_pin = HPD_PORT_C;
                break;
        case PORT_D:
-               if (IS_CHERRYVIEW(dev))
-                       intel_hdmi->ddc_bus = GMBUS_PORT_DPD_CHV;
+               if (WARN_ON(IS_BROXTON(dev_priv)))
+                       intel_hdmi->ddc_bus = GMBUS_PIN_DISABLED;
+               else if (IS_CHERRYVIEW(dev_priv))
+                       intel_hdmi->ddc_bus = GMBUS_PIN_DPD_CHV;
                else
-                       intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
+                       intel_hdmi->ddc_bus = GMBUS_PIN_DPD;
                intel_encoder->hpd_pin = HPD_PORT_D;
                break;
        case PORT_A:
@@ -1743,7 +1766,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
        if (!intel_dig_port)
                return;
 
-       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+       intel_connector = intel_connector_alloc();
        if (!intel_connector) {
                kfree(intel_dig_port);
                return;