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