]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/gpu/drm/i915/intel_crt.c
drm/i915: Make INTEL_PCH_TYPE & co only take dev_priv
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / i915 / intel_crt.c
index 827b6ef4e9aedfa669c91942d71f84e800841c38..f8919ef3a7af5f1cef61f2d667669adf04546a21 100644 (file)
@@ -84,7 +84,7 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
        if (!(tmp & ADPA_DAC_ENABLE))
                goto out;
 
-       if (HAS_PCH_CPT(dev))
+       if (HAS_PCH_CPT(dev_priv))
                *pipe = PORT_TO_PIPE_CPT(tmp);
        else
                *pipe = PORT_TO_PIPE(tmp);
@@ -143,13 +143,15 @@ static void hsw_crt_get_config(struct intel_encoder *encoder,
 
 /* Note: The caller is required to filter out dpms modes not supported by the
  * platform. */
-static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
+static void intel_crt_set_dpms(struct intel_encoder *encoder,
+                              struct intel_crtc_state *crtc_state,
+                              int mode)
 {
        struct drm_device *dev = encoder->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_crt *crt = intel_encoder_to_crt(encoder);
-       struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
-       const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
        u32 adpa;
 
        if (INTEL_INFO(dev)->gen >= 5)
@@ -163,16 +165,16 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
                adpa |= ADPA_VSYNC_ACTIVE_HIGH;
 
        /* For CPT allow 3 pipe config, for others just use A or B */
-       if (HAS_PCH_LPT(dev))
+       if (HAS_PCH_LPT(dev_priv))
                ; /* Those bits don't exist here */
-       else if (HAS_PCH_CPT(dev))
+       else if (HAS_PCH_CPT(dev_priv))
                adpa |= PORT_TRANS_SEL_CPT(crtc->pipe);
        else if (crtc->pipe == 0)
                adpa |= ADPA_PIPE_A_SELECT;
        else
                adpa |= ADPA_PIPE_B_SELECT;
 
-       if (!HAS_PCH_SPLIT(dev))
+       if (!HAS_PCH_SPLIT(dev_priv))
                I915_WRITE(BCLRPAT(crtc->pipe), 0);
 
        switch (mode) {
@@ -193,23 +195,45 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
        I915_WRITE(crt->adpa_reg, adpa);
 }
 
-static void intel_disable_crt(struct intel_encoder *encoder)
+static void intel_disable_crt(struct intel_encoder *encoder,
+                             struct intel_crtc_state *old_crtc_state,
+                             struct drm_connector_state *old_conn_state)
 {
-       intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF);
+       intel_crt_set_dpms(encoder, old_crtc_state, DRM_MODE_DPMS_OFF);
 }
 
-static void pch_disable_crt(struct intel_encoder *encoder)
+static void pch_disable_crt(struct intel_encoder *encoder,
+                           struct intel_crtc_state *old_crtc_state,
+                           struct drm_connector_state *old_conn_state)
 {
 }
 
-static void pch_post_disable_crt(struct intel_encoder *encoder)
+static void pch_post_disable_crt(struct intel_encoder *encoder,
+                                struct intel_crtc_state *old_crtc_state,
+                                struct drm_connector_state *old_conn_state)
 {
-       intel_disable_crt(encoder);
+       intel_disable_crt(encoder, old_crtc_state, old_conn_state);
 }
 
-static void intel_enable_crt(struct intel_encoder *encoder)
+static void hsw_post_disable_crt(struct intel_encoder *encoder,
+                                struct intel_crtc_state *old_crtc_state,
+                                struct drm_connector_state *old_conn_state)
 {
-       intel_crt_set_dpms(encoder, DRM_MODE_DPMS_ON);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+       pch_post_disable_crt(encoder, old_crtc_state, old_conn_state);
+
+       lpt_disable_pch_transcoder(dev_priv);
+       lpt_disable_iclkip(dev_priv);
+
+       intel_ddi_fdi_post_disable(encoder, old_crtc_state, old_conn_state);
+}
+
+static void intel_enable_crt(struct intel_encoder *encoder,
+                            struct intel_crtc_state *pipe_config,
+                            struct drm_connector_state *conn_state)
+{
+       intel_crt_set_dpms(encoder, pipe_config, DRM_MODE_DPMS_ON);
 }
 
 static enum drm_mode_status
@@ -217,7 +241,8 @@ intel_crt_mode_valid(struct drm_connector *connector,
                     struct drm_display_mode *mode)
 {
        struct drm_device *dev = connector->dev;
-       int max_dotclk = to_i915(dev)->max_dotclk_freq;
+       struct drm_i915_private *dev_priv = to_i915(dev);
+       int max_dotclk = dev_priv->max_dotclk_freq;
        int max_clock;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -226,7 +251,7 @@ intel_crt_mode_valid(struct drm_connector *connector,
        if (mode->clock < 25000)
                return MODE_CLOCK_LOW;
 
-       if (HAS_PCH_LPT(dev))
+       if (HAS_PCH_LPT(dev_priv))
                max_clock = 180000;
        else if (IS_VALLEYVIEW(dev))
                /*
@@ -245,7 +270,7 @@ intel_crt_mode_valid(struct drm_connector *connector,
                return MODE_CLOCK_HIGH;
 
        /* The FDI receiver on LPT only supports 8bpc and only has 2 lanes. */
-       if (HAS_PCH_LPT(dev) &&
+       if (HAS_PCH_LPT(dev_priv) &&
            (ironlake_get_lanes_required(mode->clock, 270000, 24) > 2))
                return MODE_CLOCK_HIGH;
 
@@ -253,15 +278,16 @@ intel_crt_mode_valid(struct drm_connector *connector,
 }
 
 static bool intel_crt_compute_config(struct intel_encoder *encoder,
-                                    struct intel_crtc_state *pipe_config)
+                                    struct intel_crtc_state *pipe_config,
+                                    struct drm_connector_state *conn_state)
 {
-       struct drm_device *dev = encoder->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
-       if (HAS_PCH_SPLIT(dev))
+       if (HAS_PCH_SPLIT(dev_priv))
                pipe_config->has_pch_encoder = true;
 
        /* LPT FDI RX only supports 8bpc. */
-       if (HAS_PCH_LPT(dev)) {
+       if (HAS_PCH_LPT(dev_priv)) {
                if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {
                        DRM_DEBUG_KMS("LPT only supports 24bpp\n");
                        return false;
@@ -271,7 +297,7 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder,
        }
 
        /* FDI must always be 2.7 GHz */
-       if (HAS_DDI(dev))
+       if (HAS_DDI(dev_priv))
                pipe_config->port_clock = 135000 * 2;
 
        return true;
@@ -287,7 +313,7 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
 
        /* The first time through, trigger an explicit detection cycle */
        if (crt->force_hotplug_required) {
-               bool turn_off_dac = HAS_PCH_SPLIT(dev);
+               bool turn_off_dac = HAS_PCH_SPLIT(dev_priv);
                u32 save_adpa;
 
                crt->force_hotplug_required = 0;
@@ -394,7 +420,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
        bool ret = false;
        int i, tries = 0;
 
-       if (HAS_PCH_SPLIT(dev))
+       if (HAS_PCH_SPLIT(dev_priv))
                return intel_ironlake_crt_detect_hotplug(connector);
 
        if (IS_VALLEYVIEW(dev))
@@ -618,6 +644,32 @@ intel_crt_load_detect(struct intel_crt *crt, uint32_t pipe)
        return status;
 }
 
+static int intel_spurious_crt_detect_dmi_callback(const struct dmi_system_id *id)
+{
+       DRM_DEBUG_DRIVER("Skipping CRT detection for %s\n", id->ident);
+       return 1;
+}
+
+static const struct dmi_system_id intel_spurious_crt_detect[] = {
+       {
+               .callback = intel_spurious_crt_detect_dmi_callback,
+               .ident = "ACER ZGB",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
+               },
+       },
+       {
+               .callback = intel_spurious_crt_detect_dmi_callback,
+               .ident = "Intel DZ77BH-55K",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "DZ77BH-55K"),
+               },
+       },
+       { }
+};
+
 static enum drm_connector_status
 intel_crt_detect(struct drm_connector *connector, bool force)
 {
@@ -634,6 +686,10 @@ intel_crt_detect(struct drm_connector *connector, bool force)
                      connector->base.id, connector->name,
                      force);
 
+       /* Skip machines without VGA that falsely report hotplug events */
+       if (dmi_check_system(intel_spurious_crt_detect))
+               return connector_status_disconnected;
+
        power_domain = intel_display_port_power_domain(intel_encoder);
        intel_display_power_get(dev_priv, power_domain);
 
@@ -783,32 +839,6 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
        .destroy = intel_encoder_destroy,
 };
 
-static int intel_no_crt_dmi_callback(const struct dmi_system_id *id)
-{
-       DRM_INFO("Skipping CRT initialization for %s\n", id->ident);
-       return 1;
-}
-
-static const struct dmi_system_id intel_no_crt[] = {
-       {
-               .callback = intel_no_crt_dmi_callback,
-               .ident = "ACER ZGB",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
-               },
-       },
-       {
-               .callback = intel_no_crt_dmi_callback,
-               .ident = "DELL XPS 8700",
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "XPS 8700"),
-               },
-       },
-       { }
-};
-
 void intel_crt_init(struct drm_device *dev)
 {
        struct drm_connector *connector;
@@ -818,11 +848,7 @@ void intel_crt_init(struct drm_device *dev)
        i915_reg_t adpa_reg;
        u32 adpa;
 
-       /* Skip machines without VGA that falsely report hotplug events */
-       if (dmi_check_system(intel_no_crt))
-               return;
-
-       if (HAS_PCH_SPLIT(dev))
+       if (HAS_PCH_SPLIT(dev_priv))
                adpa_reg = PCH_ADPA;
        else if (IS_VALLEYVIEW(dev))
                adpa_reg = VLV_ADPA;
@@ -882,19 +908,23 @@ void intel_crt_init(struct drm_device *dev)
        crt->adpa_reg = adpa_reg;
 
        crt->base.compute_config = intel_crt_compute_config;
-       if (HAS_PCH_SPLIT(dev)) {
+       if (HAS_PCH_SPLIT(dev_priv)) {
                crt->base.disable = pch_disable_crt;
                crt->base.post_disable = pch_post_disable_crt;
        } else {
                crt->base.disable = intel_disable_crt;
        }
        crt->base.enable = intel_enable_crt;
-       if (I915_HAS_HOTPLUG(dev))
+       if (I915_HAS_HOTPLUG(dev) &&
+           !dmi_check_system(intel_spurious_crt_detect))
                crt->base.hpd_pin = HPD_CRT;
-       if (HAS_DDI(dev)) {
+       if (HAS_DDI(dev_priv)) {
+               crt->base.port = PORT_E;
                crt->base.get_config = hsw_crt_get_config;
                crt->base.get_hw_state = intel_ddi_get_hw_state;
+               crt->base.post_disable = hsw_post_disable_crt;
        } else {
+               crt->base.port = PORT_NONE;
                crt->base.get_config = intel_crt_get_config;
                crt->base.get_hw_state = intel_crt_get_hw_state;
        }
@@ -915,7 +945,7 @@ void intel_crt_init(struct drm_device *dev)
         * polarity and link reversal bits or not, instead of relying on the
         * BIOS.
         */
-       if (HAS_PCH_LPT(dev)) {
+       if (HAS_PCH_LPT(dev_priv)) {
                u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT |
                                 FDI_RX_LINK_REVERSAL_OVERRIDE;