Merge tag 'drm-intel-next-2024-02-27-1' of git://anongit.freedesktop.org/drm/drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_display.c
index 7db0655..ab2f52d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/string_helpers.h>
 
 #include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_tunnel.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_atomic_uapi.h>
@@ -73,6 +74,7 @@
 #include "intel_dp.h"
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
+#include "intel_dp_tunnel.h"
 #include "intel_dpll.h"
 #include "intel_dpll_mgr.h"
 #include "intel_dpt.h"
@@ -2478,7 +2480,7 @@ intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes,
        u32 link_symbol_clock = intel_dp_link_symbol_clock(link_clock);
        u32 data_m = intel_dp_effective_data_rate(pixel_clock, bits_per_pixel_x16,
                                                  bw_overhead);
-       u32 data_n = intel_dp_max_data_rate(link_clock, nlanes);
+       u32 data_n = drm_dp_max_dprx_data_rate(link_clock, nlanes);
 
        /*
         * Windows/BIOS uses fixed M/N values always. Follow suit.
@@ -4490,6 +4492,8 @@ copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
        saved_state->crc_enabled = slave_crtc_state->crc_enabled;
 
        intel_crtc_free_hw_state(slave_crtc_state);
+       if (slave_crtc_state->dp_tunnel_ref.tunnel)
+               drm_dp_tunnel_ref_put(&slave_crtc_state->dp_tunnel_ref);
        memcpy(slave_crtc_state, saved_state, sizeof(*slave_crtc_state));
        kfree(saved_state);
 
@@ -4505,6 +4509,10 @@ copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
                      &master_crtc_state->hw.adjusted_mode);
        slave_crtc_state->hw.scaling_filter = master_crtc_state->hw.scaling_filter;
 
+       if (master_crtc_state->dp_tunnel_ref.tunnel)
+               drm_dp_tunnel_ref_get(master_crtc_state->dp_tunnel_ref.tunnel,
+                                     &slave_crtc_state->dp_tunnel_ref);
+
        copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc);
 
        slave_crtc_state->uapi.mode_changed = master_crtc_state->uapi.mode_changed;
@@ -4533,6 +4541,8 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
        /* free the old crtc_state->hw members */
        intel_crtc_free_hw_state(crtc_state);
 
+       intel_dp_tunnel_atomic_clear_stream_bw(state, crtc_state);
+
        /* FIXME: before the switch to atomic started, a new pipe_config was
         * kzalloc'd. Code that depends on any field being zero should be
         * fixed, so that the crtc_state can be safely duplicated. For now,
@@ -4851,10 +4861,12 @@ memcmp_diff_len(const u8 *a, const u8 *b, size_t len)
 }
 
 static void
-pipe_config_buffer_mismatch(struct drm_i915_private *dev_priv,
-                           bool fastset, const char *name,
+pipe_config_buffer_mismatch(bool fastset, const struct intel_crtc *crtc,
+                           const char *name,
                            const u8 *a, const u8 *b, size_t len)
 {
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
        if (fastset) {
                if (!drm_debug_enabled(DRM_UT_KMS))
                        return;
@@ -4863,7 +4875,8 @@ pipe_config_buffer_mismatch(struct drm_i915_private *dev_priv,
                len = memcmp_diff_len(a, b, len);
 
                drm_dbg_kms(&dev_priv->drm,
-                           "fastset requirement not met in %s buffer\n", name);
+                           "[CRTC:%d:%s] fastset requirement not met in %s buffer\n",
+                           crtc->base.base.id, crtc->base.name, name);
                print_hex_dump(KERN_DEBUG, "expected: ", DUMP_PREFIX_NONE,
                               16, 0, a, len, false);
                print_hex_dump(KERN_DEBUG, "found: ", DUMP_PREFIX_NONE,
@@ -4872,7 +4885,8 @@ pipe_config_buffer_mismatch(struct drm_i915_private *dev_priv,
                /* only dump up to the last difference */
                len = memcmp_diff_len(a, b, len);
 
-               drm_err(&dev_priv->drm, "mismatch in %s buffer\n", name);
+               drm_err(&dev_priv->drm, "[CRTC:%d:%s] mismatch in %s buffer\n",
+                       crtc->base.base.id, crtc->base.name, name);
                print_hex_dump(KERN_ERR, "expected: ", DUMP_PREFIX_NONE,
                               16, 0, a, len, false);
                print_hex_dump(KERN_ERR, "found: ", DUMP_PREFIX_NONE,
@@ -4903,18 +4917,34 @@ pipe_config_mismatch(bool fastset, const struct intel_crtc *crtc,
        va_end(args);
 }
 
-static bool fastboot_enabled(struct drm_i915_private *dev_priv)
+static void
+pipe_config_pll_mismatch(bool fastset,
+                        const struct intel_crtc *crtc,
+                        const char *name,
+                        const struct intel_dpll_hw_state *a,
+                        const struct intel_dpll_hw_state *b)
 {
-       /* Enable fastboot by default on Skylake and newer */
-       if (DISPLAY_VER(dev_priv) >= 9)
-               return true;
+       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
 
-       /* Enable fastboot by default on VLV and CHV */
-       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
-               return true;
+       if (fastset) {
+               if (!drm_debug_enabled(DRM_UT_KMS))
+                       return;
 
-       /* Disabled by default on all others */
-       return false;
+               drm_dbg_kms(&i915->drm,
+                           "[CRTC:%d:%s] fastset requirement not met in %s\n",
+                           crtc->base.base.id, crtc->base.name, name);
+               drm_dbg_kms(&i915->drm, "expected:\n");
+               intel_dpll_dump_hw_state(i915, a);
+               drm_dbg_kms(&i915->drm, "found:\n");
+               intel_dpll_dump_hw_state(i915, b);
+       } else {
+               drm_err(&i915->drm, "[CRTC:%d:%s] mismatch in %s buffer\n",
+                       crtc->base.base.id, crtc->base.name, name);
+               drm_err(&i915->drm, "expected:\n");
+               intel_dpll_dump_hw_state(i915, a);
+               drm_err(&i915->drm, "found:\n");
+               intel_dpll_dump_hw_state(i915, b);
+       }
 }
 
 bool
@@ -4925,14 +4955,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
        struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc->dev);
        struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
        bool ret = true;
