950-0555-drm-vc4-Relax-VEC-modeline-requirements-and-add-prog.patch 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. From ae200c4c1d2d0c9f827e7f73d00f00074e3a7a04 Mon Sep 17 00:00:00 2001
  2. From: Mateusz Kwiatkowski <[email protected]>
  3. Date: Thu, 15 Jul 2021 01:08:08 +0200
  4. Subject: [PATCH] drm/vc4: Relax VEC modeline requirements and add
  5. progressive mode support
  6. Make vc4_vec_encoder_atomic_check() accept arbitrary modelines, as long
  7. as they result in somewhat sane output from the VEC. The bounds have
  8. been determined empirically. Additionally, add support for the
  9. progressive 262-line and 312-line modes.
  10. Signed-off-by: Mateusz Kwiatkowski <[email protected]>
  11. ---
  12. drivers/gpu/drm/vc4/vc4_crtc.c | 1 +
  13. drivers/gpu/drm/vc4/vc4_vec.c | 97 ++++++++++++++++++++++++++++------
  14. 2 files changed, 83 insertions(+), 15 deletions(-)
  15. --- a/drivers/gpu/drm/vc4/vc4_crtc.c
  16. +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
  17. @@ -401,6 +401,7 @@ static void vc4_crtc_config_pv(struct dr
  18. CRTC_WRITE(PV_V_CONTROL,
  19. PV_VCONTROL_CONTINUOUS |
  20. (is_dsi ? PV_VCONTROL_DSI : 0));
  21. + CRTC_WRITE(PV_VSYNCD_EVEN, 0);
  22. }
  23. if (is_dsi)
  24. --- a/drivers/gpu/drm/vc4/vc4_vec.c
  25. +++ b/drivers/gpu/drm/vc4/vc4_vec.c
  26. @@ -423,18 +423,11 @@ static int vc4_vec_connector_atomic_chec
  27. struct drm_connector_state *new_state =
  28. drm_atomic_get_new_connector_state(state, conn);
  29. - const struct vc4_vec_tv_mode *vec_mode =
  30. - &vc4_vec_tv_modes[new_state->tv.mode];
  31. -
  32. - if (new_state->crtc) {
  33. + if (new_state->crtc && old_state->tv.mode != new_state->tv.mode) {
  34. struct drm_crtc_state *crtc_state =
  35. drm_atomic_get_new_crtc_state(state, new_state->crtc);
  36. - if (!drm_mode_equal(vec_mode->mode, &crtc_state->mode))
  37. - return -EINVAL;
  38. -
  39. - if (old_state->tv.mode != new_state->tv.mode)
  40. - crtc_state->mode_changed = true;
  41. + crtc_state->mode_changed = true;
  42. }
  43. return 0;
  44. @@ -559,7 +552,10 @@ static void vc4_vec_encoder_enable(struc
  45. VEC_WRITE(VEC_CLMP0_START, 0xac);
  46. VEC_WRITE(VEC_CLMP0_END, 0xec);
  47. VEC_WRITE(VEC_CONFIG2,
  48. - VEC_CONFIG2_UV_DIG_DIS | VEC_CONFIG2_RGB_DIG_DIS);
  49. + VEC_CONFIG2_UV_DIG_DIS |
  50. + VEC_CONFIG2_RGB_DIG_DIS |
  51. + ((encoder->crtc->state->adjusted_mode.flags &
  52. + DRM_MODE_FLAG_INTERLACE) ? 0 : VEC_CONFIG2_PROG_SCAN));
  53. VEC_WRITE(VEC_CONFIG3, VEC_CONFIG3_HORIZ_LEN_STD);
  54. VEC_WRITE(VEC_DAC_CONFIG, vec->variant->dac_config);
  55. @@ -582,17 +578,88 @@ static void vc4_vec_encoder_enable(struc
  56. }
  57. -static bool vc4_vec_encoder_mode_fixup(struct drm_encoder *encoder,
  58. - const struct drm_display_mode *mode,
  59. - struct drm_display_mode *adjusted_mode)
  60. +static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
  61. + struct drm_crtc_state *crtc_state,
  62. + struct drm_connector_state *conn_state)
  63. {
  64. - return true;
  65. + const struct drm_display_mode *reference_mode =
  66. + vc4_vec_tv_modes[conn_state->tv.mode].mode;
  67. +
  68. + if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
  69. + crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||
  70. + crtc_state->adjusted_mode.crtc_hdisplay % 4 != 0 ||
  71. + crtc_state->adjusted_mode.crtc_hsync_end -
  72. + crtc_state->adjusted_mode.crtc_hsync_start < 1)
  73. + return -EINVAL;
  74. +
  75. + switch (reference_mode->vtotal) {
  76. + case 525:
  77. + if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
  78. + crtc_state->adjusted_mode.crtc_vdisplay > 253 ||
  79. + crtc_state->adjusted_mode.crtc_vsync_start -
  80. + crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
  81. + crtc_state->adjusted_mode.crtc_vsync_end -
  82. + crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
  83. + crtc_state->adjusted_mode.crtc_vtotal -
  84. + crtc_state->adjusted_mode.crtc_vsync_end < 4 ||
  85. + crtc_state->adjusted_mode.crtc_vtotal > 262)
  86. + return -EINVAL;
  87. +
  88. + if ((crtc_state->adjusted_mode.flags &
  89. + DRM_MODE_FLAG_INTERLACE) &&
  90. + (crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
  91. + crtc_state->adjusted_mode.vsync_start % 2 != 1 ||
  92. + crtc_state->adjusted_mode.vsync_end % 2 != 1 ||
  93. + crtc_state->adjusted_mode.vtotal % 2 != 1))
  94. + return -EINVAL;
  95. +
  96. + /* progressive mode is hard-wired to 262 total lines */
  97. + if (!(crtc_state->adjusted_mode.flags &
  98. + DRM_MODE_FLAG_INTERLACE) &&
  99. + crtc_state->adjusted_mode.crtc_vtotal != 262)
  100. + return -EINVAL;
  101. +
  102. + break;
  103. +
  104. + case 625:
  105. + if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
  106. + crtc_state->adjusted_mode.crtc_vdisplay > 305 ||
  107. + crtc_state->adjusted_mode.crtc_vsync_start -
  108. + crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
  109. + crtc_state->adjusted_mode.crtc_vsync_end -
  110. + crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
  111. + crtc_state->adjusted_mode.crtc_vtotal -
  112. + crtc_state->adjusted_mode.crtc_vsync_end < 2 ||
  113. + crtc_state->adjusted_mode.crtc_vtotal > 312)
  114. + return -EINVAL;
  115. +
  116. + if ((crtc_state->adjusted_mode.flags &
  117. + DRM_MODE_FLAG_INTERLACE) &&
  118. + (crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
  119. + crtc_state->adjusted_mode.vsync_start % 2 != 0 ||
  120. + crtc_state->adjusted_mode.vsync_end % 2 != 0 ||
  121. + crtc_state->adjusted_mode.vtotal % 2 != 1))
  122. + return -EINVAL;
  123. +
  124. + /* progressive mode is hard-wired to 312 total lines */
  125. + if (!(crtc_state->adjusted_mode.flags &
  126. + DRM_MODE_FLAG_INTERLACE) &&
  127. + crtc_state->adjusted_mode.crtc_vtotal != 312)
  128. + return -EINVAL;
  129. +
  130. + break;
  131. +
  132. + default:
  133. + return -EINVAL;
  134. + }
  135. +
  136. + return 0;
  137. }
  138. static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
  139. .disable = vc4_vec_encoder_disable,
  140. .enable = vc4_vec_encoder_enable,
  141. - .mode_fixup = vc4_vec_encoder_mode_fixup,
  142. + .atomic_check = vc4_vec_encoder_atomic_check,
  143. };
  144. static const struct vc4_vec_variant bcm2835_vec_variant = {