brintos

brintos / linux-shallow public Read only

0
0
Text · 22.7 KiB · 0b7f213 Raw
720 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2022-2023 Intel Corporation4 */5 6#include "i915_drv.h"7#include "i915_reg.h"8#include "intel_color.h"9#include "intel_crtc.h"10#include "intel_de.h"11#include "intel_display_types.h"12#include "intel_vblank.h"13#include "intel_vrr.h"14 15/*16 * This timing diagram depicts the video signal in and17 * around the vertical blanking period.18 *19 * Assumptions about the fictitious mode used in this example:20 *  vblank_start >= 321 *  vsync_start = vblank_start + 122 *  vsync_end = vblank_start + 223 *  vtotal = vblank_start + 324 *25 *           start of vblank:26 *           latch double buffered registers27 *           increment frame counter (ctg+)28 *           generate start of vblank interrupt (gen4+)29 *           |30 *           |          frame start:31 *           |          generate frame start interrupt (aka. vblank interrupt) (gmch)32 *           |          may be shifted forward 1-3 extra lines via TRANSCONF33 *           |          |34 *           |          |  start of vsync:35 *           |          |  generate vsync interrupt36 *           |          |  |37 * ___xxxx___    ___xxxx___    ___xxxx___    ___xxxx___    ___xxxx___    ___xxxx38 *       .   \hs/   .      \hs/          \hs/          \hs/   .      \hs/39 * ----va---> <-----------------vb--------------------> <--------va-------------40 *       |          |       <----vs----->                     |41 * -vbs-----> <---vbs+1---> <---vbs+2---> <-----0-----> <-----1-----> <-----2--- (scanline counter gen2)42 * -vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2---> <-----0--- (scanline counter gen3+)43 * -vbs-2---> <---vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2- (scanline counter hsw+ hdmi)44 *       |          |                                         |45 *       last visible pixel                                   first visible pixel46 *                  |                                         increment frame counter (gen3/4)47 *                  pixel counter = vblank_start * htotal     pixel counter = 0 (gen3/4)48 *49 * x  = horizontal active50 * _  = horizontal blanking51 * hs = horizontal sync52 * va = vertical active53 * vb = vertical blanking54 * vs = vertical sync55 * vbs = vblank_start (number)56 *57 * Summary:58 * - most events happen at the start of horizontal sync59 * - frame start happens at the start of horizontal blank, 1-4 lines60 *   (depending on TRANSCONF settings) after the start of vblank61 * - gen3/4 pixel and frame counter are synchronized with the start62 *   of horizontal active on the first line of vertical active63 */64 65/*66 * Called from drm generic code, passed a 'crtc', which we use as a pipe index.67 */68u32 i915_get_vblank_counter(struct drm_crtc *crtc)69{70	struct intel_display *display = to_intel_display(crtc->dev);71	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);72	const struct drm_display_mode *mode = &vblank->hwmode;73	enum pipe pipe = to_intel_crtc(crtc)->pipe;74	u32 pixel, vbl_start, hsync_start, htotal;75	u64 frame;76 77	/*78	 * On i965gm TV output the frame counter only works up to79	 * the point when we enable the TV encoder. After that the80	 * frame counter ceases to work and reads zero. We need a81	 * vblank wait before enabling the TV encoder and so we82	 * have to enable vblank interrupts while the frame counter83	 * is still in a working state. However the core vblank code84	 * does not like us returning non-zero frame counter values85	 * when we've told it that we don't have a working frame86	 * counter. Thus we must stop non-zero values leaking out.87	 */88	if (!vblank->max_vblank_count)89		return 0;90 91	htotal = mode->crtc_htotal;92	hsync_start = mode->crtc_hsync_start;93	vbl_start = intel_mode_vblank_start(mode);94 95	/* Convert to pixel count */96	vbl_start *= htotal;97 98	/* Start of vblank event occurs at start of hsync */99	vbl_start -= htotal - hsync_start;100 101	/*102	 * High & low register fields aren't synchronized, so make sure103	 * we get a low value that's stable across two reads of the high104	 * register.105	 */106	frame = intel_de_read64_2x32(display, PIPEFRAMEPIXEL(display, pipe),107				     PIPEFRAME(display, pipe));108 109	pixel = frame & PIPE_PIXEL_MASK;110	frame = (frame >> PIPE_FRAME_LOW_SHIFT) & 0xffffff;111 112	/*113	 * The frame counter increments at beginning of active.114	 * Cook up a vblank counter by also checking the pixel115	 * counter against vblank start.116	 */117	return (frame + (pixel >= vbl_start)) & 0xffffff;118}119 120u32 g4x_get_vblank_counter(struct drm_crtc *crtc)121{122	struct intel_display *display = to_intel_display(crtc->dev);123	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);124	enum pipe pipe = to_intel_crtc(crtc)->pipe;125 126	if (!vblank->max_vblank_count)127		return 0;128 129	return intel_de_read(display, PIPE_FRMCOUNT_G4X(display, pipe));130}131 132static u32 intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc *crtc)133{134	struct intel_display *display = to_intel_display(crtc);135	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);136	const struct drm_display_mode *mode = &vblank->hwmode;137	u32 htotal = mode->crtc_htotal;138	u32 clock = mode->crtc_clock;139	u32 scan_prev_time, scan_curr_time, scan_post_time;140 141	/*142	 * To avoid the race condition where we might cross into the143	 * next vblank just between the PIPE_FRMTMSTMP and TIMESTAMP_CTR144	 * reads. We make sure we read PIPE_FRMTMSTMP and TIMESTAMP_CTR145	 * during the same frame.146	 */147	do {148		/*149		 * This field provides read back of the display150		 * pipe frame time stamp. The time stamp value151		 * is sampled at every start of vertical blank.152		 */153		scan_prev_time = intel_de_read_fw(display,154						  PIPE_FRMTMSTMP(crtc->pipe));155 156		/*157		 * The TIMESTAMP_CTR register has the current158		 * time stamp value.159		 */160		scan_curr_time = intel_de_read_fw(display, IVB_TIMESTAMP_CTR);161 162		scan_post_time = intel_de_read_fw(display,163						  PIPE_FRMTMSTMP(crtc->pipe));164	} while (scan_post_time != scan_prev_time);165 166	return div_u64(mul_u32_u32(scan_curr_time - scan_prev_time,167				   clock), 1000 * htotal);168}169 170/*171 * On certain encoders on certain platforms, pipe172 * scanline register will not work to get the scanline,173 * since the timings are driven from the PORT or issues174 * with scanline register updates.175 * This function will use Framestamp and current176 * timestamp registers to calculate the scanline.177 */178static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc)179{180	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);181	const struct drm_display_mode *mode = &vblank->hwmode;182	u32 vblank_start = mode->crtc_vblank_start;183	u32 vtotal = mode->crtc_vtotal;184	u32 scanline;185 186	scanline = intel_crtc_scanlines_since_frame_timestamp(crtc);187	scanline = min(scanline, vtotal - 1);188	scanline = (scanline + vblank_start) % vtotal;189 190	return scanline;191}192 193int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state)194{195	struct intel_display *display = to_intel_display(crtc_state);196	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);197 198	/*199	 * The scanline counter increments at the leading edge of hsync.200	 *201	 * On most platforms it starts counting from vtotal-1 on the202	 * first active line. That means the scanline counter value is203	 * always one less than what we would expect. Ie. just after204	 * start of vblank, which also occurs at start of hsync (on the205	 * last active line), the scanline counter will read vblank_start-1.206	 *207	 * On gen2 the scanline counter starts counting from 1 instead208	 * of vtotal-1, so we have to subtract one.209	 *210	 * On HSW+ the behaviour of the scanline counter depends on the output211	 * type. For DP ports it behaves like most other platforms, but on HDMI212	 * there's an extra 1 line difference. So we need to add two instead of213	 * one to the value.214	 *215	 * On VLV/CHV DSI the scanline counter would appear to increment216	 * approx. 1/3 of a scanline before start of vblank. Unfortunately217	 * that means we can't tell whether we're in vblank or not while218	 * we're on that particular line. We must still set scanline_offset219	 * to 1 so that the vblank timestamps come out correct when we query220	 * the scanline counter from within the vblank interrupt handler.221	 * However if queried just before the start of vblank we'll get an222	 * answer that's slightly in the future.223	 */224	if (DISPLAY_VER(display) == 2)225		return -1;226	else if (HAS_DDI(i915) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))227		return 2;228	else229		return 1;230}231 232/*233 * intel_de_read_fw(), only for fast reads of display block, no need for234 * forcewake etc.235 */236static int __intel_get_crtc_scanline(struct intel_crtc *crtc)237{238	struct intel_display *display = to_intel_display(crtc);239	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);240	const struct drm_display_mode *mode = &vblank->hwmode;241	enum pipe pipe = crtc->pipe;242	int position, vtotal;243 244	if (!crtc->active)245		return 0;246 247	if (crtc->mode_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP)248		return __intel_get_crtc_scanline_from_timestamp(crtc);249 250	vtotal = intel_mode_vtotal(mode);251 252	position = intel_de_read_fw(display, PIPEDSL(display, pipe)) & PIPEDSL_LINE_MASK;253 254	/*255	 * On HSW, the DSL reg (0x70000) appears to return 0 if we256	 * read it just before the start of vblank.  So try it again257	 * so we don't accidentally end up spanning a vblank frame258	 * increment, causing the pipe_update_end() code to squak at us.259	 *260	 * The nature of this problem means we can't simply check the ISR261	 * bit and return the vblank start value; nor can we use the scanline262	 * debug register in the transcoder as it appears to have the same263	 * problem.  We may need to extend this to include other platforms,264	 * but so far testing only shows the problem on HSW.265	 */266	if (HAS_DDI(display) && !position) {267		int i, temp;268 269		for (i = 0; i < 100; i++) {270			udelay(1);271			temp = intel_de_read_fw(display,272						PIPEDSL(display, pipe)) & PIPEDSL_LINE_MASK;273			if (temp != position) {274				position = temp;275				break;276			}277		}278	}279 280	/*281	 * See update_scanline_offset() for the details on the282	 * scanline_offset adjustment.283	 */284	return (position + vtotal + crtc->scanline_offset) % vtotal;285}286 287/*288 * The uncore version of the spin lock functions is used to decide289 * whether we need to lock the uncore lock or not.  This is only290 * needed in i915, not in Xe.291 *292 * This lock in i915 is needed because some old platforms (at least293 * IVB and possibly HSW as well), which are not supported in Xe, need294 * all register accesses to the same cacheline to be serialized,295 * otherwise they may hang.296 */297#ifdef I915298static void intel_vblank_section_enter(struct intel_display *display)299	__acquires(i915->uncore.lock)300{301	struct drm_i915_private *i915 = to_i915(display->drm);302	spin_lock(&i915->uncore.lock);303}304 305static void intel_vblank_section_exit(struct intel_display *display)306	__releases(i915->uncore.lock)307{308	struct drm_i915_private *i915 = to_i915(display->drm);309	spin_unlock(&i915->uncore.lock);310}311#else312static void intel_vblank_section_enter(struct intel_display *display)313{314}315 316static void intel_vblank_section_exit(struct intel_display *display)317{318}319#endif320 321static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,322				     bool in_vblank_irq,323				     int *vpos, int *hpos,324				     ktime_t *stime, ktime_t *etime,325				     const struct drm_display_mode *mode)326{327	struct intel_display *display = to_intel_display(_crtc->dev);328	struct drm_i915_private *dev_priv = to_i915(display->drm);329	struct intel_crtc *crtc = to_intel_crtc(_crtc);330	enum pipe pipe = crtc->pipe;331	int position;332	int vbl_start, vbl_end, hsync_start, htotal, vtotal;333	unsigned long irqflags;334	bool use_scanline_counter = DISPLAY_VER(display) >= 5 ||335		IS_G4X(dev_priv) || DISPLAY_VER(display) == 2 ||336		crtc->mode_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER;337 338	if (drm_WARN_ON(display->drm, !mode->crtc_clock)) {339		drm_dbg(display->drm,340			"trying to get scanoutpos for disabled pipe %c\n",341			pipe_name(pipe));342		return false;343	}344 345	htotal = mode->crtc_htotal;346	hsync_start = mode->crtc_hsync_start;347	vtotal = intel_mode_vtotal(mode);348	vbl_start = intel_mode_vblank_start(mode);349	vbl_end = intel_mode_vblank_end(mode);350 351	/*352	 * Enter vblank critical section, as we will do multiple353	 * timing critical raw register reads, potentially with354	 * preemption disabled, so the following code must not block.355	 */356	local_irq_save(irqflags);357	intel_vblank_section_enter(display);358 359	/* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */360 361	/* Get optional system timestamp before query. */362	if (stime)363		*stime = ktime_get();364 365	if (crtc->mode_flags & I915_MODE_FLAG_VRR) {366		int scanlines = intel_crtc_scanlines_since_frame_timestamp(crtc);367 368		position = __intel_get_crtc_scanline(crtc);369 370		/*371		 * Already exiting vblank? If so, shift our position372		 * so it looks like we're already apporaching the full373		 * vblank end. This should make the generated timestamp374		 * more or less match when the active portion will start.375		 */376		if (position >= vbl_start && scanlines < position)377			position = min(crtc->vmax_vblank_start + scanlines, vtotal - 1);378	} else if (use_scanline_counter) {379		/* No obvious pixelcount register. Only query vertical380		 * scanout position from Display scan line register.381		 */382		position = __intel_get_crtc_scanline(crtc);383	} else {384		/*385		 * Have access to pixelcount since start of frame.386		 * We can split this into vertical and horizontal387		 * scanout position.388		 */389		position = (intel_de_read_fw(display, PIPEFRAMEPIXEL(display, pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;390 391		/* convert to pixel counts */392		vbl_start *= htotal;393		vbl_end *= htotal;394		vtotal *= htotal;395 396		/*397		 * In interlaced modes, the pixel counter counts all pixels,398		 * so one field will have htotal more pixels. In order to avoid399		 * the reported position from jumping backwards when the pixel400		 * counter is beyond the length of the shorter field, just401		 * clamp the position the length of the shorter field. This402		 * matches how the scanline counter based position works since403		 * the scanline counter doesn't count the two half lines.404		 */405		position = min(position, vtotal - 1);406 407		/*408		 * Start of vblank interrupt is triggered at start of hsync,409		 * just prior to the first active line of vblank. However we410		 * consider lines to start at the leading edge of horizontal411		 * active. So, should we get here before we've crossed into412		 * the horizontal active of the first line in vblank, we would413		 * not set the DRM_SCANOUTPOS_INVBL flag. In order to fix that,414		 * always add htotal-hsync_start to the current pixel position.415		 */416		position = (position + htotal - hsync_start) % vtotal;417	}418 419	/* Get optional system timestamp after query. */420	if (etime)421		*etime = ktime_get();422 423	/* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */424 425	intel_vblank_section_exit(display);426	local_irq_restore(irqflags);427 428	/*429	 * While in vblank, position will be negative430	 * counting up towards 0 at vbl_end. And outside431	 * vblank, position will be positive counting432	 * up since vbl_end.433	 */434	if (position >= vbl_start)435		position -= vbl_end;436	else437		position += vtotal - vbl_end;438 439	if (use_scanline_counter) {440		*vpos = position;441		*hpos = 0;442	} else {443		*vpos = position / htotal;444		*hpos = position - (*vpos * htotal);445	}446 447	return true;448}449 450bool intel_crtc_get_vblank_timestamp(struct drm_crtc *crtc, int *max_error,451				     ktime_t *vblank_time, bool in_vblank_irq)452{453	return drm_crtc_vblank_helper_get_vblank_timestamp_internal(454		crtc, max_error, vblank_time, in_vblank_irq,455		i915_get_crtc_scanoutpos);456}457 458int intel_get_crtc_scanline(struct intel_crtc *crtc)459{460	struct intel_display *display = to_intel_display(crtc);461	unsigned long irqflags;462	int position;463 464	local_irq_save(irqflags);465	intel_vblank_section_enter(display);466 467	position = __intel_get_crtc_scanline(crtc);468 469	intel_vblank_section_exit(display);470	local_irq_restore(irqflags);471 472	return position;473}474 475static bool pipe_scanline_is_moving(struct intel_display *display,476				    enum pipe pipe)477{478	i915_reg_t reg = PIPEDSL(display, pipe);479	u32 line1, line2;480 481	line1 = intel_de_read(display, reg) & PIPEDSL_LINE_MASK;482	msleep(5);483	line2 = intel_de_read(display, reg) & PIPEDSL_LINE_MASK;484 485	return line1 != line2;486}487 488static void wait_for_pipe_scanline_moving(struct intel_crtc *crtc, bool state)489{490	struct intel_display *display = to_intel_display(crtc);491	enum pipe pipe = crtc->pipe;492 493	/* Wait for the display line to settle/start moving */494	if (wait_for(pipe_scanline_is_moving(display, pipe) == state, 100))495		drm_err(display->drm,496			"pipe %c scanline %s wait timed out\n",497			pipe_name(pipe), str_on_off(state));498}499 500void intel_wait_for_pipe_scanline_stopped(struct intel_crtc *crtc)501{502	wait_for_pipe_scanline_moving(crtc, false);503}504 505void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc)506{507	wait_for_pipe_scanline_moving(crtc, true);508}509 510void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state,511				      bool vrr_enable)512{513	struct intel_display *display = to_intel_display(crtc_state);514	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);515	u8 mode_flags = crtc_state->mode_flags;516	struct drm_display_mode adjusted_mode;517	int vmax_vblank_start = 0;518	unsigned long irqflags;519 520	drm_mode_init(&adjusted_mode, &crtc_state->hw.adjusted_mode);521 522	if (vrr_enable) {523		drm_WARN_ON(display->drm,524			    (mode_flags & I915_MODE_FLAG_VRR) == 0);525 526		adjusted_mode.crtc_vtotal = crtc_state->vrr.vmax;527		adjusted_mode.crtc_vblank_end = crtc_state->vrr.vmax;528		adjusted_mode.crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state);529		vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state);530	} else {531		mode_flags &= ~I915_MODE_FLAG_VRR;532	}533 534	/*535	 * Belts and suspenders locking to guarantee everyone sees 100%536	 * consistent state during fastset seamless refresh rate changes.537	 *538	 * vblank_time_lock takes care of all drm_vblank.c stuff, and539	 * uncore.lock takes care of __intel_get_crtc_scanline() which540	 * may get called elsewhere as well.541	 *542	 * TODO maybe just protect everything (including543	 * __intel_get_crtc_scanline()) with vblank_time_lock?544	 * Need to audit everything to make sure it's safe.545	 */546	spin_lock_irqsave(&display->drm->vblank_time_lock, irqflags);547	intel_vblank_section_enter(display);548 549	drm_calc_timestamping_constants(&crtc->base, &adjusted_mode);550 551	crtc->vmax_vblank_start = vmax_vblank_start;552 553	crtc->mode_flags = mode_flags;554 555	crtc->scanline_offset = intel_crtc_scanline_offset(crtc_state);556	intel_vblank_section_exit(display);557	spin_unlock_irqrestore(&display->drm->vblank_time_lock, irqflags);558}559 560int intel_mode_vdisplay(const struct drm_display_mode *mode)561{562	int vdisplay = mode->crtc_vdisplay;563 564	if (mode->flags & DRM_MODE_FLAG_INTERLACE)565		vdisplay = DIV_ROUND_UP(vdisplay, 2);566 567	return vdisplay;568}569 570int intel_mode_vblank_start(const struct drm_display_mode *mode)571{572	int vblank_start = mode->crtc_vblank_start;573 574	if (mode->flags & DRM_MODE_FLAG_INTERLACE)575		vblank_start = DIV_ROUND_UP(vblank_start, 2);576 577	return vblank_start;578}579 580int intel_mode_vblank_end(const struct drm_display_mode *mode)581{582	int vblank_end = mode->crtc_vblank_end;583 584	if (mode->flags & DRM_MODE_FLAG_INTERLACE)585		vblank_end /= 2;586 587	return vblank_end;588}589 590int intel_mode_vtotal(const struct drm_display_mode *mode)591{592	int vtotal = mode->crtc_vtotal;593 594	if (mode->flags & DRM_MODE_FLAG_INTERLACE)595		vtotal /= 2;596 597	return vtotal;598}599 600void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state,601			     const struct intel_crtc_state *new_crtc_state,602			     struct intel_vblank_evade_ctx *evade)603{604	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);605	struct drm_i915_private *i915 = to_i915(crtc->base.dev);606	const struct intel_crtc_state *crtc_state;607	const struct drm_display_mode *adjusted_mode;608 609	evade->crtc = crtc;610 611	evade->need_vlv_dsi_wa = (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) &&612		intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);613 614	/*615	 * During fastsets/etc. the transcoder is still616	 * running with the old timings at this point.617	 *618	 * TODO: maybe just use the active timings here?619	 */620	if (intel_crtc_needs_modeset(new_crtc_state))621		crtc_state = new_crtc_state;622	else623		crtc_state = old_crtc_state;624 625	adjusted_mode = &crtc_state->hw.adjusted_mode;626 627	if (crtc->mode_flags & I915_MODE_FLAG_VRR) {628		/* timing changes should happen with VRR disabled */629		drm_WARN_ON(crtc->base.dev, intel_crtc_needs_modeset(new_crtc_state) ||630			    new_crtc_state->update_m_n || new_crtc_state->update_lrr);631 632		if (intel_vrr_is_push_sent(crtc_state))633			evade->vblank_start = intel_vrr_vmin_vblank_start(crtc_state);634		else635			evade->vblank_start = intel_vrr_vmax_vblank_start(crtc_state);636	} else {637		evade->vblank_start = intel_mode_vblank_start(adjusted_mode);638	}639 640	/* FIXME needs to be calibrated sensibly */641	evade->min = evade->vblank_start - intel_usecs_to_scanlines(adjusted_mode,642								    VBLANK_EVASION_TIME_US);643	evade->max = evade->vblank_start - 1;644 645	/*646	 * M/N and TRANS_VTOTAL are double buffered on the transcoder's647	 * undelayed vblank, so with seamless M/N and LRR we must evade648	 * both vblanks.649	 *650	 * DSB execution waits for the transcoder's undelayed vblank,651	 * hence we must kick off the commit before that.652	 */653	if (intel_color_uses_dsb(new_crtc_state) ||654	    new_crtc_state->update_m_n || new_crtc_state->update_lrr)655		evade->min -= intel_mode_vblank_start(adjusted_mode) -656			intel_mode_vdisplay(adjusted_mode);657}658 659/* must be called with vblank interrupt already enabled! */660int intel_vblank_evade(struct intel_vblank_evade_ctx *evade)661{662	struct intel_crtc *crtc = evade->crtc;663	struct intel_display *display = to_intel_display(crtc);664	long timeout = msecs_to_jiffies_timeout(1);665	wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);666	DEFINE_WAIT(wait);667	int scanline;668 669	if (evade->min <= 0 || evade->max <= 0)670		return 0;671 672	for (;;) {673		/*674		 * prepare_to_wait() has a memory barrier, which guarantees675		 * other CPUs can see the task state update by the time we676		 * read the scanline.677		 */678		prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);679 680		scanline = intel_get_crtc_scanline(crtc);681		if (scanline < evade->min || scanline > evade->max)682			break;683 684		if (!timeout) {685			drm_err(display->drm,686				"Potential atomic update failure on pipe %c\n",687				pipe_name(crtc->pipe));688			break;689		}690 691		local_irq_enable();692 693		timeout = schedule_timeout(timeout);694 695		local_irq_disable();696	}697 698	finish_wait(wq, &wait);699 700	/*701	 * On VLV/CHV DSI the scanline counter would appear to702	 * increment approx. 1/3 of a scanline before start of vblank.703	 * The registers still get latched at start of vblank however.704	 * This means we must not write any registers on the first705	 * line of vblank (since not the whole line is actually in706	 * vblank). And unfortunately we can't use the interrupt to707	 * wait here since it will fire too soon. We could use the708	 * frame start interrupt instead since it will fire after the709	 * critical scanline, but that would require more changes710	 * in the interrupt code. So for now we'll just do the nasty711	 * thing and poll for the bad scanline to pass us by.712	 *713	 * FIXME figure out if BXT+ DSI suffers from this as well714	 */715	while (evade->need_vlv_dsi_wa && scanline == evade->vblank_start)716		scanline = intel_get_crtc_scanline(crtc);717 718	return scanline;719}720