0523-drm-vc4-Add-support-for-double-clocked-modes.patch 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. From 184580ac95b7fa05eaf5ee16393ddd6103493d0a Mon Sep 17 00:00:00 2001
  2. From: Eric Anholt <eric@anholt.net>
  3. Date: Wed, 28 Sep 2016 19:01:48 -0700
  4. Subject: [PATCH] drm/vc4: Add support for double-clocked modes.
  5. Now that we have infoframes to report the pixel repeat flag, we can
  6. start using it. Fixes locking the 720x480i and 720x576i modes on my
  7. Dell 2408WFP. Like the 1920x1080i case, they don't fit properly on
  8. the screen, though.
  9. Signed-off-by: Eric Anholt <eric@anholt.net>
  10. ---
  11. drivers/gpu/drm/vc4/vc4_crtc.c | 17 +++++++++++------
  12. drivers/gpu/drm/vc4/vc4_hdmi.c | 16 +++++++++++-----
  13. drivers/gpu/drm/vc4/vc4_regs.h | 2 ++
  14. 3 files changed, 24 insertions(+), 11 deletions(-)
  15. --- a/drivers/gpu/drm/vc4/vc4_crtc.c
  16. +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
  17. @@ -371,6 +371,7 @@ static void vc4_crtc_mode_set_nofb(struc
  18. bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
  19. vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
  20. u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
  21. + u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
  22. bool debug_dump_regs = false;
  23. if (debug_dump_regs) {
  24. @@ -384,14 +385,17 @@ static void vc4_crtc_mode_set_nofb(struc
  25. CRTC_WRITE(PV_CONTROL, 0);
  26. CRTC_WRITE(PV_HORZA,
  27. - VC4_SET_FIELD(mode->htotal - mode->hsync_end,
  28. + VC4_SET_FIELD((mode->htotal -
  29. + mode->hsync_end) * pixel_rep,
  30. PV_HORZA_HBP) |
  31. - VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
  32. + VC4_SET_FIELD((mode->hsync_end -
  33. + mode->hsync_start) * pixel_rep,
  34. PV_HORZA_HSYNC));
  35. CRTC_WRITE(PV_HORZB,
  36. - VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
  37. + VC4_SET_FIELD((mode->hsync_start -
  38. + mode->hdisplay) * pixel_rep,
  39. PV_HORZB_HFP) |
  40. - VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
  41. + VC4_SET_FIELD(mode->hdisplay * pixel_rep, PV_HORZB_HACTIVE));
  42. CRTC_WRITE(PV_VERTA,
  43. VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
  44. @@ -426,7 +430,7 @@ static void vc4_crtc_mode_set_nofb(struc
  45. PV_VCONTROL_CONTINUOUS |
  46. (is_dsi ? PV_VCONTROL_DSI : 0) |
  47. PV_VCONTROL_INTERLACE |
  48. - VC4_SET_FIELD(mode->htotal / 2,
  49. + VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
  50. PV_VCONTROL_ODD_DELAY));
  51. CRTC_WRITE(PV_VSYNCD_EVEN, 0);
  52. } else {
  53. @@ -435,12 +439,13 @@ static void vc4_crtc_mode_set_nofb(struc
  54. (is_dsi ? PV_VCONTROL_DSI : 0));
  55. }
  56. - CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
  57. + CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
  58. CRTC_WRITE(PV_CONTROL,
  59. VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
  60. VC4_SET_FIELD(vc4_get_fifo_full_level(format),
  61. PV_CONTROL_FIFO_LEVEL) |
  62. + VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
  63. PV_CONTROL_CLR_AT_START |
  64. PV_CONTROL_TRIGGER_UNDERFLOW |
  65. PV_CONTROL_WAIT_HSTART |
  66. --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
  67. +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
  68. @@ -411,6 +411,7 @@ static void vc4_hdmi_encoder_mode_set(st
  69. bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
  70. bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
  71. bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
  72. + u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
  73. u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
  74. VC4_HDMI_VERTA_VSP) |
  75. VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
  76. @@ -433,7 +434,8 @@ static void vc4_hdmi_encoder_mode_set(st
  77. HD_WRITE(VC4_HD_VID_CTL, 0);
  78. - clk_set_rate(vc4->hdmi->pixel_clock, mode->clock * 1000);
  79. + clk_set_rate(vc4->hdmi->pixel_clock, mode->clock * 1000 *
  80. + ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
  81. HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
  82. HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
  83. @@ -443,14 +445,18 @@ static void vc4_hdmi_encoder_mode_set(st
  84. HDMI_WRITE(VC4_HDMI_HORZA,
  85. (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
  86. (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
  87. - VC4_SET_FIELD(mode->hdisplay, VC4_HDMI_HORZA_HAP));
  88. + VC4_SET_FIELD(mode->hdisplay * pixel_rep,
  89. + VC4_HDMI_HORZA_HAP));
  90. HDMI_WRITE(VC4_HDMI_HORZB,
  91. - VC4_SET_FIELD(mode->htotal - mode->hsync_end,
  92. + VC4_SET_FIELD((mode->htotal -
  93. + mode->hsync_end) * pixel_rep,
  94. VC4_HDMI_HORZB_HBP) |
  95. - VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
  96. + VC4_SET_FIELD((mode->hsync_end -
  97. + mode->hsync_start) * pixel_rep,
  98. VC4_HDMI_HORZB_HSP) |
  99. - VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
  100. + VC4_SET_FIELD((mode->hsync_start -
  101. + mode->hdisplay) * pixel_rep,
  102. VC4_HDMI_HORZB_HFP));
  103. HDMI_WRITE(VC4_HDMI_VERTA0, verta);
  104. --- a/drivers/gpu/drm/vc4/vc4_regs.h
  105. +++ b/drivers/gpu/drm/vc4/vc4_regs.h
  106. @@ -175,6 +175,8 @@
  107. # define PV_CONTROL_CLR_AT_START BIT(14)
  108. # define PV_CONTROL_TRIGGER_UNDERFLOW BIT(13)
  109. # define PV_CONTROL_WAIT_HSTART BIT(12)
  110. +# define PV_CONTROL_PIXEL_REP_MASK VC4_MASK(5, 4)
  111. +# define PV_CONTROL_PIXEL_REP_SHIFT 4
  112. # define PV_CONTROL_CLK_SELECT_DSI_VEC 0
  113. # define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI 1
  114. # define PV_CONTROL_CLK_SELECT_MASK VC4_MASK(3, 2)