-       bool fixup_inherited = fastset &&
-               current_config->inherited && !pipe_config->inherited;
-
-       if (fixup_inherited && !fastboot_enabled(dev_priv)) {
-               drm_dbg_kms(&dev_priv->drm,
-                           "initial modeset and fastboot not set\n");
-               ret = false;
-       }
 
 #define PIPE_CONF_CHECK_X(name) do { \
        if (current_config->name != pipe_config->name) { \
@@ -5012,7 +5034,17 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
        } \
 } while (0)
 
-#define PIPE_CONF_CHECK_TIMINGS(name) do { \
+#define PIPE_CONF_CHECK_PLL(name) do { \
+       if (!intel_dpll_compare_hw_state(dev_priv, &current_config->name, \
+                                        &pipe_config->name)) { \
+               pipe_config_pll_mismatch(fastset, crtc, __stringify(name), \
+                                        &current_config->name, \
+                                        &pipe_config->name); \
+               ret = false; \
+       } \
+} while (0)
+
+#define PIPE_CONF_CHECK_TIMINGS(name) do {     \
        PIPE_CONF_CHECK_I(name.crtc_hdisplay); \
        PIPE_CONF_CHECK_I(name.crtc_htotal); \
        PIPE_CONF_CHECK_I(name.crtc_hblank_start); \
@@ -5071,7 +5103,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
        BUILD_BUG_ON(sizeof(current_config->name) != (len)); \
        BUILD_BUG_ON(sizeof(pipe_config->name) != (len)); \
        if (!intel_compare_buffer(current_config->name, pipe_config->name, (len))) { \
-               pipe_config_buffer_mismatch(dev_priv, fastset, __stringify(name), \
+               pipe_config_buffer_mismatch(fastset, crtc, __stringify(name), \
                                            current_config->name, \
                                            pipe_config->name, \
                                            (len)); \
@@ -5215,42 +5247,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
        PIPE_CONF_CHECK_BOOL(double_wide);
 
-       if (dev_priv->display.dpll.mgr) {
+       if (dev_priv->display.dpll.mgr)
                PIPE_CONF_CHECK_P(shared_dpll);
 
-               PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
-               PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
-               PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
-               PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
-               PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
-               PIPE_CONF_CHECK_X(dpll_hw_state.spll);
-               PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
-               PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
-               PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
-               PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
-               PIPE_CONF_CHECK_X(dpll_hw_state.div0);
-               PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
-               PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
-               PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
-               PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
-       }
+       /* FIXME convert everything over the dpll_mgr */
+       if (dev_priv->display.dpll.mgr || HAS_GMCH(dev_priv))
+               PIPE_CONF_CHECK_PLL(dpll_hw_state);
 
        PIPE_CONF_CHECK_X(dsi_pll.ctrl);
        PIPE_CONF_CHECK_X(dsi_pll.div);
@@ -5373,6 +5375,10 @@ static int intel_modeset_pipe(struct intel_atomic_state *state,
        if (ret)
                return ret;
 
+       ret = intel_dp_tunnel_atomic_add_state_for_crtc(state, crtc);
+       if (ret)
+               return ret;
+
        ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);
        if (ret)
                return ret;
@@ -6260,12 +6266,11 @@ static int intel_atomic_check_config(struct intel_atomic_state *state,
 
 static int intel_atomic_check_config_and_link(struct intel_atomic_state *state)
 {
-       struct drm_i915_private *i915 = to_i915(state->base.dev);
        struct intel_link_bw_limits new_limits;
        struct intel_link_bw_limits old_limits;
        int ret;
 
-       intel_link_bw_init_limits(i915, &new_limits);
+       intel_link_bw_init_limits(state, &new_limits);
        old_limits = new_limits;
 
        while (true) {
@@ -7118,6 +7123,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 
        intel_commit_modeset_disables(state);
 
+       intel_dp_tunnel_atomic_alloc_bw(state);
+
        /* FIXME: Eventually get rid of our crtc->config pointer */
        for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
                crtc->config = new_crtc_state;
@@ -8094,8 +8101,9 @@ void intel_hpd_poll_fini(struct drm_i915_private *i915)
        /* Kill all the work that may have been queued by hpd. */
        drm_connector_list_iter_begin(&i915->drm, &conn_iter);
        for_each_intel_connector_iter(connector, &conn_iter) {
-               if (connector->modeset_retry_work.func)
-                       cancel_work_sync(&connector->modeset_retry_work);
+               if (connector->modeset_retry_work.func &&
+                   cancel_work_sync(&connector->modeset_retry_work))
+                       drm_connector_put(&connector->base);
                if (connector->hdcp.shim) {
                        cancel_delayed_work_sync(&connector->hdcp.check_work);
                        cancel_work_sync(&connector->hdcp.prop_work);