1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 * 5 * High level crtc/connector/encoder modeset state verification. 6 */ 7 8 #include <drm/drm_atomic_state_helper.h> 9 10 #include "i915_drv.h" 11 #include "intel_atomic.h" 12 #include "intel_crtc.h" 13 #include "intel_crtc_state_dump.h" 14 #include "intel_cx0_phy.h" 15 #include "intel_display.h" 16 #include "intel_display_types.h" 17 #include "intel_fdi.h" 18 #include "intel_modeset_verify.h" 19 #include "intel_snps_phy.h" 20 #include "skl_watermark.h" 21 22 /* 23 * Cross check the actual hw state with our own modeset state tracking (and its 24 * internal consistency). 25 */ 26 static void intel_connector_verify_state(struct intel_crtc_state *crtc_state, 27 struct drm_connector_state *conn_state) 28 { 29 struct intel_connector *connector = to_intel_connector(conn_state->connector); 30 struct drm_i915_private *i915 = to_i915(connector->base.dev); 31 32 drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n", 33 connector->base.base.id, connector->base.name); 34 35 if (connector->get_hw_state(connector)) { 36 struct intel_encoder *encoder = intel_attached_encoder(connector); 37 38 I915_STATE_WARN(i915, !crtc_state, 39 "connector enabled without attached crtc\n"); 40 41 if (!crtc_state) 42 return; 43 44 I915_STATE_WARN(i915, !crtc_state->hw.active, 45 "connector is active, but attached crtc isn't\n"); 46 47 if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST) 48 return; 49 50 I915_STATE_WARN(i915, 51 conn_state->best_encoder != &encoder->base, 52 "atomic encoder doesn't match attached encoder\n"); 53 54 I915_STATE_WARN(i915, conn_state->crtc != encoder->base.crtc, 55 "attached encoder crtc differs from connector crtc\n"); 56 } else { 57 I915_STATE_WARN(i915, crtc_state && crtc_state->hw.active, 58 "attached crtc is active, but connector isn't\n"); 59 I915_STATE_WARN(i915, !crtc_state && conn_state->best_encoder, 60 "best encoder set without crtc!\n"); 61 } 62 } 63 64 static void 65 verify_connector_state(struct intel_atomic_state *state, 66 struct intel_crtc *crtc) 67 { 68 struct drm_connector *connector; 69 struct drm_connector_state *new_conn_state; 70 int i; 71 72 for_each_new_connector_in_state(&state->base, connector, new_conn_state, i) { 73 struct drm_encoder *encoder = connector->encoder; 74 struct intel_crtc_state *crtc_state = NULL; 75 76 if (new_conn_state->crtc != &crtc->base) 77 continue; 78 79 if (crtc) 80 crtc_state = intel_atomic_get_new_crtc_state(state, crtc); 81 82 intel_connector_verify_state(crtc_state, new_conn_state); 83 84 I915_STATE_WARN(to_i915(connector->dev), new_conn_state->best_encoder != encoder, 85 "connector's atomic encoder doesn't match legacy encoder\n"); 86 } 87 } 88 89 static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv, 90 const struct intel_crtc_state *pipe_config) 91 { 92 if (pipe_config->has_pch_encoder) { 93 int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config), 94 &pipe_config->fdi_m_n); 95 int dotclock = pipe_config->hw.adjusted_mode.crtc_clock; 96 97 /* 98 * FDI already provided one idea for the dotclock. 99 * Yell if the encoder disagrees. Allow for slight 100 * rounding differences. 101 */ 102 drm_WARN(&dev_priv->drm, abs(fdi_dotclock - dotclock) > 1, 103 "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n", 104 fdi_dotclock, dotclock); 105 } 106 } 107 108 static void 109 verify_encoder_state(struct drm_i915_private *dev_priv, struct intel_atomic_state *state) 110 { 111 struct intel_encoder *encoder; 112 struct drm_connector *connector; 113 struct drm_connector_state *old_conn_state, *new_conn_state; 114 int i; 115 116 for_each_intel_encoder(&dev_priv->drm, encoder) { 117 bool enabled = false, found = false; 118 enum pipe pipe; 119 120 drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s]\n", 121 encoder->base.base.id, 122 encoder->base.name); 123 124 for_each_oldnew_connector_in_state(&state->base, connector, old_conn_state, 125 new_conn_state, i) { 126 if (old_conn_state->best_encoder == &encoder->base) 127 found = true; 128 129 if (new_conn_state->best_encoder != &encoder->base) 130 continue; 131 132 found = true; 133 enabled = true; 134 135 I915_STATE_WARN(dev_priv, 136 new_conn_state->crtc != encoder->base.crtc, 137 "connector's crtc doesn't match encoder crtc\n"); 138 } 139 140 if (!found) 141 continue; 142 143 I915_STATE_WARN(dev_priv, !!encoder->base.crtc != enabled, 144 "encoder's enabled state mismatch (expected %i, found %i)\n", 145 !!encoder->base.crtc, enabled); 146 147 if (!encoder->base.crtc) { 148 bool active; 149 150 active = encoder->get_hw_state(encoder, &pipe); 151 I915_STATE_WARN(dev_priv, active, 152 "encoder detached but still enabled on pipe %c.\n", 153 pipe_name(pipe)); 154 } 155 } 156 } 157 158 static void 159 verify_crtc_state(struct intel_crtc *crtc, 160 struct intel_crtc_state *old_crtc_state, 161 struct intel_crtc_state *new_crtc_state) 162 { 163 struct drm_device *dev = crtc->base.dev; 164 struct drm_i915_private *dev_priv = to_i915(dev); 165 struct intel_encoder *encoder; 166 struct intel_crtc_state *pipe_config = old_crtc_state; 167 struct drm_atomic_state *state = old_crtc_state->uapi.state; 168 struct intel_crtc *master_crtc; 169 170 __drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi); 171 intel_crtc_free_hw_state(old_crtc_state); 172 intel_crtc_state_reset(old_crtc_state, crtc); 173 old_crtc_state->uapi.state = state; 174 175 drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s]\n", crtc->base.base.id, 176 crtc->base.name); 177 178 pipe_config->hw.enable = new_crtc_state->hw.enable; 179 180 intel_crtc_get_pipe_config(pipe_config); 181 182 /* we keep both pipes enabled on 830 */ 183 if (IS_I830(dev_priv) && pipe_config->hw.active) 184 pipe_config->hw.active = new_crtc_state->hw.active; 185 186 I915_STATE_WARN(dev_priv, 187 new_crtc_state->hw.active != pipe_config->hw.active, 188 "crtc active state doesn't match with hw state (expected %i, found %i)\n", 189 new_crtc_state->hw.active, pipe_config->hw.active); 190 191 I915_STATE_WARN(dev_priv, crtc->active != new_crtc_state->hw.active, 192 "transitional active state does not match atomic hw state (expected %i, found %i)\n", 193 new_crtc_state->hw.active, crtc->active); 194 195 master_crtc = intel_master_crtc(new_crtc_state); 196 197 for_each_encoder_on_crtc(dev, &master_crtc->base, encoder) { 198 enum pipe pipe; 199 bool active; 200 201 active = encoder->get_hw_state(encoder, &pipe); 202 I915_STATE_WARN(dev_priv, active != new_crtc_state->hw.active, 203 "[ENCODER:%i] active %i with crtc active %i\n", 204 encoder->base.base.id, active, 205 new_crtc_state->hw.active); 206 207 I915_STATE_WARN(dev_priv, active && master_crtc->pipe != pipe, 208 "Encoder connected to wrong pipe %c\n", 209 pipe_name(pipe)); 210 211 if (active) 212 intel_encoder_get_config(encoder, pipe_config); 213 } 214 215 if (!new_crtc_state->hw.active) 216 return; 217 218 intel_pipe_config_sanity_check(dev_priv, pipe_config); 219 220 if (!intel_pipe_config_compare(new_crtc_state, 221 pipe_config, false)) { 222 I915_STATE_WARN(dev_priv, 1, "pipe state doesn't match!\n"); 223 intel_crtc_state_dump(pipe_config, NULL, "hw state"); 224 intel_crtc_state_dump(new_crtc_state, NULL, "sw state"); 225 } 226 } 227 228 void intel_modeset_verify_crtc(struct intel_crtc *crtc, 229 struct intel_atomic_state *state, 230 struct intel_crtc_state *old_crtc_state, 231 struct intel_crtc_state *new_crtc_state) 232 { 233 if (!intel_crtc_needs_modeset(new_crtc_state) && 234 !intel_crtc_needs_fastset(new_crtc_state)) 235 return; 236 237 intel_wm_state_verify(crtc, new_crtc_state); 238 verify_connector_state(state, crtc); 239 verify_crtc_state(crtc, old_crtc_state, new_crtc_state); 240 intel_shared_dpll_state_verify(crtc, old_crtc_state, new_crtc_state); 241 intel_mpllb_state_verify(state, new_crtc_state); 242 intel_c10pll_state_verify(state, new_crtc_state); 243 } 244 245 void intel_modeset_verify_disabled(struct drm_i915_private *dev_priv, 246 struct intel_atomic_state *state) 247 { 248 verify_encoder_state(dev_priv, state); 249 verify_connector_state(state, NULL); 250 intel_shared_dpll_verify_disabled(dev_priv); 251 } 252