intel_pipe_crc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  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. #include <linux/seq_file.h>
  27. #include <linux/circ_buf.h>
  28. #include <linux/ctype.h>
  29. #include <linux/debugfs.h>
  30. #include "intel_drv.h"
  31. static const char * const pipe_crc_sources[] = {
  32. "none",
  33. "plane1",
  34. "plane2",
  35. "pf",
  36. "pipe",
  37. "TV",
  38. "DP-B",
  39. "DP-C",
  40. "DP-D",
  41. "auto",
  42. };
  43. static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
  44. uint32_t *val)
  45. {
  46. if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
  47. *source = INTEL_PIPE_CRC_SOURCE_PIPE;
  48. switch (*source) {
  49. case INTEL_PIPE_CRC_SOURCE_PIPE:
  50. *val = PIPE_CRC_ENABLE | PIPE_CRC_INCLUDE_BORDER_I8XX;
  51. break;
  52. case INTEL_PIPE_CRC_SOURCE_NONE:
  53. *val = 0;
  54. break;
  55. default:
  56. return -EINVAL;
  57. }
  58. return 0;
  59. }
  60. static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
  61. enum pipe pipe,
  62. enum intel_pipe_crc_source *source)
  63. {
  64. struct drm_device *dev = &dev_priv->drm;
  65. struct intel_encoder *encoder;
  66. struct intel_crtc *crtc;
  67. struct intel_digital_port *dig_port;
  68. int ret = 0;
  69. *source = INTEL_PIPE_CRC_SOURCE_PIPE;
  70. drm_modeset_lock_all(dev);
  71. for_each_intel_encoder(dev, encoder) {
  72. if (!encoder->base.crtc)
  73. continue;
  74. crtc = to_intel_crtc(encoder->base.crtc);
  75. if (crtc->pipe != pipe)
  76. continue;
  77. switch (encoder->type) {
  78. case INTEL_OUTPUT_TVOUT:
  79. *source = INTEL_PIPE_CRC_SOURCE_TV;
  80. break;
  81. case INTEL_OUTPUT_DP:
  82. case INTEL_OUTPUT_EDP:
  83. dig_port = enc_to_dig_port(&encoder->base);
  84. switch (dig_port->base.port) {
  85. case PORT_B:
  86. *source = INTEL_PIPE_CRC_SOURCE_DP_B;
  87. break;
  88. case PORT_C:
  89. *source = INTEL_PIPE_CRC_SOURCE_DP_C;
  90. break;
  91. case PORT_D:
  92. *source = INTEL_PIPE_CRC_SOURCE_DP_D;
  93. break;
  94. default:
  95. WARN(1, "nonexisting DP port %c\n",
  96. port_name(dig_port->base.port));
  97. break;
  98. }
  99. break;
  100. default:
  101. break;
  102. }
  103. }
  104. drm_modeset_unlock_all(dev);
  105. return ret;
  106. }
  107. static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
  108. enum pipe pipe,
  109. enum intel_pipe_crc_source *source,
  110. uint32_t *val)
  111. {
  112. bool need_stable_symbols = false;
  113. if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) {
  114. int ret = i9xx_pipe_crc_auto_source(dev_priv, pipe, source);
  115. if (ret)
  116. return ret;
  117. }
  118. switch (*source) {
  119. case INTEL_PIPE_CRC_SOURCE_PIPE:
  120. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_VLV;
  121. break;
  122. case INTEL_PIPE_CRC_SOURCE_DP_B:
  123. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_VLV;
  124. need_stable_symbols = true;
  125. break;
  126. case INTEL_PIPE_CRC_SOURCE_DP_C:
  127. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV;
  128. need_stable_symbols = true;
  129. break;
  130. case INTEL_PIPE_CRC_SOURCE_DP_D:
  131. if (!IS_CHERRYVIEW(dev_priv))
  132. return -EINVAL;
  133. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_VLV;
  134. need_stable_symbols = true;
  135. break;
  136. case INTEL_PIPE_CRC_SOURCE_NONE:
  137. *val = 0;
  138. break;
  139. default:
  140. return -EINVAL;
  141. }
  142. /*
  143. * When the pipe CRC tap point is after the transcoders we need
  144. * to tweak symbol-level features to produce a deterministic series of
  145. * symbols for a given frame. We need to reset those features only once
  146. * a frame (instead of every nth symbol):
  147. * - DC-balance: used to ensure a better clock recovery from the data
  148. * link (SDVO)
  149. * - DisplayPort scrambling: used for EMI reduction
  150. */
  151. if (need_stable_symbols) {
  152. uint32_t tmp = I915_READ(PORT_DFT2_G4X);
  153. tmp |= DC_BALANCE_RESET_VLV;
  154. switch (pipe) {
  155. case PIPE_A:
  156. tmp |= PIPE_A_SCRAMBLE_RESET;
  157. break;
  158. case PIPE_B:
  159. tmp |= PIPE_B_SCRAMBLE_RESET;
  160. break;
  161. case PIPE_C:
  162. tmp |= PIPE_C_SCRAMBLE_RESET;
  163. break;
  164. default:
  165. return -EINVAL;
  166. }
  167. I915_WRITE(PORT_DFT2_G4X, tmp);
  168. }
  169. return 0;
  170. }
  171. static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
  172. enum pipe pipe,
  173. enum intel_pipe_crc_source *source,
  174. uint32_t *val)
  175. {
  176. bool need_stable_symbols = false;
  177. if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) {
  178. int ret = i9xx_pipe_crc_auto_source(dev_priv, pipe, source);
  179. if (ret)
  180. return ret;
  181. }
  182. switch (*source) {
  183. case INTEL_PIPE_CRC_SOURCE_PIPE:
  184. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_I9XX;
  185. break;
  186. case INTEL_PIPE_CRC_SOURCE_TV:
  187. if (!SUPPORTS_TV(dev_priv))
  188. return -EINVAL;
  189. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_TV_PRE;
  190. break;
  191. case INTEL_PIPE_CRC_SOURCE_DP_B:
  192. if (!IS_G4X(dev_priv))
  193. return -EINVAL;
  194. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_G4X;
  195. need_stable_symbols = true;
  196. break;
  197. case INTEL_PIPE_CRC_SOURCE_DP_C:
  198. if (!IS_G4X(dev_priv))
  199. return -EINVAL;
  200. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_G4X;
  201. need_stable_symbols = true;
  202. break;
  203. case INTEL_PIPE_CRC_SOURCE_DP_D:
  204. if (!IS_G4X(dev_priv))
  205. return -EINVAL;
  206. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_G4X;
  207. need_stable_symbols = true;
  208. break;
  209. case INTEL_PIPE_CRC_SOURCE_NONE:
  210. *val = 0;
  211. break;
  212. default:
  213. return -EINVAL;
  214. }
  215. /*
  216. * When the pipe CRC tap point is after the transcoders we need
  217. * to tweak symbol-level features to produce a deterministic series of
  218. * symbols for a given frame. We need to reset those features only once
  219. * a frame (instead of every nth symbol):
  220. * - DC-balance: used to ensure a better clock recovery from the data
  221. * link (SDVO)
  222. * - DisplayPort scrambling: used for EMI reduction
  223. */
  224. if (need_stable_symbols) {
  225. uint32_t tmp = I915_READ(PORT_DFT2_G4X);
  226. WARN_ON(!IS_G4X(dev_priv));
  227. I915_WRITE(PORT_DFT_I9XX,
  228. I915_READ(PORT_DFT_I9XX) | DC_BALANCE_RESET);
  229. if (pipe == PIPE_A)
  230. tmp |= PIPE_A_SCRAMBLE_RESET;
  231. else
  232. tmp |= PIPE_B_SCRAMBLE_RESET;
  233. I915_WRITE(PORT_DFT2_G4X, tmp);
  234. }
  235. return 0;
  236. }
  237. static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv,
  238. enum pipe pipe)
  239. {
  240. uint32_t tmp = I915_READ(PORT_DFT2_G4X);
  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);
  257. }
  258. static void g4x_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv,
  259. enum pipe pipe)
  260. {
  261. uint32_t tmp = I915_READ(PORT_DFT2_G4X);
  262. if (pipe == PIPE_A)
  263. tmp &= ~PIPE_A_SCRAMBLE_RESET;
  264. else
  265. tmp &= ~PIPE_B_SCRAMBLE_RESET;
  266. I915_WRITE(PORT_DFT2_G4X, tmp);
  267. if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) {
  268. I915_WRITE(PORT_DFT_I9XX,
  269. I915_READ(PORT_DFT_I9XX) & ~DC_BALANCE_RESET);
  270. }
  271. }
  272. static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
  273. uint32_t *val)
  274. {
  275. if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
  276. *source = INTEL_PIPE_CRC_SOURCE_PIPE;
  277. switch (*source) {
  278. case INTEL_PIPE_CRC_SOURCE_PLANE1:
  279. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_ILK;
  280. break;
  281. case INTEL_PIPE_CRC_SOURCE_PLANE2:
  282. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_ILK;
  283. break;
  284. case INTEL_PIPE_CRC_SOURCE_PIPE:
  285. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_ILK;
  286. break;
  287. case INTEL_PIPE_CRC_SOURCE_NONE:
  288. *val = 0;
  289. break;
  290. default:
  291. return -EINVAL;
  292. }
  293. return 0;
  294. }
  295. static void hsw_pipe_A_crc_wa(struct drm_i915_private *dev_priv,
  296. bool enable)
  297. {
  298. struct drm_device *dev = &dev_priv->drm;
  299. struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_A);
  300. struct intel_crtc_state *pipe_config;
  301. struct drm_atomic_state *state;
  302. struct drm_modeset_acquire_ctx ctx;
  303. int ret = 0;
  304. drm_modeset_acquire_init(&ctx, 0);
  305. state = drm_atomic_state_alloc(dev);
  306. if (!state) {
  307. ret = -ENOMEM;
  308. goto unlock;
  309. }
  310. state->acquire_ctx = &ctx;
  311. retry:
  312. pipe_config = intel_atomic_get_crtc_state(state, crtc);
  313. if (IS_ERR(pipe_config)) {
  314. ret = PTR_ERR(pipe_config);
  315. goto put_state;
  316. }
  317. if (HAS_IPS(dev_priv)) {
  318. /*
  319. * When IPS gets enabled, the pipe CRC changes. Since IPS gets
  320. * enabled and disabled dynamically based on package C states,
  321. * user space can't make reliable use of the CRCs, so let's just
  322. * completely disable it.
  323. */
  324. pipe_config->ips_force_disable = enable;
  325. }
  326. if (IS_HASWELL(dev_priv)) {
  327. pipe_config->pch_pfit.force_thru = enable;
  328. if (pipe_config->cpu_transcoder == TRANSCODER_EDP &&
  329. pipe_config->pch_pfit.enabled != enable)
  330. pipe_config->base.connectors_changed = true;
  331. }
  332. ret = drm_atomic_commit(state);
  333. put_state:
  334. if (ret == -EDEADLK) {
  335. drm_atomic_state_clear(state);
  336. drm_modeset_backoff(&ctx);
  337. goto retry;
  338. }
  339. drm_atomic_state_put(state);
  340. unlock:
  341. WARN(ret, "Toggling workaround to %i returns %i\n", enable, ret);
  342. drm_modeset_drop_locks(&ctx);
  343. drm_modeset_acquire_fini(&ctx);
  344. }
  345. static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv,
  346. enum pipe pipe,
  347. enum intel_pipe_crc_source *source,
  348. uint32_t *val,
  349. bool set_wa)
  350. {
  351. if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
  352. *source = INTEL_PIPE_CRC_SOURCE_PF;
  353. switch (*source) {
  354. case INTEL_PIPE_CRC_SOURCE_PLANE1:
  355. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_IVB;
  356. break;
  357. case INTEL_PIPE_CRC_SOURCE_PLANE2:
  358. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB;
  359. break;
  360. case INTEL_PIPE_CRC_SOURCE_PF:
  361. if (set_wa && (IS_HASWELL(dev_priv) ||
  362. IS_BROADWELL(dev_priv)) && pipe == PIPE_A)
  363. hsw_pipe_A_crc_wa(dev_priv, true);
  364. *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB;
  365. break;
  366. case INTEL_PIPE_CRC_SOURCE_NONE:
  367. *val = 0;
  368. break;
  369. default:
  370. return -EINVAL;
  371. }
  372. return 0;
  373. }
  374. static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv,
  375. enum pipe pipe,
  376. enum intel_pipe_crc_source *source, u32 *val,
  377. bool set_wa)
  378. {
  379. if (IS_GEN2(dev_priv))
  380. return i8xx_pipe_crc_ctl_reg(source, val);
  381. else if (INTEL_GEN(dev_priv) < 5)
  382. return i9xx_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
  383. else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
  384. return vlv_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
  385. else if (IS_GEN5(dev_priv) || IS_GEN6(dev_priv))
  386. return ilk_pipe_crc_ctl_reg(source, val);
  387. else
  388. return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val, set_wa);
  389. }
  390. static int
  391. display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s)
  392. {
  393. int i;
  394. if (!buf) {
  395. *s = INTEL_PIPE_CRC_SOURCE_NONE;
  396. return 0;
  397. }
  398. i = match_string(pipe_crc_sources, ARRAY_SIZE(pipe_crc_sources), buf);
  399. if (i < 0)
  400. return i;
  401. *s = i;
  402. return 0;
  403. }
  404. void intel_display_crc_init(struct drm_i915_private *dev_priv)
  405. {
  406. enum pipe pipe;
  407. for_each_pipe(dev_priv, pipe) {
  408. struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
  409. spin_lock_init(&pipe_crc->lock);
  410. }
  411. }
  412. static int i8xx_crc_source_valid(struct drm_i915_private *dev_priv,
  413. const enum intel_pipe_crc_source source)
  414. {
  415. switch (source) {
  416. case INTEL_PIPE_CRC_SOURCE_PIPE:
  417. case INTEL_PIPE_CRC_SOURCE_NONE:
  418. return 0;
  419. default:
  420. return -EINVAL;
  421. }
  422. }
  423. static int i9xx_crc_source_valid(struct drm_i915_private *dev_priv,
  424. const enum intel_pipe_crc_source source)
  425. {
  426. switch (source) {
  427. case INTEL_PIPE_CRC_SOURCE_PIPE:
  428. case INTEL_PIPE_CRC_SOURCE_TV:
  429. case INTEL_PIPE_CRC_SOURCE_DP_B:
  430. case INTEL_PIPE_CRC_SOURCE_DP_C:
  431. case INTEL_PIPE_CRC_SOURCE_DP_D:
  432. case INTEL_PIPE_CRC_SOURCE_NONE:
  433. return 0;
  434. default:
  435. return -EINVAL;
  436. }
  437. }
  438. static int vlv_crc_source_valid(struct drm_i915_private *dev_priv,
  439. const enum intel_pipe_crc_source source)
  440. {
  441. switch (source) {
  442. case INTEL_PIPE_CRC_SOURCE_PIPE:
  443. case INTEL_PIPE_CRC_SOURCE_DP_B:
  444. case INTEL_PIPE_CRC_SOURCE_DP_C:
  445. case INTEL_PIPE_CRC_SOURCE_DP_D:
  446. case INTEL_PIPE_CRC_SOURCE_NONE:
  447. return 0;
  448. default:
  449. return -EINVAL;
  450. }
  451. }
  452. static int ilk_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_PLANE1:
  458. case INTEL_PIPE_CRC_SOURCE_PLANE2:
  459. case INTEL_PIPE_CRC_SOURCE_NONE:
  460. return 0;
  461. default:
  462. return -EINVAL;
  463. }
  464. }
  465. static int ivb_crc_source_valid(struct drm_i915_private *dev_priv,
  466. const enum intel_pipe_crc_source source)
  467. {
  468. switch (source) {
  469. case INTEL_PIPE_CRC_SOURCE_PIPE:
  470. case INTEL_PIPE_CRC_SOURCE_PLANE1:
  471. case INTEL_PIPE_CRC_SOURCE_PLANE2:
  472. case INTEL_PIPE_CRC_SOURCE_PF:
  473. case INTEL_PIPE_CRC_SOURCE_NONE:
  474. return 0;
  475. default:
  476. return -EINVAL;
  477. }
  478. }
  479. static int
  480. intel_is_valid_crc_source(struct drm_i915_private *dev_priv,
  481. const enum intel_pipe_crc_source source)
  482. {
  483. if (IS_GEN2(dev_priv))
  484. return i8xx_crc_source_valid(dev_priv, source);
  485. else if (INTEL_GEN(dev_priv) < 5)
  486. return i9xx_crc_source_valid(dev_priv, source);
  487. else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
  488. return vlv_crc_source_valid(dev_priv, source);
  489. else if (IS_GEN5(dev_priv) || IS_GEN6(dev_priv))
  490. return ilk_crc_source_valid(dev_priv, source);
  491. else
  492. return ivb_crc_source_valid(dev_priv, source);
  493. }
  494. const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc,
  495. size_t *count)
  496. {
  497. *count = ARRAY_SIZE(pipe_crc_sources);
  498. return pipe_crc_sources;
  499. }
  500. int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
  501. size_t *values_cnt)
  502. {
  503. struct drm_i915_private *dev_priv = to_i915(crtc->dev);
  504. enum intel_pipe_crc_source source;
  505. if (display_crc_ctl_parse_source(source_name, &source) < 0) {
  506. DRM_DEBUG_DRIVER("unknown source %s\n", source_name);
  507. return -EINVAL;
  508. }
  509. if (source == INTEL_PIPE_CRC_SOURCE_AUTO ||
  510. intel_is_valid_crc_source(dev_priv, source) == 0) {
  511. *values_cnt = 5;
  512. return 0;
  513. }
  514. return -EINVAL;
  515. }
  516. int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name)
  517. {
  518. struct drm_i915_private *dev_priv = to_i915(crtc->dev);
  519. struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index];
  520. enum intel_display_power_domain power_domain;
  521. enum intel_pipe_crc_source source;
  522. u32 val = 0; /* shut up gcc */
  523. int ret = 0;
  524. if (display_crc_ctl_parse_source(source_name, &source) < 0) {
  525. DRM_DEBUG_DRIVER("unknown source %s\n", source_name);
  526. return -EINVAL;
  527. }
  528. power_domain = POWER_DOMAIN_PIPE(crtc->index);
  529. if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) {
  530. DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n");
  531. return -EIO;
  532. }
  533. ret = get_new_crc_ctl_reg(dev_priv, crtc->index, &source, &val, true);
  534. if (ret != 0)
  535. goto out;
  536. pipe_crc->source = source;
  537. I915_WRITE(PIPE_CRC_CTL(crtc->index), val);
  538. POSTING_READ(PIPE_CRC_CTL(crtc->index));
  539. if (!source) {
  540. if (IS_G4X(dev_priv))
  541. g4x_undo_pipe_scramble_reset(dev_priv, crtc->index);
  542. else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
  543. vlv_undo_pipe_scramble_reset(dev_priv, crtc->index);
  544. else if ((IS_HASWELL(dev_priv) ||
  545. IS_BROADWELL(dev_priv)) && crtc->index == PIPE_A)
  546. hsw_pipe_A_crc_wa(dev_priv, false);
  547. }
  548. pipe_crc->skipped = 0;
  549. out:
  550. intel_display_power_put(dev_priv, power_domain);
  551. return ret;
  552. }
  553. void intel_crtc_enable_pipe_crc(struct intel_crtc *intel_crtc)
  554. {
  555. struct drm_crtc *crtc = &intel_crtc->base;
  556. struct drm_i915_private *dev_priv = to_i915(crtc->dev);
  557. struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index];
  558. u32 val = 0;
  559. if (!crtc->crc.opened)
  560. return;
  561. if (get_new_crc_ctl_reg(dev_priv, crtc->index, &pipe_crc->source, &val, false) < 0)
  562. return;
  563. /* Don't need pipe_crc->lock here, IRQs are not generated. */
  564. pipe_crc->skipped = 0;
  565. I915_WRITE(PIPE_CRC_CTL(crtc->index), val);
  566. POSTING_READ(PIPE_CRC_CTL(crtc->index));
  567. }
  568. void intel_crtc_disable_pipe_crc(struct intel_crtc *intel_crtc)
  569. {
  570. struct drm_crtc *crtc = &intel_crtc->base;
  571. struct drm_i915_private *dev_priv = to_i915(crtc->dev);
  572. struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index];
  573. /* Swallow crc's until we stop generating them. */
  574. spin_lock_irq(&pipe_crc->lock);
  575. pipe_crc->skipped = INT_MIN;
  576. spin_unlock_irq(&pipe_crc->lock);
  577. I915_WRITE(PIPE_CRC_CTL(crtc->index), 0);
  578. POSTING_READ(PIPE_CRC_CTL(crtc->index));
  579. synchronize_irq(dev_priv->drm.irq);
  580. }