db83c12f59e772f11858fb57ecb2620bc9ab2953
[oweals/openwrt.git] /
1 From 9536044338d9c341e805e288a58090c49a793638 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Tue, 9 Apr 2019 18:23:41 +0100
4 Subject: [PATCH] drm: vc4: FKMS reads the EDID from fw, and supports
5  mode setting
6
7 This extends FKMS to read the EDID from the display, and support
8 requesting a particular mode via KMS.
9
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
11 ---
12  drivers/gpu/drm/vc4/vc4_firmware_kms.c     | 334 ++++++++++++++++++---
13  include/soc/bcm2835/raspberrypi-firmware.h |   2 +
14  2 files changed, 302 insertions(+), 34 deletions(-)
15
16 --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
17 +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
18 @@ -88,11 +88,60 @@ struct mailbox_blank_display {
19         u32 blank;
20  };
21  
22 -struct mailbox_get_width_height {
23 +struct mailbox_get_edid {
24         struct rpi_firmware_property_tag_header tag1;
25 -       u32 display;
26 -       struct rpi_firmware_property_tag_header tag2;
27 -       u32 wh[2];
28 +       u32 block;
29 +       u32 display_number;
30 +       u8 edid[128];
31 +};
32 +
33 +struct set_timings {
34 +       u8 display;
35 +       u8 padding;
36 +       u16 video_id_code;
37 +
38 +       u32 clock;              /* in kHz */
39 +
40 +       u16 hdisplay;
41 +       u16 hsync_start;
42 +
43 +       u16 hsync_end;
44 +       u16 htotal;
45 +
46 +       u16 hskew;
47 +       u16 vdisplay;
48 +
49 +       u16 vsync_start;
50 +       u16 vsync_end;
51 +
52 +       u16 vtotal;
53 +       u16 vscan;
54 +
55 +       u16 vrefresh;
56 +       u16 padding2;
57 +
58 +       u32 flags;
59 +#define  TIMINGS_FLAGS_H_SYNC_POS      BIT(0)
60 +#define  TIMINGS_FLAGS_H_SYNC_NEG      0
61 +#define  TIMINGS_FLAGS_V_SYNC_POS      BIT(1)
62 +#define  TIMINGS_FLAGS_V_SYNC_NEG      0
63 +
64 +#define TIMINGS_FLAGS_ASPECT_MASK      GENMASK(7, 4)
65 +#define TIMINGS_FLAGS_ASPECT_NONE      (0 << 4)
66 +#define TIMINGS_FLAGS_ASPECT_4_3       (1 << 4)
67 +#define TIMINGS_FLAGS_ASPECT_16_9      (2 << 4)
68 +#define TIMINGS_FLAGS_ASPECT_64_27     (3 << 4)
69 +#define TIMINGS_FLAGS_ASPECT_256_135   (4 << 4)
70 +
71 +/* Limited range RGB flag. Not set corresponds to full range. */
72 +#define TIMINGS_FLAGS_RGB_LIMITED      BIT(8)
73 +/* DVI monitor, therefore disable infoframes. Not set corresponds to HDMI. */
74 +#define TIMINGS_FLAGS_DVI              BIT(9)
75 +};
76 +
77 +struct mailbox_set_mode {
78 +       struct rpi_firmware_property_tag_header tag1;
79 +       struct set_timings timings;
80  };
81  
82  static const struct vc_image_format {
83 @@ -186,6 +235,7 @@ struct vc4_crtc {
84         u32 overscan[4];
85         bool vblank_enabled;
86         u32 display_number;
87 +       u32 display_type;
88  };
89  
90  static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc)
91 @@ -195,6 +245,8 @@ static inline struct vc4_crtc *to_vc4_cr
92  
93  struct vc4_fkms_encoder {
94         struct drm_encoder base;
95 +       bool hdmi_monitor;
96 +       bool rgb_range_selectable;
97  };
98  
99  static inline struct vc4_fkms_encoder *
100 @@ -212,7 +264,9 @@ struct vc4_fkms_connector {
101          * hook.
102          */
103         struct drm_encoder *encoder;
104 -       u32 display_idx;
105 +       struct vc4_dev *vc4_dev;
106 +       u32 display_number;
107 +       u32 display_type;
108  };
109  
110  static inline struct vc4_fkms_connector *
111 @@ -221,6 +275,26 @@ to_vc4_fkms_connector(struct drm_connect
112         return container_of(connector, struct vc4_fkms_connector, base);
113  }
114  
115 +static u32 vc4_get_display_type(u32 display_number)
116 +{
117 +       const u32 display_types[] = {
118 +               /* The firmware display (DispmanX) IDs map to specific types in
119 +                * a fixed manner.
120 +                */
121 +               DRM_MODE_ENCODER_DSI,   /* MAIN_LCD */
122 +               DRM_MODE_ENCODER_DSI,   /* AUX_LCD */
123 +               DRM_MODE_ENCODER_TMDS,  /* HDMI0 */
124 +               DRM_MODE_ENCODER_TVDAC, /* VEC */
125 +               DRM_MODE_ENCODER_NONE,  /* FORCE_LCD */
126 +               DRM_MODE_ENCODER_NONE,  /* FORCE_TV */
127 +               DRM_MODE_ENCODER_NONE,  /* FORCE_OTHER */
128 +               DRM_MODE_ENCODER_TMDS,  /* HDMI1 */
129 +               DRM_MODE_ENCODER_NONE,  /* FORCE_TV2 */
130 +       };
131 +       return display_number > ARRAY_SIZE(display_types) - 1 ?
132 +                       DRM_MODE_ENCODER_NONE : display_types[display_number];
133 +}
134 +
135  /* Firmware's structure for making an FB mbox call. */
136  struct fbinfo_s {
137         u32 xres, yres, xres_virtual, yres_virtual;
138 @@ -255,10 +329,15 @@ static int vc4_plane_set_blank(struct dr
139                         .plane_id = vc4_plane->mb.plane.plane_id,
140                 }
141         };
142 +       static const char * const plane_types[] = {
143 +                                                       "overlay",
144 +                                                       "primary",
145 +                                                       "cursor"
146 +                                                 };
147         int ret;
148  
149 -       DRM_DEBUG_ATOMIC("[PLANE:%d:%s] overlay plane %s",
150 -                        plane->base.id, plane->name,
151 +       DRM_DEBUG_ATOMIC("[PLANE:%d:%s] %s plane %s",
152 +                        plane->base.id, plane->name, plane_types[plane->type],
153                          blank ? "blank" : "unblank");
154  
155         if (blank)
156 @@ -593,13 +672,102 @@ fail:
157  
158  static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
159  {
160 -       /* Everyting is handled in the planes. */
161 +       struct drm_device *dev = crtc->dev;
162 +       struct vc4_dev *vc4 = to_vc4_dev(dev);
163 +       struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
164 +       struct drm_display_mode *mode = &crtc->state->adjusted_mode;
165 +       struct vc4_fkms_encoder *vc4_encoder =
166 +                                       to_vc4_fkms_encoder(vc4_crtc->encoder);
167 +       struct mailbox_set_mode mb = {
168 +               .tag1 = { RPI_FIRMWARE_SET_TIMING,
169 +                         sizeof(struct set_timings), 0},
170 +       };
171 +       union hdmi_infoframe frame;
172 +       int ret;
173 +
174 +       ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
175 +       if (ret < 0) {
176 +               DRM_ERROR("couldn't fill AVI infoframe\n");
177 +               return;
178 +       }
179 +
180 +       DRM_DEBUG_KMS("Setting mode for display num %u mode name %s, clk %d, h(disp %d, start %d, end %d, total %d, skew %d) v(disp %d, start %d, end %d, total %d, scan %d), vrefresh %d, par %u\n",
181 +                     vc4_crtc->display_number, mode->name, mode->clock,
182 +                     mode->hdisplay, mode->hsync_start, mode->hsync_end,
183 +                     mode->htotal, mode->hskew, mode->vdisplay,
184 +                     mode->vsync_start, mode->vsync_end, mode->vtotal,
185 +                     mode->vscan, mode->vrefresh, mode->picture_aspect_ratio);
186 +       mb.timings.display = vc4_crtc->display_number;
187 +
188 +       mb.timings.video_id_code = frame.avi.video_code;
189 +
190 +       mb.timings.clock = mode->clock;
191 +       mb.timings.hdisplay = mode->hdisplay;
192 +       mb.timings.hsync_start = mode->hsync_start;
193 +       mb.timings.hsync_end = mode->hsync_end;
194 +       mb.timings.htotal = mode->htotal;
195 +       mb.timings.hskew = mode->hskew;
196 +       mb.timings.vdisplay = mode->vdisplay;
197 +       mb.timings.vsync_start = mode->vsync_start;
198 +       mb.timings.vsync_end = mode->vsync_end;
199 +       mb.timings.vtotal = mode->vtotal;
200 +       mb.timings.vscan = mode->vscan;
201 +       mb.timings.vrefresh = 0;
202 +       mb.timings.flags = 0;
203 +       if (mode->flags & DRM_MODE_FLAG_PHSYNC)
204 +               mb.timings.flags |= TIMINGS_FLAGS_H_SYNC_POS;
205 +       if (mode->flags & DRM_MODE_FLAG_PVSYNC)
206 +               mb.timings.flags |= TIMINGS_FLAGS_V_SYNC_POS;
207 +
208 +       switch (frame.avi.picture_aspect) {
209 +       default:
210 +       case HDMI_PICTURE_ASPECT_NONE:
211 +               mode->flags |= TIMINGS_FLAGS_ASPECT_NONE;
212 +               break;
213 +       case HDMI_PICTURE_ASPECT_4_3:
214 +               mode->flags |= TIMINGS_FLAGS_ASPECT_4_3;
215 +               break;
216 +       case HDMI_PICTURE_ASPECT_16_9:
217 +               mode->flags |= TIMINGS_FLAGS_ASPECT_16_9;
218 +               break;
219 +       case HDMI_PICTURE_ASPECT_64_27:
220 +               mode->flags |= TIMINGS_FLAGS_ASPECT_64_27;
221 +               break;
222 +       case HDMI_PICTURE_ASPECT_256_135:
223 +               mode->flags |= TIMINGS_FLAGS_ASPECT_256_135;
224 +               break;
225 +       }
226 +
227 +       if (!vc4_encoder->hdmi_monitor)
228 +               mb.timings.flags |= TIMINGS_FLAGS_DVI;
229 +       else if (drm_default_rgb_quant_range(mode) ==
230 +                                       HDMI_QUANTIZATION_RANGE_LIMITED)
231 +               mb.timings.flags |= TIMINGS_FLAGS_RGB_LIMITED;
232 +
233 +       /*
234 +       FIXME: To implement
235 +       switch(mode->flag & DRM_MODE_FLAG_3D_MASK) {
236 +       case DRM_MODE_FLAG_3D_NONE:
237 +       case DRM_MODE_FLAG_3D_FRAME_PACKING:
238 +       case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE:
239 +       case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE:
240 +       case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL:
241 +       case DRM_MODE_FLAG_3D_L_DEPTH:
242 +       case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH:
243 +       case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM:
244 +       case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF:
245 +       }
246 +       */
247 +
248 +       ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb));
249  }
250  
251  static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
252  {
253         struct drm_plane *plane;
254  
255 +       DRM_DEBUG_KMS("[CRTC:%d] vblanks off.\n",
256 +                     crtc->base.id);
257         drm_crtc_vblank_off(crtc);
258  
259         /* Always turn the planes off on CRTC disable. In DRM, planes
260 @@ -617,6 +785,8 @@ static void vc4_crtc_enable(struct drm_c
261  {
262         struct drm_plane *plane;
263  
264 +       DRM_DEBUG_KMS("[CRTC:%d] vblanks on.\n",
265 +                     crtc->base.id);
266         drm_crtc_vblank_on(crtc);
267  
268         /* Unblank the planes (if they're supposed to be displayed). */
269 @@ -635,12 +805,20 @@ vc4_crtc_mode_valid(struct drm_crtc *crt
270                 return MODE_NO_DBLESCAN;
271         }
272  
273 +       /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling
274 +        * working.
275 +        */
276 +       if (mode->clock > 340000)
277 +               return MODE_CLOCK_HIGH;
278 +
279         return MODE_OK;
280  }
281  
282  static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
283                                  struct drm_crtc_state *state)
284  {
285 +       DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n",
286 +                     crtc->base.id);
287         return 0;
288  }
289  
290 @@ -650,6 +828,8 @@ static void vc4_crtc_atomic_flush(struct
291         struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
292         struct drm_device *dev = crtc->dev;
293  
294 +       DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_flush.\n",
295 +                     crtc->base.id);
296         if (crtc->state->event) {
297                 unsigned long flags;
298  
299 @@ -717,6 +897,8 @@ static int vc4_fkms_enable_vblank(struct
300  {
301         struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
302  
303 +       DRM_DEBUG_KMS("[CRTC:%d] enable_vblank.\n",
304 +                     crtc->base.id);
305         vc4_crtc->vblank_enabled = true;
306  
307         return 0;
308 @@ -726,6 +908,8 @@ static void vc4_fkms_disable_vblank(stru
309  {
310         struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
311  
312 +       DRM_DEBUG_KMS("[CRTC:%d] disable_vblank.\n",
313 +                     crtc->base.id);
314         vc4_crtc->vblank_enabled = false;
315  }
316  
317 @@ -760,36 +944,92 @@ static const struct of_device_id vc4_fir
318  static enum drm_connector_status
319  vc4_fkms_connector_detect(struct drm_connector *connector, bool force)
320  {
321 +       DRM_DEBUG_KMS("connector detect.\n");
322         return connector_status_connected;
323  }
324  
325 -static int vc4_fkms_connector_get_modes(struct drm_connector *connector)
326 +static int vc4_fkms_get_edid_block(void *data, u8 *buf, unsigned int block,
327 +                                  size_t len)
328  {
329 -       struct drm_device *dev = connector->dev;
330         struct vc4_fkms_connector *fkms_connector =
331 -               to_vc4_fkms_connector(connector);
332 -       struct vc4_dev *vc4 = to_vc4_dev(dev);
333 -       struct drm_display_mode *mode;
334 -       struct mailbox_get_width_height wh = {
335 -               .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, },
336 -               .display = fkms_connector->display_idx,
337 -               .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT,
338 -                         8, 0, },
339 +                                       (struct vc4_fkms_connector *)data;
340 +       struct vc4_dev *vc4 = fkms_connector->vc4_dev;
341 +       struct mailbox_get_edid mb = {
342 +               .tag1 = { RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY,
343 +                         128 + 8, 0 },
344 +               .block = block,
345 +               .display_number = fkms_connector->display_number,
346         };
347 -       int ret;
348 +       int ret = 0;
349 +
350 +       ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb));
351 +
352 +       if (!ret)
353 +               memcpy(buf, mb.edid, len);
354 +
355 +       return ret;
356 +}
357 +
358 +static int vc4_fkms_connector_get_modes(struct drm_connector *connector)
359 +{
360 +       struct vc4_fkms_connector *fkms_connector =
361 +                                       to_vc4_fkms_connector(connector);
362 +       struct drm_encoder *encoder = fkms_connector->encoder;
363 +       struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder);
364 +       int ret = 0;
365 +       struct edid *edid;
366 +
367 +       edid = drm_do_get_edid(connector, vc4_fkms_get_edid_block,
368 +                              fkms_connector);
369 +
370 +       /* FIXME: Can we do CEC?
371 +        * cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid);
372 +        * if (!edid)
373 +        *      return -ENODEV;
374 +        */
375 +
376 +       vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
377  
378 -       ret = rpi_firmware_property_list(vc4->firmware, &wh, sizeof(wh));
379 +       if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
380 +               vc4_encoder->rgb_range_selectable =
381 +                       drm_rgb_quant_range_selectable(edid);
382 +       }
383 +
384 +       drm_connector_update_edid_property(connector, edid);
385 +       ret = drm_add_edid_modes(connector, edid);
386 +       kfree(edid);
387 +
388 +       return ret;
389 +}
390 +
391 +/* FIXME: Read LCD mode from the firmware. This is the DSI panel resolution. */
392 +static const struct drm_display_mode lcd_mode = {
393 +       DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
394 +                25979400 / 1000,
395 +                800, 800 + 1, 800 + 1 + 2, 800 + 1 + 2 + 46, 0,
396 +                480, 480 + 7, 480 + 7 + 2, 480 + 7 + 2 + 21, 0,
397 +                DRM_MODE_FLAG_INTERLACE)
398 +};
399 +
400 +static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector)
401 +{
402 +       //struct vc4_fkms_connector *fkms_connector =
403 +       //                              to_vc4_fkms_connector(connector);
404 +       //struct drm_encoder *encoder = fkms_connector->encoder;
405 +       //struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder);
406 +       struct drm_display_mode *mode;
407 +       //int ret = 0;
408  
409 -       if (ret) {
410 -               DRM_ERROR("Failed to get screen size: %d (0x%08x 0x%08x)\n",
411 -                         ret, wh.wh[0], wh.wh[1]);
412 -               return 0;
413 +       mode = drm_mode_duplicate(connector->dev,
414 +                                 &lcd_mode);
415 +       if (!mode) {
416 +               DRM_ERROR("Failed to create a new display mode\n");
417 +               return -ENOMEM;
418         }
419  
420 -       mode = drm_cvt_mode(dev, wh.wh[0], wh.wh[1], 60 /* vrefresh */,
421 -                           0, 0, false);
422         drm_mode_probed_add(connector, mode);
423  
424 +       /* We have one mode */
425         return 1;
426  }
427  
428 @@ -798,11 +1038,14 @@ vc4_fkms_connector_best_encoder(struct d
429  {
430         struct vc4_fkms_connector *fkms_connector =
431                 to_vc4_fkms_connector(connector);
432 +       DRM_DEBUG_KMS("best_connector.\n");
433         return fkms_connector->encoder;
434  }
435  
436  static void vc4_fkms_connector_destroy(struct drm_connector *connector)
437  {
438 +       DRM_DEBUG_KMS("[CONNECTOR:%d] destroy.\n",
439 +                     connector->base.id);
440         drm_connector_unregister(connector);
441         drm_connector_cleanup(connector);
442  }
443 @@ -821,14 +1064,22 @@ static const struct drm_connector_helper
444         .best_encoder = vc4_fkms_connector_best_encoder,
445  };
446  
447 +static const struct drm_connector_helper_funcs vc4_fkms_lcd_conn_helper_funcs = {
448 +       .get_modes = vc4_fkms_lcd_connector_get_modes,
449 +       .best_encoder = vc4_fkms_connector_best_encoder,
450 +};
451 +
452  static struct drm_connector *
453  vc4_fkms_connector_init(struct drm_device *dev, struct drm_encoder *encoder,
454 -                       u32 display_idx)
455 +                       u32 display_num)
456  {
457         struct drm_connector *connector = NULL;
458         struct vc4_fkms_connector *fkms_connector;
459 +       struct vc4_dev *vc4_dev = to_vc4_dev(dev);
460         int ret = 0;
461  
462 +       DRM_DEBUG_KMS("connector_init, display_num %u\n", display_num);
463 +
464         fkms_connector = devm_kzalloc(dev->dev, sizeof(*fkms_connector),
465                                       GFP_KERNEL);
466         if (!fkms_connector) {
467 @@ -838,11 +1089,21 @@ vc4_fkms_connector_init(struct drm_devic
468         connector = &fkms_connector->base;
469  
470         fkms_connector->encoder = encoder;
471 -       fkms_connector->display_idx = display_idx;
472 -
473 -       drm_connector_init(dev, connector, &vc4_fkms_connector_funcs,
474 -                          DRM_MODE_CONNECTOR_HDMIA);
475 -       drm_connector_helper_add(connector, &vc4_fkms_connector_helper_funcs);
476 +       fkms_connector->display_number = display_num;
477 +       fkms_connector->display_type = vc4_get_display_type(display_num);
478 +       fkms_connector->vc4_dev = vc4_dev;
479 +
480 +       if (fkms_connector->display_type == DRM_MODE_ENCODER_DSI) {
481 +               drm_connector_init(dev, connector, &vc4_fkms_connector_funcs,
482 +                                  DRM_MODE_CONNECTOR_DSI);
483 +               drm_connector_helper_add(connector,
484 +                                        &vc4_fkms_lcd_conn_helper_funcs);
485 +       } else {
486 +               drm_connector_init(dev, connector, &vc4_fkms_connector_funcs,
487 +                                  DRM_MODE_CONNECTOR_HDMIA);
488 +               drm_connector_helper_add(connector,
489 +                                        &vc4_fkms_connector_helper_funcs);
490 +       }
491  
492         connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
493                              DRM_CONNECTOR_POLL_DISCONNECT);
494 @@ -863,6 +1124,7 @@ vc4_fkms_connector_init(struct drm_devic
495  
496  static void vc4_fkms_encoder_destroy(struct drm_encoder *encoder)
497  {
498 +       DRM_DEBUG_KMS("Encoder_destroy\n");
499         drm_encoder_cleanup(encoder);
500  }
501  
502 @@ -872,10 +1134,12 @@ static const struct drm_encoder_funcs vc
503  
504  static void vc4_fkms_encoder_enable(struct drm_encoder *encoder)
505  {
506 +       DRM_DEBUG_KMS("Encoder_enable\n");
507  }
508  
509  static void vc4_fkms_encoder_disable(struct drm_encoder *encoder)
510  {
511 +       DRM_DEBUG_KMS("Encoder_disable\n");
512  }
513  
514  static const struct drm_encoder_helper_funcs vc4_fkms_encoder_helper_funcs = {
515 @@ -907,6 +1171,7 @@ static int vc4_fkms_create_screen(struct
516         crtc = &vc4_crtc->base;
517  
518         vc4_crtc->display_number = display_ref;
519 +       vc4_crtc->display_type = vc4_get_display_type(display_ref);
520  
521         /* Blank the firmware provided framebuffer */
522         rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank));
523 @@ -950,13 +1215,14 @@ static int vc4_fkms_create_screen(struct
524                 return -ENOMEM;
525         vc4_crtc->encoder = &vc4_encoder->base;
526         vc4_encoder->base.possible_crtcs |= drm_crtc_mask(crtc) ;
527 +
528         drm_encoder_init(drm, &vc4_encoder->base, &vc4_fkms_encoder_funcs,
529 -                        DRM_MODE_ENCODER_TMDS, NULL);
530 +                        vc4_crtc->display_type, NULL);
531         drm_encoder_helper_add(&vc4_encoder->base,
532                                &vc4_fkms_encoder_helper_funcs);
533  
534         vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base,
535 -                                                     display_idx);
536 +                                                     display_ref);
537         if (IS_ERR(vc4_crtc->connector)) {
538                 ret = PTR_ERR(vc4_crtc->connector);
539                 goto err_destroy_encoder;
540 --- a/include/soc/bcm2835/raspberrypi-firmware.h
541 +++ b/include/soc/bcm2835/raspberrypi-firmware.h
542 @@ -78,6 +78,7 @@ enum rpi_firmware_property_tag {
543         RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE =       0x00030014,
544         RPI_FIRMWARE_GET_EDID_BLOCK =                         0x00030020,
545         RPI_FIRMWARE_GET_CUSTOMER_OTP =                       0x00030021,
546 +       RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY =                 0x00030023,
547         RPI_FIRMWARE_GET_DOMAIN_STATE =                       0x00030030,
548         RPI_FIRMWARE_GET_THROTTLED =                          0x00030046,
549         RPI_FIRMWARE_GET_CLOCK_MEASURED =                     0x00030047,
550 @@ -150,6 +151,7 @@ enum rpi_firmware_property_tag {
551         RPI_FIRMWARE_VCHIQ_INIT =                             0x00048010,
552  
553         RPI_FIRMWARE_SET_PLANE =                              0x00048015,
554 +       RPI_FIRMWARE_SET_TIMING =                             0x00048017,
555  
556         RPI_FIRMWARE_GET_COMMAND_LINE =                       0x00050001,
557         RPI_FIRMWARE_GET_DMA_CHANNELS =                       0x00060001,