cffd3043536daa3c67a1dd8d5cf7f3d25e3f7053
[openwrt/staging/linusw.git] /
1 From 9f4f8d9e78dc7fbffba47dea9beb8cadd60fbc8c Mon Sep 17 00:00:00 2001
2 From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
3 Date: Thu, 15 Jul 2021 01:08:11 +0200
4 Subject: [PATCH] drm/vc4: Make VEC progressive modes readily
5 accessible
6
7 Add predefined modelines for the 240p (NTSC) and 288p (PAL) progressive
8 modes, and report them through vc4_vec_connector_get_modes().
9
10 Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
11 ---
12 drivers/gpu/drm/vc4/vc4_vec.c | 73 ++++++++++++++++++++++++++---------
13 1 file changed, 55 insertions(+), 18 deletions(-)
14
15 --- a/drivers/gpu/drm/vc4/vc4_vec.c
16 +++ b/drivers/gpu/drm/vc4/vc4_vec.c
17 @@ -245,7 +245,8 @@ enum vc4_vec_tv_mode_id {
18 };
19
20 struct vc4_vec_tv_mode {
21 - const struct drm_display_mode *mode;
22 + const struct drm_display_mode *interlaced_mode;
23 + const struct drm_display_mode *progressive_mode;
24 u32 config0;
25 u32 config1;
26 u32 custom_freq;
27 @@ -279,61 +280,81 @@ static const struct debugfs_reg32 vec_re
28 };
29
30 static const struct drm_display_mode drm_mode_480i = {
31 - DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
32 + DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
33 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
34 480, 480 + 7, 480 + 7 + 6, 525, 0,
35 DRM_MODE_FLAG_INTERLACE)
36 };
37
38 +static const struct drm_display_mode drm_mode_240p = {
39 + DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500,
40 + 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
41 + 240, 240 + 3, 240 + 3 + 3, 262, 0, 0)
42 +};
43 +
44 static const struct drm_display_mode drm_mode_576i = {
45 - DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
46 + DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
47 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
48 576, 576 + 4, 576 + 4 + 6, 625, 0,
49 DRM_MODE_FLAG_INTERLACE)
50 };
51
52 +static const struct drm_display_mode drm_mode_288p = {
53 + DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500,
54 + 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
55 + 288, 288 + 2, 288 + 2 + 3, 312, 0, 0)
56 +};
57 +
58 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
59 [VC4_VEC_TV_MODE_NTSC] = {
60 - .mode = &drm_mode_480i,
61 + .interlaced_mode = &drm_mode_480i,
62 + .progressive_mode = &drm_mode_240p,
63 .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
64 .config1 = VEC_CONFIG1_C_CVBS_CVBS,
65 },
66 [VC4_VEC_TV_MODE_NTSC_J] = {
67 - .mode = &drm_mode_480i,
68 + .interlaced_mode = &drm_mode_480i,
69 + .progressive_mode = &drm_mode_240p,
70 .config0 = VEC_CONFIG0_NTSC_STD,
71 .config1 = VEC_CONFIG1_C_CVBS_CVBS,
72 },
73 [VC4_VEC_TV_MODE_NTSC_443] = {
74 /* NTSC with PAL chroma frequency */
75 - .mode = &drm_mode_480i,
76 + .interlaced_mode = &drm_mode_480i,
77 + .progressive_mode = &drm_mode_240p,
78 .config0 = VEC_CONFIG0_NTSC_STD,
79 .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
80 .custom_freq = 0x2a098acb,
81 },
82 [VC4_VEC_TV_MODE_PAL] = {
83 - .mode = &drm_mode_576i,
84 + .interlaced_mode = &drm_mode_576i,
85 + .progressive_mode = &drm_mode_288p,
86 .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
87 .config1 = VEC_CONFIG1_C_CVBS_CVBS,
88 },
89 [VC4_VEC_TV_MODE_PAL_M] = {
90 - .mode = &drm_mode_480i,
91 + .interlaced_mode = &drm_mode_480i,
92 + .progressive_mode = &drm_mode_240p,
93 .config0 = VEC_CONFIG0_PAL_M_STD,
94 .config1 = VEC_CONFIG1_C_CVBS_CVBS,
95 },
96 [VC4_VEC_TV_MODE_PAL_N] = {
97 - .mode = &drm_mode_576i,
98 + .interlaced_mode = &drm_mode_576i,
99 + .progressive_mode = &drm_mode_288p,
100 .config0 = VEC_CONFIG0_PAL_N_STD,
101 .config1 = VEC_CONFIG1_C_CVBS_CVBS,
102 },
103 [VC4_VEC_TV_MODE_PAL60] = {
104 /* PAL-M with chroma frequency of regular PAL */
105 - .mode = &drm_mode_480i,
106 + .interlaced_mode = &drm_mode_480i,
107 + .progressive_mode = &drm_mode_240p,
108 .config0 = VEC_CONFIG0_PAL_M_STD,
109 .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
110 .custom_freq = 0x2a098acb,
111 },
112 [VC4_VEC_TV_MODE_SECAM] = {
113 - .mode = &drm_mode_576i,
114 + .interlaced_mode = &drm_mode_576i,
115 + .progressive_mode = &drm_mode_288p,
116 .config0 = VEC_CONFIG0_SECAM_STD,
117 .config1 = VEC_CONFIG1_C_CVBS_CVBS,
118 .custom_freq = 0x29c71c72,
119 @@ -393,16 +414,32 @@ static void vc4_vec_connector_destroy(st
120 static int vc4_vec_connector_get_modes(struct drm_connector *connector)
121 {
122 struct drm_connector_state *state = connector->state;
123 - struct drm_display_mode *mode;
124 + struct drm_display_mode *interlaced_mode, *progressive_mode;
125
126 - mode = drm_mode_duplicate(connector->dev,
127 - vc4_vec_tv_modes[state->tv.mode].mode);
128 - if (!mode) {
129 + interlaced_mode =
130 + drm_mode_duplicate(connector->dev,
131 + vc4_vec_tv_modes[state->tv.mode].interlaced_mode);
132 + progressive_mode =
133 + drm_mode_duplicate(connector->dev,
134 + vc4_vec_tv_modes[state->tv.mode].progressive_mode);
135 + if (!interlaced_mode || !progressive_mode) {
136 DRM_ERROR("Failed to create a new display mode\n");
137 + drm_mode_destroy(connector->dev, interlaced_mode);
138 + drm_mode_destroy(connector->dev, progressive_mode);
139 return -ENOMEM;
140 }
141
142 - drm_mode_probed_add(connector, mode);
143 + if (connector->cmdline_mode.specified &&
144 + connector->cmdline_mode.refresh_specified &&
145 + !connector->cmdline_mode.interlace)
146 + /* progressive mode set at boot, let's make it preferred */
147 + progressive_mode->type |= DRM_MODE_TYPE_PREFERRED;
148 + else
149 + /* otherwise, interlaced mode is preferred */
150 + interlaced_mode->type |= DRM_MODE_TYPE_PREFERRED;
151 +
152 + drm_mode_probed_add(connector, interlaced_mode);
153 + drm_mode_probed_add(connector, progressive_mode);
154
155 return 1;
156 }
157 @@ -583,7 +620,7 @@ static int vc4_vec_encoder_atomic_check(
158 struct drm_connector_state *conn_state)
159 {
160 const struct drm_display_mode *reference_mode =
161 - vc4_vec_tv_modes[conn_state->tv.mode].mode;
162 + vc4_vec_tv_modes[conn_state->tv.mode].interlaced_mode;
163
164 if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
165 crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||