1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include <linux/debugfs.h> 7 8 #include <drm/drm_print.h> 9 10 #include "hsw_ips.h" 11 #include "i915_reg.h" 12 #include "intel_color_regs.h" 13 #include "intel_de.h" 14 #include "intel_display_regs.h" 15 #include "intel_display_rpm.h" 16 #include "intel_display_types.h" 17 #include "intel_pcode.h" 18 19 static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) 20 { 21 struct intel_display *display = to_intel_display(crtc_state); 22 u32 val; 23 24 if (!crtc_state->ips_enabled) 25 return; 26 27 /* 28 * We can only enable IPS after we enable a plane and wait for a vblank 29 * This function is called from post_plane_update, which is run after 30 * a vblank wait. 31 */ 32 drm_WARN_ON(display->drm, 33 !(crtc_state->active_planes & ~BIT(PLANE_CURSOR))); 34 35 val = IPS_ENABLE; 36 37 if (display->ips.false_color) 38 val |= IPS_FALSE_COLOR; 39 40 if (display->platform.broadwell) { 41 drm_WARN_ON(display->drm, 42 intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL, 43 val | IPS_PCODE_CONTROL)); 44 /* 45 * Quoting Art Runyan: "its not safe to expect any particular 46 * value in IPS_CTL bit 31 after enabling IPS through the 47 * mailbox." Moreover, the mailbox may return a bogus state, 48 * so we need to just enable it and continue on. 49 */ 50 } else { 51 intel_de_write(display, IPS_CTL, val); 52 /* 53 * The bit only becomes 1 in the next vblank, so this wait here 54 * is essentially intel_wait_for_vblank. If we don't have this 55 * and don't wait for vblanks until the end of crtc_enable, then 56 * the HW state readout code will complain that the expected 57 * IPS_CTL value is not the one we read. 58 */ 59 if (intel_de_wait_for_set(display, IPS_CTL, IPS_ENABLE, 50)) 60 drm_err(display->drm, 61 "Timed out waiting for IPS enable\n"); 62 } 63 } 64 65 bool hsw_ips_disable(const struct intel_crtc_state *crtc_state) 66 { 67 struct intel_display *display = to_intel_display(crtc_state); 68 bool need_vblank_wait = false; 69 70 if (!crtc_state->ips_enabled) 71 return need_vblank_wait; 72 73 if (display->platform.broadwell) { 74 drm_WARN_ON(display->drm, 75 intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL, 0)); 76 /* 77 * Wait for PCODE to finish disabling IPS. The BSpec specified 78 * 42ms timeout value leads to occasional timeouts so use 100ms 79 * instead. 80 */ 81 if (intel_de_wait_for_clear(display, IPS_CTL, IPS_ENABLE, 100)) 82 drm_err(display->drm, 83 "Timed out waiting for IPS disable\n"); 84 } else { 85 intel_de_write(display, IPS_CTL, 0); 86 intel_de_posting_read(display, IPS_CTL); 87 } 88 89 /* We need to wait for a vblank before we can disable the plane. */ 90 need_vblank_wait = true; 91 92 return need_vblank_wait; 93 } 94 95 static bool hsw_ips_need_disable(struct intel_atomic_state *state, 96 struct intel_crtc *crtc) 97 { 98 struct intel_display *display = to_intel_display(state); 99 const struct intel_crtc_state *old_crtc_state = 100 intel_atomic_get_old_crtc_state(state, crtc); 101 const struct intel_crtc_state *new_crtc_state = 102 intel_atomic_get_new_crtc_state(state, crtc); 103 104 if (!old_crtc_state->ips_enabled) 105 return false; 106 107 if (intel_crtc_needs_modeset(new_crtc_state)) 108 return true; 109 110 /* 111 * Workaround : Do not read or write the pipe palette/gamma data while 112 * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. 113 * 114 * Disable IPS before we program the LUT. 115 */ 116 if (display->platform.haswell && 117 intel_crtc_needs_color_update(new_crtc_state) && 118 new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) 119 return true; 120 121 return !new_crtc_state->ips_enabled; 122 } 123 124 bool hsw_ips_pre_update(struct intel_atomic_state *state, 125 struct intel_crtc *crtc) 126 { 127 const struct intel_crtc_state *old_crtc_state = 128 intel_atomic_get_old_crtc_state(state, crtc); 129 130 if (!hsw_ips_need_disable(state, crtc)) 131 return false; 132 133 return hsw_ips_disable(old_crtc_state); 134 } 135 136 static bool hsw_ips_need_enable(struct intel_atomic_state *state, 137 struct intel_crtc *crtc) 138 { 139 struct intel_display *display = to_intel_display(state); 140 const struct intel_crtc_state *old_crtc_state = 141 intel_atomic_get_old_crtc_state(state, crtc); 142 const struct intel_crtc_state *new_crtc_state = 143 intel_atomic_get_new_crtc_state(state, crtc); 144 145 if (!new_crtc_state->ips_enabled) 146 return false; 147 148 if (intel_crtc_needs_modeset(new_crtc_state)) 149 return true; 150 151 /* 152 * Workaround : Do not read or write the pipe palette/gamma data while 153 * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled. 154 * 155 * Re-enable IPS after the LUT has been programmed. 156 */ 157 if (display->platform.haswell && 158 intel_crtc_needs_color_update(new_crtc_state) && 159 new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) 160 return true; 161 162 /* 163 * We can't read out IPS on broadwell, assume the worst and 164 * forcibly enable IPS on the first fastset. 165 */ 166 if (intel_crtc_needs_fastset(new_crtc_state) && old_crtc_state->inherited) 167 return true; 168 169 return !old_crtc_state->ips_enabled; 170 } 171 172 void hsw_ips_post_update(struct intel_atomic_state *state, 173 struct intel_crtc *crtc) 174 { 175 const struct intel_crtc_state *new_crtc_state = 176 intel_atomic_get_new_crtc_state(state, crtc); 177 178 if (!hsw_ips_need_enable(state, crtc)) 179 return; 180 181 hsw_ips_enable(new_crtc_state); 182 } 183 184 /* IPS only exists on ULT machines and is tied to pipe A. */ 185 bool hsw_crtc_supports_ips(struct intel_crtc *crtc) 186 { 187 struct intel_display *display = to_intel_display(crtc); 188 189 return HAS_IPS(display) && crtc->pipe == PIPE_A; 190 } 191 192 static bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state) 193 { 194 struct intel_display *display = to_intel_display(crtc_state); 195 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 196 197 /* IPS only exists on ULT machines and is tied to pipe A. */ 198 if (!hsw_crtc_supports_ips(crtc)) 199 return false; 200 201 if (!display->params.enable_ips) 202 return false; 203 204 if (crtc_state->pipe_bpp > 24) 205 return false; 206 207 /* 208 * We compare against max which means we must take 209 * the increased cdclk requirement into account when 210 * calculating the new cdclk. 211 * 212 * Should measure whether using a lower cdclk w/o IPS 213 */ 214 if (display->platform.broadwell && 215 crtc_state->pixel_rate > display->cdclk.max_cdclk_freq * 95 / 100) 216 return false; 217 218 return true; 219 } 220 221 int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state) 222 { 223 struct intel_display *display = to_intel_display(crtc_state); 224 225 if (!display->platform.broadwell) 226 return 0; 227 228 if (!hsw_crtc_state_ips_capable(crtc_state)) 229 return 0; 230 231 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ 232 return DIV_ROUND_UP(crtc_state->pixel_rate * 100, 95); 233 } 234 235 int hsw_ips_compute_config(struct intel_atomic_state *state, 236 struct intel_crtc *crtc) 237 { 238 struct intel_display *display = to_intel_display(state); 239 struct intel_crtc_state *crtc_state = 240 intel_atomic_get_new_crtc_state(state, crtc); 241 242 crtc_state->ips_enabled = false; 243 244 if (!hsw_crtc_state_ips_capable(crtc_state)) 245 return 0; 246 247 /* 248 * When IPS gets enabled, the pipe CRC changes. Since IPS gets 249 * enabled and disabled dynamically based on package C states, 250 * user space can't make reliable use of the CRCs, so let's just 251 * completely disable it. 252 */ 253 if (crtc_state->crc_enabled) 254 return 0; 255 256 /* IPS should be fine as long as at least one plane is enabled. */ 257 if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR))) 258 return 0; 259 260 if (display->platform.broadwell) { 261 const struct intel_cdclk_state *cdclk_state; 262 263 cdclk_state = intel_atomic_get_cdclk_state(state); 264 if (IS_ERR(cdclk_state)) 265 return PTR_ERR(cdclk_state); 266 267 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ 268 if (crtc_state->pixel_rate > intel_cdclk_logical(cdclk_state) * 95 / 100) 269 return 0; 270 } 271 272 crtc_state->ips_enabled = true; 273 274 return 0; 275 } 276 277 void hsw_ips_get_config(struct intel_crtc_state *crtc_state) 278 { 279 struct intel_display *display = to_intel_display(crtc_state); 280 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 281 282 if (!hsw_crtc_supports_ips(crtc)) 283 return; 284 285 if (display->platform.haswell) { 286 crtc_state->ips_enabled = intel_de_read(display, IPS_CTL) & IPS_ENABLE; 287 } else { 288 /* 289 * We cannot readout IPS state on broadwell, set to 290 * true so we can set it to a defined state on first 291 * commit. 292 */ 293 crtc_state->ips_enabled = true; 294 } 295 } 296 297 static int hsw_ips_debugfs_false_color_get(void *data, u64 *val) 298 { 299 struct intel_crtc *crtc = data; 300 struct intel_display *display = to_intel_display(crtc); 301 302 *val = display->ips.false_color; 303 304 return 0; 305 } 306 307 static int hsw_ips_debugfs_false_color_set(void *data, u64 val) 308 { 309 struct intel_crtc *crtc = data; 310 struct intel_display *display = to_intel_display(crtc); 311 struct intel_crtc_state *crtc_state; 312 int ret; 313 314 ret = drm_modeset_lock(&crtc->base.mutex, NULL); 315 if (ret) 316 return ret; 317 318 display->ips.false_color = val; 319 320 crtc_state = to_intel_crtc_state(crtc->base.state); 321 322 if (!crtc_state->hw.active) 323 goto unlock; 324 325 if (crtc_state->uapi.commit && 326 !try_wait_for_completion(&crtc_state->uapi.commit->hw_done)) 327 goto unlock; 328 329 hsw_ips_enable(crtc_state); 330 331 unlock: 332 drm_modeset_unlock(&crtc->base.mutex); 333 334 return ret; 335 } 336 337 DEFINE_DEBUGFS_ATTRIBUTE(hsw_ips_debugfs_false_color_fops, 338 hsw_ips_debugfs_false_color_get, 339 hsw_ips_debugfs_false_color_set, 340 "%llu\n"); 341 342 static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) 343 { 344 struct intel_crtc *crtc = m->private; 345 struct intel_display *display = to_intel_display(crtc); 346 struct ref_tracker *wakeref; 347 348 wakeref = intel_display_rpm_get(display); 349 350 seq_printf(m, "Enabled by kernel parameter: %s\n", 351 str_yes_no(display->params.enable_ips)); 352 353 if (DISPLAY_VER(display) >= 8) { 354 seq_puts(m, "Currently: unknown\n"); 355 } else { 356 if (intel_de_read(display, IPS_CTL) & IPS_ENABLE) 357 seq_puts(m, "Currently: enabled\n"); 358 else 359 seq_puts(m, "Currently: disabled\n"); 360 } 361 362 intel_display_rpm_put(display, wakeref); 363 364 return 0; 365 } 366 367 DEFINE_SHOW_ATTRIBUTE(hsw_ips_debugfs_status); 368 369 void hsw_ips_crtc_debugfs_add(struct intel_crtc *crtc) 370 { 371 if (!hsw_crtc_supports_ips(crtc)) 372 return; 373 374 debugfs_create_file("i915_ips_false_color", 0644, crtc->base.debugfs_entry, 375 crtc, &hsw_ips_debugfs_false_color_fops); 376 377 debugfs_create_file("i915_ips_status", 0444, crtc->base.debugfs_entry, 378 crtc, &hsw_ips_debugfs_status_fops); 379 } 380