Linux Audio

Check our new training course

Loading...
v5.14.15
  1/*
  2 * Copyright © 2013 Intel Corporation
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice (including the next
 12 * paragraph) shall be included in all copies or substantial portions of the
 13 * Software.
 14 *
 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21 * IN THE SOFTWARE.
 22 *
 23 * Author: Damien Lespiau <damien.lespiau@intel.com>
 24 *
 25 */
 26
 27#include <linux/circ_buf.h>
 28#include <linux/ctype.h>
 29#include <linux/debugfs.h>
 30#include <linux/seq_file.h>
 31
 
 
 32#include "intel_atomic.h"
 33#include "intel_de.h"
 34#include "intel_display_types.h"
 35#include "intel_pipe_crc.h"
 36
 37static const char * const pipe_crc_sources[] = {
 38	[INTEL_PIPE_CRC_SOURCE_NONE] = "none",
 39	[INTEL_PIPE_CRC_SOURCE_PLANE1] = "plane1",
 40	[INTEL_PIPE_CRC_SOURCE_PLANE2] = "plane2",
 41	[INTEL_PIPE_CRC_SOURCE_PLANE3] = "plane3",
 42	[INTEL_PIPE_CRC_SOURCE_PLANE4] = "plane4",
 43	[INTEL_PIPE_CRC_SOURCE_PLANE5] = "plane5",
 44	[INTEL_PIPE_CRC_SOURCE_PLANE6] = "plane6",
 45	[INTEL_PIPE_CRC_SOURCE_PLANE7] = "plane7",
 46	[INTEL_PIPE_CRC_SOURCE_PIPE] = "pipe",
 47	[INTEL_PIPE_CRC_SOURCE_TV] = "TV",
 48	[INTEL_PIPE_CRC_SOURCE_DP_B] = "DP-B",
 49	[INTEL_PIPE_CRC_SOURCE_DP_C] = "DP-C",
 50	[INTEL_PIPE_CRC_SOURCE_DP_D] = "DP-D",
 51	[INTEL_PIPE_CRC_SOURCE_AUTO] = "auto",
 52};
 53
 54static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
 55				 u32 *val)
 56{
 57	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
 58		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
 59
 60	switch (*source) {
 61	case INTEL_PIPE_CRC_SOURCE_PIPE:
 62		*val = PIPE_CRC_ENABLE | PIPE_CRC_INCLUDE_BORDER_I8XX;
 63		break;
 64	case INTEL_PIPE_CRC_SOURCE_NONE:
 65		*val = 0;
 66		break;
 67	default:
 68		return -EINVAL;
 69	}
 70
 71	return 0;
 72}
 73
 74static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
 75				     enum pipe pipe,
 76				     enum intel_pipe_crc_source *source)
 77{
 78	struct drm_device *dev = &dev_priv->drm;
 79	struct intel_encoder *encoder;
 80	struct intel_crtc *crtc;
 81	struct intel_digital_port *dig_port;
 82	int ret = 0;
 83
 84	*source = INTEL_PIPE_CRC_SOURCE_PIPE;
 85
 86	drm_modeset_lock_all(dev);
 87	for_each_intel_encoder(dev, encoder) {
 88		if (!encoder->base.crtc)
 89			continue;
 90
 91		crtc = to_intel_crtc(encoder->base.crtc);
 92
 93		if (crtc->pipe != pipe)
 94			continue;
 95
 96		switch (encoder->type) {
 97		case INTEL_OUTPUT_TVOUT:
 98			*source = INTEL_PIPE_CRC_SOURCE_TV;
 99			break;
100		case INTEL_OUTPUT_DP:
101		case INTEL_OUTPUT_EDP:
102			dig_port = enc_to_dig_port(encoder);
103			switch (dig_port->base.port) {
104			case PORT_B:
105				*source = INTEL_PIPE_CRC_SOURCE_DP_B;
106				break;
107			case PORT_C:
108				*source = INTEL_PIPE_CRC_SOURCE_DP_C;
109				break;
110			case PORT_D:
111				*source = INTEL_PIPE_CRC_SOURCE_DP_D;
112				break;
113			default:
114				drm_WARN(dev, 1, "nonexisting DP port %c\n",
115					 port_name(dig_port->base.port));
116				break;
117			}
118			break;
119		default:
120			break;
121		}
122	}
123	drm_modeset_unlock_all(dev);
124
125	return ret;
126}
127
128static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
129				enum pipe pipe,
130				enum intel_pipe_crc_source *source,
131				u32 *val)
132{
133	bool need_stable_symbols = false;
134
135	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) {
136		int ret = i9xx_pipe_crc_auto_source(dev_priv, pipe, source);
137		if (ret)
138			return ret;
139	}
140
141	switch (*source) {
142	case INTEL_PIPE_CRC_SOURCE_PIPE:
143		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_VLV;
144		break;
145	case INTEL_PIPE_CRC_SOURCE_DP_B:
146		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_VLV;
147		need_stable_symbols = true;
148		break;
149	case INTEL_PIPE_CRC_SOURCE_DP_C:
150		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV;
151		need_stable_symbols = true;
152		break;
153	case INTEL_PIPE_CRC_SOURCE_DP_D:
154		if (!IS_CHERRYVIEW(dev_priv))
155			return -EINVAL;
156		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_VLV;
157		need_stable_symbols = true;
158		break;
159	case INTEL_PIPE_CRC_SOURCE_NONE:
160		*val = 0;
161		break;
162	default:
163		return -EINVAL;
164	}
165
166	/*
167	 * When the pipe CRC tap point is after the transcoders we need
168	 * to tweak symbol-level features to produce a deterministic series of
169	 * symbols for a given frame. We need to reset those features only once
170	 * a frame (instead of every nth symbol):
171	 *   - DC-balance: used to ensure a better clock recovery from the data
172	 *     link (SDVO)
173	 *   - DisplayPort scrambling: used for EMI reduction
174	 */
175	if (need_stable_symbols) {
176		u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X);
177
178		tmp |= DC_BALANCE_RESET_VLV;
179		switch (pipe) {
180		case PIPE_A:
181			tmp |= PIPE_A_SCRAMBLE_RESET;
182			break;
183		case PIPE_B:
184			tmp |= PIPE_B_SCRAMBLE_RESET;
185			break;
186		case PIPE_C:
187			tmp |= PIPE_C_SCRAMBLE_RESET;
188			break;
189		default:
190			return -EINVAL;
191		}
192		intel_de_write(dev_priv, PORT_DFT2_G4X, tmp);
193	}
194
195	return 0;
196}
197
198static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
199				 enum pipe pipe,
200				 enum intel_pipe_crc_source *source,
201				 u32 *val)
202{
203	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) {
204		int ret = i9xx_pipe_crc_auto_source(dev_priv, pipe, source);
205		if (ret)
206			return ret;
207	}
208
209	switch (*source) {
210	case INTEL_PIPE_CRC_SOURCE_PIPE:
211		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_I9XX;
212		break;
213	case INTEL_PIPE_CRC_SOURCE_TV:
214		if (!SUPPORTS_TV(dev_priv))
215			return -EINVAL;
216		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_TV_PRE;
217		break;
218	case INTEL_PIPE_CRC_SOURCE_NONE:
219		*val = 0;
220		break;
221	default:
222		/*
223		 * The DP CRC source doesn't work on g4x.
224		 * It can be made to work to some degree by selecting
225		 * the correct CRC source before the port is enabled,
226		 * and not touching the CRC source bits again until
227		 * the port is disabled. But even then the bits
228		 * eventually get stuck and a reboot is needed to get
229		 * working CRCs on the pipe again. Let's simply
230		 * refuse to use DP CRCs on g4x.
231		 */
232		return -EINVAL;
233	}
234
235	return 0;
236}
237
238static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv,
239					 enum pipe pipe)
240{
241	u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X);
242
243	switch (pipe) {
244	case PIPE_A:
245		tmp &= ~PIPE_A_SCRAMBLE_RESET;
246		break;
247	case PIPE_B:
248		tmp &= ~PIPE_B_SCRAMBLE_RESET;
249		break;
250	case PIPE_C:
251		tmp &= ~PIPE_C_SCRAMBLE_RESET;
252		break;
253	default:
254		return;
255	}
256	if (!(tmp & PIPE_SCRAMBLE_RESET_MASK))
257		tmp &= ~DC_BALANCE_RESET_VLV;
258	intel_de_write(dev_priv, PORT_DFT2_G4X, tmp);
259}
260
261static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
262				u32 *val)
263{
264	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
265		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
266
267	switch (*source) {
268	case INTEL_PIPE_CRC_SOURCE_PLANE1:
269		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_ILK;
270		break;
271	case INTEL_PIPE_CRC_SOURCE_PLANE2:
272		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_ILK;
273		break;
274	case INTEL_PIPE_CRC_SOURCE_PIPE:
275		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_ILK;
276		break;
277	case INTEL_PIPE_CRC_SOURCE_NONE:
278		*val = 0;
279		break;
280	default:
281		return -EINVAL;
282	}
283
284	return 0;
285}
286
287static void
288intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable)
289{
290	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
291	struct intel_crtc_state *pipe_config;
292	struct drm_atomic_state *state;
293	struct drm_modeset_acquire_ctx ctx;
294	int ret;
295
296	drm_modeset_acquire_init(&ctx, 0);
297
298	state = drm_atomic_state_alloc(&dev_priv->drm);
299	if (!state) {
300		ret = -ENOMEM;
301		goto unlock;
302	}
303
304	state->acquire_ctx = &ctx;
 
305
306retry:
307	pipe_config = intel_atomic_get_crtc_state(state, crtc);
308	if (IS_ERR(pipe_config)) {
309		ret = PTR_ERR(pipe_config);
310		goto put_state;
311	}
312
313	pipe_config->uapi.mode_changed = pipe_config->has_psr;
314	pipe_config->crc_enabled = enable;
315
316	if (IS_HASWELL(dev_priv) &&
317	    pipe_config->hw.active && crtc->pipe == PIPE_A &&
318	    pipe_config->cpu_transcoder == TRANSCODER_EDP)
319		pipe_config->uapi.mode_changed = true;
320
321	ret = drm_atomic_commit(state);
322
323put_state:
324	if (ret == -EDEADLK) {
325		drm_atomic_state_clear(state);
326		drm_modeset_backoff(&ctx);
327		goto retry;
328	}
329
330	drm_atomic_state_put(state);
331unlock:
332	drm_WARN(&dev_priv->drm, ret,
333		 "Toggling workaround to %i returns %i\n", enable, ret);
334	drm_modeset_drop_locks(&ctx);
335	drm_modeset_acquire_fini(&ctx);
336}
337
338static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
339				enum pipe pipe,
340				enum intel_pipe_crc_source *source,
341				u32 *val)
342{
343	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
344		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
345
346	switch (*source) {
347	case INTEL_PIPE_CRC_SOURCE_PLANE1:
348		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_IVB;
349		break;
350	case INTEL_PIPE_CRC_SOURCE_PLANE2:
351		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB;
352		break;
353	case INTEL_PIPE_CRC_SOURCE_PIPE:
354		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB;
355		break;
356	case INTEL_PIPE_CRC_SOURCE_NONE:
357		*val = 0;
358		break;
359	default:
360		return -EINVAL;
361	}
362
363	return 0;
364}
365
366static int skl_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
367				enum pipe pipe,
368				enum intel_pipe_crc_source *source,
369				u32 *val)
370{
371	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
372		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
373
374	switch (*source) {
375	case INTEL_PIPE_CRC_SOURCE_PLANE1:
376		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_1_SKL;
377		break;
378	case INTEL_PIPE_CRC_SOURCE_PLANE2:
379		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_2_SKL;
380		break;
381	case INTEL_PIPE_CRC_SOURCE_PLANE3:
382		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_3_SKL;
383		break;
384	case INTEL_PIPE_CRC_SOURCE_PLANE4:
385		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_4_SKL;
386		break;
387	case INTEL_PIPE_CRC_SOURCE_PLANE5:
388		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_5_SKL;
389		break;
390	case INTEL_PIPE_CRC_SOURCE_PLANE6:
391		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_6_SKL;
392		break;
393	case INTEL_PIPE_CRC_SOURCE_PLANE7:
394		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_7_SKL;
395		break;
396	case INTEL_PIPE_CRC_SOURCE_PIPE:
397		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DMUX_SKL;
398		break;
399	case INTEL_PIPE_CRC_SOURCE_NONE:
400		*val = 0;
401		break;
402	default:
403		return -EINVAL;
404	}
405
406	return 0;
407}
408
409static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv,
410			       enum pipe pipe,
411			       enum intel_pipe_crc_source *source, u32 *val)
412{
413	if (DISPLAY_VER(dev_priv) == 2)
414		return i8xx_pipe_crc_ctl_reg(source, val);
415	else if (DISPLAY_VER(dev_priv) < 5)
416		return i9xx_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
417	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
418		return vlv_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
419	else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv))
420		return ilk_pipe_crc_ctl_reg(source, val);
421	else if (DISPLAY_VER(dev_priv) < 9)
422		return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
423	else
424		return skl_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
425}
426
427static int
428display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s)
429{
430	int i;
431
432	if (!buf) {
433		*s = INTEL_PIPE_CRC_SOURCE_NONE;
434		return 0;
435	}
436
437	i = match_string(pipe_crc_sources, ARRAY_SIZE(pipe_crc_sources), buf);
438	if (i < 0)
439		return i;
440
441	*s = i;
442	return 0;
443}
444
445void intel_crtc_crc_init(struct intel_crtc *crtc)
446{
447	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
448
449	spin_lock_init(&pipe_crc->lock);
450}
451
452static int i8xx_crc_source_valid(struct drm_i915_private *dev_priv,
453				 const enum intel_pipe_crc_source source)
454{
455	switch (source) {
456	case INTEL_PIPE_CRC_SOURCE_PIPE:
457	case INTEL_PIPE_CRC_SOURCE_NONE:
458		return 0;
459	default:
460		return -EINVAL;
461	}
462}
463
464static int i9xx_crc_source_valid(struct drm_i915_private *dev_priv,
465				 const enum intel_pipe_crc_source source)
466{
467	switch (source) {
468	case INTEL_PIPE_CRC_SOURCE_PIPE:
469	case INTEL_PIPE_CRC_SOURCE_TV:
470	case INTEL_PIPE_CRC_SOURCE_NONE:
471		return 0;
472	default:
473		return -EINVAL;
474	}
475}
476
477static int vlv_crc_source_valid(struct drm_i915_private *dev_priv,
478				const enum intel_pipe_crc_source source)
479{
480	switch (source) {
481	case INTEL_PIPE_CRC_SOURCE_PIPE:
482	case INTEL_PIPE_CRC_SOURCE_DP_B:
483	case INTEL_PIPE_CRC_SOURCE_DP_C:
484	case INTEL_PIPE_CRC_SOURCE_DP_D:
485	case INTEL_PIPE_CRC_SOURCE_NONE:
486		return 0;
487	default:
488		return -EINVAL;
489	}
490}
491
492static int ilk_crc_source_valid(struct drm_i915_private *dev_priv,
493				const enum intel_pipe_crc_source source)
494{
495	switch (source) {
496	case INTEL_PIPE_CRC_SOURCE_PIPE:
497	case INTEL_PIPE_CRC_SOURCE_PLANE1:
498	case INTEL_PIPE_CRC_SOURCE_PLANE2:
499	case INTEL_PIPE_CRC_SOURCE_NONE:
500		return 0;
501	default:
502		return -EINVAL;
503	}
504}
505
506static int ivb_crc_source_valid(struct drm_i915_private *dev_priv,
507				const enum intel_pipe_crc_source source)
508{
509	switch (source) {
510	case INTEL_PIPE_CRC_SOURCE_PIPE:
511	case INTEL_PIPE_CRC_SOURCE_PLANE1:
512	case INTEL_PIPE_CRC_SOURCE_PLANE2:
513	case INTEL_PIPE_CRC_SOURCE_NONE:
514		return 0;
515	default:
516		return -EINVAL;
517	}
518}
519
520static int skl_crc_source_valid(struct drm_i915_private *dev_priv,
521				const enum intel_pipe_crc_source source)
522{
523	switch (source) {
524	case INTEL_PIPE_CRC_SOURCE_PIPE:
525	case INTEL_PIPE_CRC_SOURCE_PLANE1:
526	case INTEL_PIPE_CRC_SOURCE_PLANE2:
527	case INTEL_PIPE_CRC_SOURCE_PLANE3:
528	case INTEL_PIPE_CRC_SOURCE_PLANE4:
529	case INTEL_PIPE_CRC_SOURCE_PLANE5:
530	case INTEL_PIPE_CRC_SOURCE_PLANE6:
531	case INTEL_PIPE_CRC_SOURCE_PLANE7:
532	case INTEL_PIPE_CRC_SOURCE_NONE:
533		return 0;
534	default:
535		return -EINVAL;
536	}
537}
538
539static int
540intel_is_valid_crc_source(struct drm_i915_private *dev_priv,
541			  const enum intel_pipe_crc_source source)
542{
543	if (DISPLAY_VER(dev_priv) == 2)
544		return i8xx_crc_source_valid(dev_priv, source);
545	else if (DISPLAY_VER(dev_priv) < 5)
546		return i9xx_crc_source_valid(dev_priv, source);
547	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
548		return vlv_crc_source_valid(dev_priv, source);
549	else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv))
550		return ilk_crc_source_valid(dev_priv, source);
551	else if (DISPLAY_VER(dev_priv) < 9)
552		return ivb_crc_source_valid(dev_priv, source);
553	else
554		return skl_crc_source_valid(dev_priv, source);
555}
556
557const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc,
558					      size_t *count)
559{
560	*count = ARRAY_SIZE(pipe_crc_sources);
561	return pipe_crc_sources;
562}
563
564int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
565				 size_t *values_cnt)
566{
567	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
568	enum intel_pipe_crc_source source;
569
570	if (display_crc_ctl_parse_source(source_name, &source) < 0) {
571		drm_dbg(&dev_priv->drm, "unknown source %s\n", source_name);
572		return -EINVAL;
573	}
574
575	if (source == INTEL_PIPE_CRC_SOURCE_AUTO ||
576	    intel_is_valid_crc_source(dev_priv, source) == 0) {
577		*values_cnt = 5;
578		return 0;
579	}
580
581	return -EINVAL;
582}
583
584int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name)
585{
586	struct intel_crtc *crtc = to_intel_crtc(_crtc);
587	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
588	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
589	enum intel_display_power_domain power_domain;
590	enum intel_pipe_crc_source source;
591	enum pipe pipe = crtc->pipe;
592	intel_wakeref_t wakeref;
593	u32 val = 0; /* shut up gcc */
594	int ret = 0;
595	bool enable;
596
597	if (display_crc_ctl_parse_source(source_name, &source) < 0) {
598		drm_dbg(&dev_priv->drm, "unknown source %s\n", source_name);
599		return -EINVAL;
600	}
601
602	power_domain = POWER_DOMAIN_PIPE(pipe);
603	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
604	if (!wakeref) {
605		drm_dbg_kms(&dev_priv->drm,
606			    "Trying to capture CRC while pipe is off\n");
607		return -EIO;
608	}
609
610	enable = source != INTEL_PIPE_CRC_SOURCE_NONE;
611	if (enable)
612		intel_crtc_crc_setup_workarounds(crtc, true);
613
614	ret = get_new_crc_ctl_reg(dev_priv, pipe, &source, &val);
615	if (ret != 0)
616		goto out;
617
618	pipe_crc->source = source;
619	intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
620	intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
621
622	if (!source) {
623		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
624			vlv_undo_pipe_scramble_reset(dev_priv, pipe);
625	}
626
627	pipe_crc->skipped = 0;
628
629out:
630	if (!enable)
631		intel_crtc_crc_setup_workarounds(crtc, false);
632
633	intel_display_power_put(dev_priv, power_domain, wakeref);
634
635	return ret;
636}
637
638void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc)
639{
640	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
641	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
642	enum pipe pipe = crtc->pipe;
643	u32 val = 0;
644
645	if (!crtc->base.crc.opened)
646		return;
647
648	if (get_new_crc_ctl_reg(dev_priv, pipe, &pipe_crc->source, &val) < 0)
649		return;
650
651	/* Don't need pipe_crc->lock here, IRQs are not generated. */
652	pipe_crc->skipped = 0;
653
654	intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
655	intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
656}
657
658void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
659{
660	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
661	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
662	enum pipe pipe = crtc->pipe;
663
664	/* Swallow crc's until we stop generating them. */
665	spin_lock_irq(&pipe_crc->lock);
666	pipe_crc->skipped = INT_MIN;
667	spin_unlock_irq(&pipe_crc->lock);
668
669	intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), 0);
670	intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
671	intel_synchronize_irq(dev_priv);
672}
v6.8
  1/*
  2 * Copyright © 2013 Intel Corporation
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice (including the next
 12 * paragraph) shall be included in all copies or substantial portions of the
 13 * Software.
 14 *
 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21 * IN THE SOFTWARE.
 22 *
 23 * Author: Damien Lespiau <damien.lespiau@intel.com>
 24 *
 25 */
 26
 
 27#include <linux/ctype.h>
 28#include <linux/debugfs.h>
 29#include <linux/seq_file.h>
 30
 31#include "i915_irq.h"
 32#include "i915_reg.h"
 33#include "intel_atomic.h"
 34#include "intel_de.h"
 35#include "intel_display_types.h"
 36#include "intel_pipe_crc.h"
 37
 38static const char * const pipe_crc_sources[] = {
 39	[INTEL_PIPE_CRC_SOURCE_NONE] = "none",
 40	[INTEL_PIPE_CRC_SOURCE_PLANE1] = "plane1",
 41	[INTEL_PIPE_CRC_SOURCE_PLANE2] = "plane2",
 42	[INTEL_PIPE_CRC_SOURCE_PLANE3] = "plane3",
 43	[INTEL_PIPE_CRC_SOURCE_PLANE4] = "plane4",
 44	[INTEL_PIPE_CRC_SOURCE_PLANE5] = "plane5",
 45	[INTEL_PIPE_CRC_SOURCE_PLANE6] = "plane6",
 46	[INTEL_PIPE_CRC_SOURCE_PLANE7] = "plane7",
 47	[INTEL_PIPE_CRC_SOURCE_PIPE] = "pipe",
 48	[INTEL_PIPE_CRC_SOURCE_TV] = "TV",
 49	[INTEL_PIPE_CRC_SOURCE_DP_B] = "DP-B",
 50	[INTEL_PIPE_CRC_SOURCE_DP_C] = "DP-C",
 51	[INTEL_PIPE_CRC_SOURCE_DP_D] = "DP-D",
 52	[INTEL_PIPE_CRC_SOURCE_AUTO] = "auto",
 53};
 54
 55static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
 56				 u32 *val)
 57{
 58	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
 59		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
 60
 61	switch (*source) {
 62	case INTEL_PIPE_CRC_SOURCE_PIPE:
 63		*val = PIPE_CRC_ENABLE | PIPE_CRC_INCLUDE_BORDER_I8XX;
 64		break;
 65	case INTEL_PIPE_CRC_SOURCE_NONE:
 66		*val = 0;
 67		break;
 68	default:
 69		return -EINVAL;
 70	}
 71
 72	return 0;
 73}
 74
 75static void i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
 76				      enum pipe pipe,
 77				      enum intel_pipe_crc_source *source)
 78{
 
 79	struct intel_encoder *encoder;
 80	struct intel_crtc *crtc;
 81	struct intel_digital_port *dig_port;
 
 82
 83	*source = INTEL_PIPE_CRC_SOURCE_PIPE;
 84
 85	drm_modeset_lock_all(&dev_priv->drm);
 86	for_each_intel_encoder(&dev_priv->drm, encoder) {
 87		if (!encoder->base.crtc)
 88			continue;
 89
 90		crtc = to_intel_crtc(encoder->base.crtc);
 91
 92		if (crtc->pipe != pipe)
 93			continue;
 94
 95		switch (encoder->type) {
 96		case INTEL_OUTPUT_TVOUT:
 97			*source = INTEL_PIPE_CRC_SOURCE_TV;
 98			break;
 99		case INTEL_OUTPUT_DP:
100		case INTEL_OUTPUT_EDP:
101			dig_port = enc_to_dig_port(encoder);
102			switch (dig_port->base.port) {
103			case PORT_B:
104				*source = INTEL_PIPE_CRC_SOURCE_DP_B;
105				break;
106			case PORT_C:
107				*source = INTEL_PIPE_CRC_SOURCE_DP_C;
108				break;
109			case PORT_D:
110				*source = INTEL_PIPE_CRC_SOURCE_DP_D;
111				break;
112			default:
113				drm_WARN(&dev_priv->drm, 1, "nonexisting DP port %c\n",
114					 port_name(dig_port->base.port));
115				break;
116			}
117			break;
118		default:
119			break;
120		}
121	}
122	drm_modeset_unlock_all(&dev_priv->drm);
 
 
123}
124
125static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
126				enum pipe pipe,
127				enum intel_pipe_crc_source *source,
128				u32 *val)
129{
130	bool need_stable_symbols = false;
131
132	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
133		i9xx_pipe_crc_auto_source(dev_priv, pipe, source);
 
 
 
134
135	switch (*source) {
136	case INTEL_PIPE_CRC_SOURCE_PIPE:
137		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_VLV;
138		break;
139	case INTEL_PIPE_CRC_SOURCE_DP_B:
140		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_VLV;
141		need_stable_symbols = true;
142		break;
143	case INTEL_PIPE_CRC_SOURCE_DP_C:
144		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV;
145		need_stable_symbols = true;
146		break;
147	case INTEL_PIPE_CRC_SOURCE_DP_D:
148		if (!IS_CHERRYVIEW(dev_priv))
149			return -EINVAL;
150		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_VLV;
151		need_stable_symbols = true;
152		break;
153	case INTEL_PIPE_CRC_SOURCE_NONE:
154		*val = 0;
155		break;
156	default:
157		return -EINVAL;
158	}
159
160	/*
161	 * When the pipe CRC tap point is after the transcoders we need
162	 * to tweak symbol-level features to produce a deterministic series of
163	 * symbols for a given frame. We need to reset those features only once
164	 * a frame (instead of every nth symbol):
165	 *   - DC-balance: used to ensure a better clock recovery from the data
166	 *     link (SDVO)
167	 *   - DisplayPort scrambling: used for EMI reduction
168	 */
169	if (need_stable_symbols) {
170		u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X);
171
172		tmp |= DC_BALANCE_RESET_VLV;
173		switch (pipe) {
174		case PIPE_A:
175			tmp |= PIPE_A_SCRAMBLE_RESET;
176			break;
177		case PIPE_B:
178			tmp |= PIPE_B_SCRAMBLE_RESET;
179			break;
180		case PIPE_C:
181			tmp |= PIPE_C_SCRAMBLE_RESET;
182			break;
183		default:
184			return -EINVAL;
185		}
186		intel_de_write(dev_priv, PORT_DFT2_G4X, tmp);
187	}
188
189	return 0;
190}
191
192static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
193				 enum pipe pipe,
194				 enum intel_pipe_crc_source *source,
195				 u32 *val)
196{
197	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
198		i9xx_pipe_crc_auto_source(dev_priv, pipe, source);
 
 
 
199
200	switch (*source) {
201	case INTEL_PIPE_CRC_SOURCE_PIPE:
202		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_I9XX;
203		break;
204	case INTEL_PIPE_CRC_SOURCE_TV:
205		if (!SUPPORTS_TV(dev_priv))
206			return -EINVAL;
207		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_TV_PRE;
208		break;
209	case INTEL_PIPE_CRC_SOURCE_NONE:
210		*val = 0;
211		break;
212	default:
213		/*
214		 * The DP CRC source doesn't work on g4x.
215		 * It can be made to work to some degree by selecting
216		 * the correct CRC source before the port is enabled,
217		 * and not touching the CRC source bits again until
218		 * the port is disabled. But even then the bits
219		 * eventually get stuck and a reboot is needed to get
220		 * working CRCs on the pipe again. Let's simply
221		 * refuse to use DP CRCs on g4x.
222		 */
223		return -EINVAL;
224	}
225
226	return 0;
227}
228
229static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv,
230					 enum pipe pipe)
231{
232	u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X);
233
234	switch (pipe) {
235	case PIPE_A:
236		tmp &= ~PIPE_A_SCRAMBLE_RESET;
237		break;
238	case PIPE_B:
239		tmp &= ~PIPE_B_SCRAMBLE_RESET;
240		break;
241	case PIPE_C:
242		tmp &= ~PIPE_C_SCRAMBLE_RESET;
243		break;
244	default:
245		return;
246	}
247	if (!(tmp & PIPE_SCRAMBLE_RESET_MASK))
248		tmp &= ~DC_BALANCE_RESET_VLV;
249	intel_de_write(dev_priv, PORT_DFT2_G4X, tmp);
250}
251
252static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
253				u32 *val)
254{
255	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
256		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
257
258	switch (*source) {
259	case INTEL_PIPE_CRC_SOURCE_PLANE1:
260		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_ILK;
261		break;
262	case INTEL_PIPE_CRC_SOURCE_PLANE2:
263		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_ILK;
264		break;
265	case INTEL_PIPE_CRC_SOURCE_PIPE:
266		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_ILK;
267		break;
268	case INTEL_PIPE_CRC_SOURCE_NONE:
269		*val = 0;
270		break;
271	default:
272		return -EINVAL;
273	}
274
275	return 0;
276}
277
278static void
279intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable)
280{
281	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
282	struct intel_crtc_state *pipe_config;
283	struct drm_atomic_state *state;
284	struct drm_modeset_acquire_ctx ctx;
285	int ret;
286
287	drm_modeset_acquire_init(&ctx, 0);
288
289	state = drm_atomic_state_alloc(&dev_priv->drm);
290	if (!state) {
291		ret = -ENOMEM;
292		goto unlock;
293	}
294
295	state->acquire_ctx = &ctx;
296	to_intel_atomic_state(state)->internal = true;
297
298retry:
299	pipe_config = intel_atomic_get_crtc_state(state, crtc);
300	if (IS_ERR(pipe_config)) {
301		ret = PTR_ERR(pipe_config);
302		goto put_state;
303	}
304
305	pipe_config->uapi.mode_changed = pipe_config->has_psr;
306	pipe_config->crc_enabled = enable;
307
308	if (IS_HASWELL(dev_priv) &&
309	    pipe_config->hw.active && crtc->pipe == PIPE_A &&
310	    pipe_config->cpu_transcoder == TRANSCODER_EDP)
311		pipe_config->uapi.mode_changed = true;
312
313	ret = drm_atomic_commit(state);
314
315put_state:
316	if (ret == -EDEADLK) {
317		drm_atomic_state_clear(state);
318		drm_modeset_backoff(&ctx);
319		goto retry;
320	}
321
322	drm_atomic_state_put(state);
323unlock:
324	drm_WARN(&dev_priv->drm, ret,
325		 "Toggling workaround to %i returns %i\n", enable, ret);
326	drm_modeset_drop_locks(&ctx);
327	drm_modeset_acquire_fini(&ctx);
328}
329
330static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
331				enum pipe pipe,
332				enum intel_pipe_crc_source *source,
333				u32 *val)
334{
335	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
336		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
337
338	switch (*source) {
339	case INTEL_PIPE_CRC_SOURCE_PLANE1:
340		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_IVB;
341		break;
342	case INTEL_PIPE_CRC_SOURCE_PLANE2:
343		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB;
344		break;
345	case INTEL_PIPE_CRC_SOURCE_PIPE:
346		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB;
347		break;
348	case INTEL_PIPE_CRC_SOURCE_NONE:
349		*val = 0;
350		break;
351	default:
352		return -EINVAL;
353	}
354
355	return 0;
356}
357
358static int skl_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
359				enum pipe pipe,
360				enum intel_pipe_crc_source *source,
361				u32 *val)
362{
363	if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
364		*source = INTEL_PIPE_CRC_SOURCE_PIPE;
365
366	switch (*source) {
367	case INTEL_PIPE_CRC_SOURCE_PLANE1:
368		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_1_SKL;
369		break;
370	case INTEL_PIPE_CRC_SOURCE_PLANE2:
371		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_2_SKL;
372		break;
373	case INTEL_PIPE_CRC_SOURCE_PLANE3:
374		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_3_SKL;
375		break;
376	case INTEL_PIPE_CRC_SOURCE_PLANE4:
377		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_4_SKL;
378		break;
379	case INTEL_PIPE_CRC_SOURCE_PLANE5:
380		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_5_SKL;
381		break;
382	case INTEL_PIPE_CRC_SOURCE_PLANE6:
383		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_6_SKL;
384		break;
385	case INTEL_PIPE_CRC_SOURCE_PLANE7:
386		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PLANE_7_SKL;
387		break;
388	case INTEL_PIPE_CRC_SOURCE_PIPE:
389		*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DMUX_SKL;
390		break;
391	case INTEL_PIPE_CRC_SOURCE_NONE:
392		*val = 0;
393		break;
394	default:
395		return -EINVAL;
396	}
397
398	return 0;
399}
400
401static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv,
402			       enum pipe pipe,
403			       enum intel_pipe_crc_source *source, u32 *val)
404{
405	if (DISPLAY_VER(dev_priv) == 2)
406		return i8xx_pipe_crc_ctl_reg(source, val);
407	else if (DISPLAY_VER(dev_priv) < 5)
408		return i9xx_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
409	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
410		return vlv_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
411	else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv))
412		return ilk_pipe_crc_ctl_reg(source, val);
413	else if (DISPLAY_VER(dev_priv) < 9)
414		return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
415	else
416		return skl_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
417}
418
419static int
420display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s)
421{
422	int i;
423
424	if (!buf) {
425		*s = INTEL_PIPE_CRC_SOURCE_NONE;
426		return 0;
427	}
428
429	i = match_string(pipe_crc_sources, ARRAY_SIZE(pipe_crc_sources), buf);
430	if (i < 0)
431		return i;
432
433	*s = i;
434	return 0;
435}
436
437void intel_crtc_crc_init(struct intel_crtc *crtc)
438{
439	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
440
441	spin_lock_init(&pipe_crc->lock);
442}
443
444static int i8xx_crc_source_valid(struct drm_i915_private *dev_priv,
445				 const enum intel_pipe_crc_source source)
446{
447	switch (source) {
448	case INTEL_PIPE_CRC_SOURCE_PIPE:
449	case INTEL_PIPE_CRC_SOURCE_NONE:
450		return 0;
451	default:
452		return -EINVAL;
453	}
454}
455
456static int i9xx_crc_source_valid(struct drm_i915_private *dev_priv,
457				 const enum intel_pipe_crc_source source)
458{
459	switch (source) {
460	case INTEL_PIPE_CRC_SOURCE_PIPE:
461	case INTEL_PIPE_CRC_SOURCE_TV:
462	case INTEL_PIPE_CRC_SOURCE_NONE:
463		return 0;
464	default:
465		return -EINVAL;
466	}
467}
468
469static int vlv_crc_source_valid(struct drm_i915_private *dev_priv,
470				const enum intel_pipe_crc_source source)
471{
472	switch (source) {
473	case INTEL_PIPE_CRC_SOURCE_PIPE:
474	case INTEL_PIPE_CRC_SOURCE_DP_B:
475	case INTEL_PIPE_CRC_SOURCE_DP_C:
476	case INTEL_PIPE_CRC_SOURCE_DP_D:
477	case INTEL_PIPE_CRC_SOURCE_NONE:
478		return 0;
479	default:
480		return -EINVAL;
481	}
482}
483
484static int ilk_crc_source_valid(struct drm_i915_private *dev_priv,
485				const enum intel_pipe_crc_source source)
486{
487	switch (source) {
488	case INTEL_PIPE_CRC_SOURCE_PIPE:
489	case INTEL_PIPE_CRC_SOURCE_PLANE1:
490	case INTEL_PIPE_CRC_SOURCE_PLANE2:
491	case INTEL_PIPE_CRC_SOURCE_NONE:
492		return 0;
493	default:
494		return -EINVAL;
495	}
496}
497
498static int ivb_crc_source_valid(struct drm_i915_private *dev_priv,
499				const enum intel_pipe_crc_source source)
500{
501	switch (source) {
502	case INTEL_PIPE_CRC_SOURCE_PIPE:
503	case INTEL_PIPE_CRC_SOURCE_PLANE1:
504	case INTEL_PIPE_CRC_SOURCE_PLANE2:
505	case INTEL_PIPE_CRC_SOURCE_NONE:
506		return 0;
507	default:
508		return -EINVAL;
509	}
510}
511
512static int skl_crc_source_valid(struct drm_i915_private *dev_priv,
513				const enum intel_pipe_crc_source source)
514{
515	switch (source) {
516	case INTEL_PIPE_CRC_SOURCE_PIPE:
517	case INTEL_PIPE_CRC_SOURCE_PLANE1:
518	case INTEL_PIPE_CRC_SOURCE_PLANE2:
519	case INTEL_PIPE_CRC_SOURCE_PLANE3:
520	case INTEL_PIPE_CRC_SOURCE_PLANE4:
521	case INTEL_PIPE_CRC_SOURCE_PLANE5:
522	case INTEL_PIPE_CRC_SOURCE_PLANE6:
523	case INTEL_PIPE_CRC_SOURCE_PLANE7:
524	case INTEL_PIPE_CRC_SOURCE_NONE:
525		return 0;
526	default:
527		return -EINVAL;
528	}
529}
530
531static int
532intel_is_valid_crc_source(struct drm_i915_private *dev_priv,
533			  const enum intel_pipe_crc_source source)
534{
535	if (DISPLAY_VER(dev_priv) == 2)
536		return i8xx_crc_source_valid(dev_priv, source);
537	else if (DISPLAY_VER(dev_priv) < 5)
538		return i9xx_crc_source_valid(dev_priv, source);
539	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
540		return vlv_crc_source_valid(dev_priv, source);
541	else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv))
542		return ilk_crc_source_valid(dev_priv, source);
543	else if (DISPLAY_VER(dev_priv) < 9)
544		return ivb_crc_source_valid(dev_priv, source);
545	else
546		return skl_crc_source_valid(dev_priv, source);
547}
548
549const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc,
550					      size_t *count)
551{
552	*count = ARRAY_SIZE(pipe_crc_sources);
553	return pipe_crc_sources;
554}
555
556int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
557				 size_t *values_cnt)
558{
559	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
560	enum intel_pipe_crc_source source;
561
562	if (display_crc_ctl_parse_source(source_name, &source) < 0) {
563		drm_dbg(&dev_priv->drm, "unknown source %s\n", source_name);
564		return -EINVAL;
565	}
566
567	if (source == INTEL_PIPE_CRC_SOURCE_AUTO ||
568	    intel_is_valid_crc_source(dev_priv, source) == 0) {
569		*values_cnt = 5;
570		return 0;
571	}
572
573	return -EINVAL;
574}
575
576int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name)
577{
578	struct intel_crtc *crtc = to_intel_crtc(_crtc);
579	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
580	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
581	enum intel_display_power_domain power_domain;
582	enum intel_pipe_crc_source source;
583	enum pipe pipe = crtc->pipe;
584	intel_wakeref_t wakeref;
585	u32 val = 0; /* shut up gcc */
586	int ret = 0;
587	bool enable;
588
589	if (display_crc_ctl_parse_source(source_name, &source) < 0) {
590		drm_dbg(&dev_priv->drm, "unknown source %s\n", source_name);
591		return -EINVAL;
592	}
593
594	power_domain = POWER_DOMAIN_PIPE(pipe);
595	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
596	if (!wakeref) {
597		drm_dbg_kms(&dev_priv->drm,
598			    "Trying to capture CRC while pipe is off\n");
599		return -EIO;
600	}
601
602	enable = source != INTEL_PIPE_CRC_SOURCE_NONE;
603	if (enable)
604		intel_crtc_crc_setup_workarounds(crtc, true);
605
606	ret = get_new_crc_ctl_reg(dev_priv, pipe, &source, &val);
607	if (ret != 0)
608		goto out;
609
610	pipe_crc->source = source;
611	intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
612	intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
613
614	if (!source) {
615		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
616			vlv_undo_pipe_scramble_reset(dev_priv, pipe);
617	}
618
619	pipe_crc->skipped = 0;
620
621out:
622	if (!enable)
623		intel_crtc_crc_setup_workarounds(crtc, false);
624
625	intel_display_power_put(dev_priv, power_domain, wakeref);
626
627	return ret;
628}
629
630void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc)
631{
632	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
633	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
634	enum pipe pipe = crtc->pipe;
635	u32 val = 0;
636
637	if (!crtc->base.crc.opened)
638		return;
639
640	if (get_new_crc_ctl_reg(dev_priv, pipe, &pipe_crc->source, &val) < 0)
641		return;
642
643	/* Don't need pipe_crc->lock here, IRQs are not generated. */
644	pipe_crc->skipped = 0;
645
646	intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
647	intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
648}
649
650void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
651{
652	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
653	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
654	enum pipe pipe = crtc->pipe;
655
656	/* Swallow crc's until we stop generating them. */
657	spin_lock_irq(&pipe_crc->lock);
658	pipe_crc->skipped = INT_MIN;
659	spin_unlock_irq(&pipe_crc->lock);
660
661	intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), 0);
662	intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
663	intel_synchronize_irq(dev_priv);
664}