X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0606-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch;fp=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0606-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch;h=0000000000000000000000000000000000000000;hb=67dcc43f3a22dc3a7ac07a7065971b426feeb043;hp=b56f97005dcff84458482219f337acc355c54178;hpb=47a93a810f78adce5a130d287f82b28e9b54313c;p=openwrt%2Fstaging%2Fchunkeey.git diff --git a/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch b/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch deleted file mode 100644 index b56f97005d..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0606-drm-vc4-FKMS-reads-the-EDID-from-fw-and-supports-mod.patch +++ /dev/null @@ -1,557 +0,0 @@ -From 9536044338d9c341e805e288a58090c49a793638 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 9 Apr 2019 18:23:41 +0100 -Subject: [PATCH 606/806] drm: vc4: FKMS reads the EDID from fw, and supports - mode setting - -This extends FKMS to read the EDID from the display, and support -requesting a particular mode via KMS. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_firmware_kms.c | 334 ++++++++++++++++++--- - include/soc/bcm2835/raspberrypi-firmware.h | 2 + - 2 files changed, 302 insertions(+), 34 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c -@@ -88,11 +88,60 @@ struct mailbox_blank_display { - u32 blank; - }; - --struct mailbox_get_width_height { -+struct mailbox_get_edid { - struct rpi_firmware_property_tag_header tag1; -- u32 display; -- struct rpi_firmware_property_tag_header tag2; -- u32 wh[2]; -+ u32 block; -+ u32 display_number; -+ u8 edid[128]; -+}; -+ -+struct set_timings { -+ u8 display; -+ u8 padding; -+ u16 video_id_code; -+ -+ u32 clock; /* in kHz */ -+ -+ u16 hdisplay; -+ u16 hsync_start; -+ -+ u16 hsync_end; -+ u16 htotal; -+ -+ u16 hskew; -+ u16 vdisplay; -+ -+ u16 vsync_start; -+ u16 vsync_end; -+ -+ u16 vtotal; -+ u16 vscan; -+ -+ u16 vrefresh; -+ u16 padding2; -+ -+ u32 flags; -+#define TIMINGS_FLAGS_H_SYNC_POS BIT(0) -+#define TIMINGS_FLAGS_H_SYNC_NEG 0 -+#define TIMINGS_FLAGS_V_SYNC_POS BIT(1) -+#define TIMINGS_FLAGS_V_SYNC_NEG 0 -+ -+#define TIMINGS_FLAGS_ASPECT_MASK GENMASK(7, 4) -+#define TIMINGS_FLAGS_ASPECT_NONE (0 << 4) -+#define TIMINGS_FLAGS_ASPECT_4_3 (1 << 4) -+#define TIMINGS_FLAGS_ASPECT_16_9 (2 << 4) -+#define TIMINGS_FLAGS_ASPECT_64_27 (3 << 4) -+#define TIMINGS_FLAGS_ASPECT_256_135 (4 << 4) -+ -+/* Limited range RGB flag. Not set corresponds to full range. */ -+#define TIMINGS_FLAGS_RGB_LIMITED BIT(8) -+/* DVI monitor, therefore disable infoframes. Not set corresponds to HDMI. */ -+#define TIMINGS_FLAGS_DVI BIT(9) -+}; -+ -+struct mailbox_set_mode { -+ struct rpi_firmware_property_tag_header tag1; -+ struct set_timings timings; - }; - - static const struct vc_image_format { -@@ -186,6 +235,7 @@ struct vc4_crtc { - u32 overscan[4]; - bool vblank_enabled; - u32 display_number; -+ u32 display_type; - }; - - static inline struct vc4_crtc *to_vc4_crtc(struct drm_crtc *crtc) -@@ -195,6 +245,8 @@ static inline struct vc4_crtc *to_vc4_cr - - struct vc4_fkms_encoder { - struct drm_encoder base; -+ bool hdmi_monitor; -+ bool rgb_range_selectable; - }; - - static inline struct vc4_fkms_encoder * -@@ -212,7 +264,9 @@ struct vc4_fkms_connector { - * hook. - */ - struct drm_encoder *encoder; -- u32 display_idx; -+ struct vc4_dev *vc4_dev; -+ u32 display_number; -+ u32 display_type; - }; - - static inline struct vc4_fkms_connector * -@@ -221,6 +275,26 @@ to_vc4_fkms_connector(struct drm_connect - return container_of(connector, struct vc4_fkms_connector, base); - } - -+static u32 vc4_get_display_type(u32 display_number) -+{ -+ const u32 display_types[] = { -+ /* The firmware display (DispmanX) IDs map to specific types in -+ * a fixed manner. -+ */ -+ DRM_MODE_ENCODER_DSI, /* MAIN_LCD */ -+ DRM_MODE_ENCODER_DSI, /* AUX_LCD */ -+ DRM_MODE_ENCODER_TMDS, /* HDMI0 */ -+ DRM_MODE_ENCODER_TVDAC, /* VEC */ -+ DRM_MODE_ENCODER_NONE, /* FORCE_LCD */ -+ DRM_MODE_ENCODER_NONE, /* FORCE_TV */ -+ DRM_MODE_ENCODER_NONE, /* FORCE_OTHER */ -+ DRM_MODE_ENCODER_TMDS, /* HDMI1 */ -+ DRM_MODE_ENCODER_NONE, /* FORCE_TV2 */ -+ }; -+ return display_number > ARRAY_SIZE(display_types) - 1 ? -+ DRM_MODE_ENCODER_NONE : display_types[display_number]; -+} -+ - /* Firmware's structure for making an FB mbox call. */ - struct fbinfo_s { - u32 xres, yres, xres_virtual, yres_virtual; -@@ -255,10 +329,15 @@ static int vc4_plane_set_blank(struct dr - .plane_id = vc4_plane->mb.plane.plane_id, - } - }; -+ static const char * const plane_types[] = { -+ "overlay", -+ "primary", -+ "cursor" -+ }; - int ret; - -- DRM_DEBUG_ATOMIC("[PLANE:%d:%s] overlay plane %s", -- plane->base.id, plane->name, -+ DRM_DEBUG_ATOMIC("[PLANE:%d:%s] %s plane %s", -+ plane->base.id, plane->name, plane_types[plane->type], - blank ? "blank" : "unblank"); - - if (blank) -@@ -593,13 +672,102 @@ fail: - - static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc) - { -- /* Everyting is handled in the planes. */ -+ struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -+ struct drm_display_mode *mode = &crtc->state->adjusted_mode; -+ struct vc4_fkms_encoder *vc4_encoder = -+ to_vc4_fkms_encoder(vc4_crtc->encoder); -+ struct mailbox_set_mode mb = { -+ .tag1 = { RPI_FIRMWARE_SET_TIMING, -+ sizeof(struct set_timings), 0}, -+ }; -+ union hdmi_infoframe frame; -+ int ret; -+ -+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false); -+ if (ret < 0) { -+ DRM_ERROR("couldn't fill AVI infoframe\n"); -+ return; -+ } -+ -+ 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", -+ vc4_crtc->display_number, mode->name, mode->clock, -+ mode->hdisplay, mode->hsync_start, mode->hsync_end, -+ mode->htotal, mode->hskew, mode->vdisplay, -+ mode->vsync_start, mode->vsync_end, mode->vtotal, -+ mode->vscan, mode->vrefresh, mode->picture_aspect_ratio); -+ mb.timings.display = vc4_crtc->display_number; -+ -+ mb.timings.video_id_code = frame.avi.video_code; -+ -+ mb.timings.clock = mode->clock; -+ mb.timings.hdisplay = mode->hdisplay; -+ mb.timings.hsync_start = mode->hsync_start; -+ mb.timings.hsync_end = mode->hsync_end; -+ mb.timings.htotal = mode->htotal; -+ mb.timings.hskew = mode->hskew; -+ mb.timings.vdisplay = mode->vdisplay; -+ mb.timings.vsync_start = mode->vsync_start; -+ mb.timings.vsync_end = mode->vsync_end; -+ mb.timings.vtotal = mode->vtotal; -+ mb.timings.vscan = mode->vscan; -+ mb.timings.vrefresh = 0; -+ mb.timings.flags = 0; -+ if (mode->flags & DRM_MODE_FLAG_PHSYNC) -+ mb.timings.flags |= TIMINGS_FLAGS_H_SYNC_POS; -+ if (mode->flags & DRM_MODE_FLAG_PVSYNC) -+ mb.timings.flags |= TIMINGS_FLAGS_V_SYNC_POS; -+ -+ switch (frame.avi.picture_aspect) { -+ default: -+ case HDMI_PICTURE_ASPECT_NONE: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_NONE; -+ break; -+ case HDMI_PICTURE_ASPECT_4_3: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_4_3; -+ break; -+ case HDMI_PICTURE_ASPECT_16_9: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_16_9; -+ break; -+ case HDMI_PICTURE_ASPECT_64_27: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_64_27; -+ break; -+ case HDMI_PICTURE_ASPECT_256_135: -+ mode->flags |= TIMINGS_FLAGS_ASPECT_256_135; -+ break; -+ } -+ -+ if (!vc4_encoder->hdmi_monitor) -+ mb.timings.flags |= TIMINGS_FLAGS_DVI; -+ else if (drm_default_rgb_quant_range(mode) == -+ HDMI_QUANTIZATION_RANGE_LIMITED) -+ mb.timings.flags |= TIMINGS_FLAGS_RGB_LIMITED; -+ -+ /* -+ FIXME: To implement -+ switch(mode->flag & DRM_MODE_FLAG_3D_MASK) { -+ case DRM_MODE_FLAG_3D_NONE: -+ case DRM_MODE_FLAG_3D_FRAME_PACKING: -+ case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: -+ case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: -+ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: -+ case DRM_MODE_FLAG_3D_L_DEPTH: -+ case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: -+ case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: -+ case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: -+ } -+ */ -+ -+ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); - } - - static void vc4_crtc_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) - { - struct drm_plane *plane; - -+ DRM_DEBUG_KMS("[CRTC:%d] vblanks off.\n", -+ crtc->base.id); - drm_crtc_vblank_off(crtc); - - /* Always turn the planes off on CRTC disable. In DRM, planes -@@ -617,6 +785,8 @@ static void vc4_crtc_enable(struct drm_c - { - struct drm_plane *plane; - -+ DRM_DEBUG_KMS("[CRTC:%d] vblanks on.\n", -+ crtc->base.id); - drm_crtc_vblank_on(crtc); - - /* Unblank the planes (if they're supposed to be displayed). */ -@@ -635,12 +805,20 @@ vc4_crtc_mode_valid(struct drm_crtc *crt - return MODE_NO_DBLESCAN; - } - -+ /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling -+ * working. -+ */ -+ if (mode->clock > 340000) -+ return MODE_CLOCK_HIGH; -+ - return MODE_OK; - } - - static int vc4_crtc_atomic_check(struct drm_crtc *crtc, - struct drm_crtc_state *state) - { -+ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_check.\n", -+ crtc->base.id); - return 0; - } - -@@ -650,6 +828,8 @@ static void vc4_crtc_atomic_flush(struct - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - struct drm_device *dev = crtc->dev; - -+ DRM_DEBUG_KMS("[CRTC:%d] crtc_atomic_flush.\n", -+ crtc->base.id); - if (crtc->state->event) { - unsigned long flags; - -@@ -717,6 +897,8 @@ static int vc4_fkms_enable_vblank(struct - { - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - -+ DRM_DEBUG_KMS("[CRTC:%d] enable_vblank.\n", -+ crtc->base.id); - vc4_crtc->vblank_enabled = true; - - return 0; -@@ -726,6 +908,8 @@ static void vc4_fkms_disable_vblank(stru - { - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - -+ DRM_DEBUG_KMS("[CRTC:%d] disable_vblank.\n", -+ crtc->base.id); - vc4_crtc->vblank_enabled = false; - } - -@@ -760,36 +944,92 @@ static const struct of_device_id vc4_fir - static enum drm_connector_status - vc4_fkms_connector_detect(struct drm_connector *connector, bool force) - { -+ DRM_DEBUG_KMS("connector detect.\n"); - return connector_status_connected; - } - --static int vc4_fkms_connector_get_modes(struct drm_connector *connector) -+static int vc4_fkms_get_edid_block(void *data, u8 *buf, unsigned int block, -+ size_t len) - { -- struct drm_device *dev = connector->dev; - struct vc4_fkms_connector *fkms_connector = -- to_vc4_fkms_connector(connector); -- struct vc4_dev *vc4 = to_vc4_dev(dev); -- struct drm_display_mode *mode; -- struct mailbox_get_width_height wh = { -- .tag1 = {RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, 4, 0, }, -- .display = fkms_connector->display_idx, -- .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_GET_PHYSICAL_WIDTH_HEIGHT, -- 8, 0, }, -+ (struct vc4_fkms_connector *)data; -+ struct vc4_dev *vc4 = fkms_connector->vc4_dev; -+ struct mailbox_get_edid mb = { -+ .tag1 = { RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY, -+ 128 + 8, 0 }, -+ .block = block, -+ .display_number = fkms_connector->display_number, - }; -- int ret; -+ int ret = 0; -+ -+ ret = rpi_firmware_property_list(vc4->firmware, &mb, sizeof(mb)); -+ -+ if (!ret) -+ memcpy(buf, mb.edid, len); -+ -+ return ret; -+} -+ -+static int vc4_fkms_connector_get_modes(struct drm_connector *connector) -+{ -+ struct vc4_fkms_connector *fkms_connector = -+ to_vc4_fkms_connector(connector); -+ struct drm_encoder *encoder = fkms_connector->encoder; -+ struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); -+ int ret = 0; -+ struct edid *edid; -+ -+ edid = drm_do_get_edid(connector, vc4_fkms_get_edid_block, -+ fkms_connector); -+ -+ /* FIXME: Can we do CEC? -+ * cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid); -+ * if (!edid) -+ * return -ENODEV; -+ */ -+ -+ vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); - -- ret = rpi_firmware_property_list(vc4->firmware, &wh, sizeof(wh)); -+ if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { -+ vc4_encoder->rgb_range_selectable = -+ drm_rgb_quant_range_selectable(edid); -+ } -+ -+ drm_connector_update_edid_property(connector, edid); -+ ret = drm_add_edid_modes(connector, edid); -+ kfree(edid); -+ -+ return ret; -+} -+ -+/* FIXME: Read LCD mode from the firmware. This is the DSI panel resolution. */ -+static const struct drm_display_mode lcd_mode = { -+ DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, -+ 25979400 / 1000, -+ 800, 800 + 1, 800 + 1 + 2, 800 + 1 + 2 + 46, 0, -+ 480, 480 + 7, 480 + 7 + 2, 480 + 7 + 2 + 21, 0, -+ DRM_MODE_FLAG_INTERLACE) -+}; -+ -+static int vc4_fkms_lcd_connector_get_modes(struct drm_connector *connector) -+{ -+ //struct vc4_fkms_connector *fkms_connector = -+ // to_vc4_fkms_connector(connector); -+ //struct drm_encoder *encoder = fkms_connector->encoder; -+ //struct vc4_fkms_encoder *vc4_encoder = to_vc4_fkms_encoder(encoder); -+ struct drm_display_mode *mode; -+ //int ret = 0; - -- if (ret) { -- DRM_ERROR("Failed to get screen size: %d (0x%08x 0x%08x)\n", -- ret, wh.wh[0], wh.wh[1]); -- return 0; -+ mode = drm_mode_duplicate(connector->dev, -+ &lcd_mode); -+ if (!mode) { -+ DRM_ERROR("Failed to create a new display mode\n"); -+ return -ENOMEM; - } - -- mode = drm_cvt_mode(dev, wh.wh[0], wh.wh[1], 60 /* vrefresh */, -- 0, 0, false); - drm_mode_probed_add(connector, mode); - -+ /* We have one mode */ - return 1; - } - -@@ -798,11 +1038,14 @@ vc4_fkms_connector_best_encoder(struct d - { - struct vc4_fkms_connector *fkms_connector = - to_vc4_fkms_connector(connector); -+ DRM_DEBUG_KMS("best_connector.\n"); - return fkms_connector->encoder; - } - - static void vc4_fkms_connector_destroy(struct drm_connector *connector) - { -+ DRM_DEBUG_KMS("[CONNECTOR:%d] destroy.\n", -+ connector->base.id); - drm_connector_unregister(connector); - drm_connector_cleanup(connector); - } -@@ -821,14 +1064,22 @@ static const struct drm_connector_helper - .best_encoder = vc4_fkms_connector_best_encoder, - }; - -+static const struct drm_connector_helper_funcs vc4_fkms_lcd_conn_helper_funcs = { -+ .get_modes = vc4_fkms_lcd_connector_get_modes, -+ .best_encoder = vc4_fkms_connector_best_encoder, -+}; -+ - static struct drm_connector * - vc4_fkms_connector_init(struct drm_device *dev, struct drm_encoder *encoder, -- u32 display_idx) -+ u32 display_num) - { - struct drm_connector *connector = NULL; - struct vc4_fkms_connector *fkms_connector; -+ struct vc4_dev *vc4_dev = to_vc4_dev(dev); - int ret = 0; - -+ DRM_DEBUG_KMS("connector_init, display_num %u\n", display_num); -+ - fkms_connector = devm_kzalloc(dev->dev, sizeof(*fkms_connector), - GFP_KERNEL); - if (!fkms_connector) { -@@ -838,11 +1089,21 @@ vc4_fkms_connector_init(struct drm_devic - connector = &fkms_connector->base; - - fkms_connector->encoder = encoder; -- fkms_connector->display_idx = display_idx; -- -- drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, -- DRM_MODE_CONNECTOR_HDMIA); -- drm_connector_helper_add(connector, &vc4_fkms_connector_helper_funcs); -+ fkms_connector->display_number = display_num; -+ fkms_connector->display_type = vc4_get_display_type(display_num); -+ fkms_connector->vc4_dev = vc4_dev; -+ -+ if (fkms_connector->display_type == DRM_MODE_ENCODER_DSI) { -+ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, -+ DRM_MODE_CONNECTOR_DSI); -+ drm_connector_helper_add(connector, -+ &vc4_fkms_lcd_conn_helper_funcs); -+ } else { -+ drm_connector_init(dev, connector, &vc4_fkms_connector_funcs, -+ DRM_MODE_CONNECTOR_HDMIA); -+ drm_connector_helper_add(connector, -+ &vc4_fkms_connector_helper_funcs); -+ } - - connector->polled = (DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT); -@@ -863,6 +1124,7 @@ vc4_fkms_connector_init(struct drm_devic - - static void vc4_fkms_encoder_destroy(struct drm_encoder *encoder) - { -+ DRM_DEBUG_KMS("Encoder_destroy\n"); - drm_encoder_cleanup(encoder); - } - -@@ -872,10 +1134,12 @@ static const struct drm_encoder_funcs vc - - static void vc4_fkms_encoder_enable(struct drm_encoder *encoder) - { -+ DRM_DEBUG_KMS("Encoder_enable\n"); - } - - static void vc4_fkms_encoder_disable(struct drm_encoder *encoder) - { -+ DRM_DEBUG_KMS("Encoder_disable\n"); - } - - static const struct drm_encoder_helper_funcs vc4_fkms_encoder_helper_funcs = { -@@ -907,6 +1171,7 @@ static int vc4_fkms_create_screen(struct - crtc = &vc4_crtc->base; - - vc4_crtc->display_number = display_ref; -+ vc4_crtc->display_type = vc4_get_display_type(display_ref); - - /* Blank the firmware provided framebuffer */ - rpi_firmware_property_list(vc4->firmware, &blank, sizeof(blank)); -@@ -950,13 +1215,14 @@ static int vc4_fkms_create_screen(struct - return -ENOMEM; - vc4_crtc->encoder = &vc4_encoder->base; - vc4_encoder->base.possible_crtcs |= drm_crtc_mask(crtc) ; -+ - drm_encoder_init(drm, &vc4_encoder->base, &vc4_fkms_encoder_funcs, -- DRM_MODE_ENCODER_TMDS, NULL); -+ vc4_crtc->display_type, NULL); - drm_encoder_helper_add(&vc4_encoder->base, - &vc4_fkms_encoder_helper_funcs); - - vc4_crtc->connector = vc4_fkms_connector_init(drm, &vc4_encoder->base, -- display_idx); -+ display_ref); - if (IS_ERR(vc4_crtc->connector)) { - ret = PTR_ERR(vc4_crtc->connector); - goto err_destroy_encoder; ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -78,6 +78,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE = 0x00030014, - RPI_FIRMWARE_GET_EDID_BLOCK = 0x00030020, - RPI_FIRMWARE_GET_CUSTOMER_OTP = 0x00030021, -+ RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY = 0x00030023, - RPI_FIRMWARE_GET_DOMAIN_STATE = 0x00030030, - RPI_FIRMWARE_GET_THROTTLED = 0x00030046, - RPI_FIRMWARE_GET_CLOCK_MEASURED = 0x00030047, -@@ -150,6 +151,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_VCHIQ_INIT = 0x00048010, - - RPI_FIRMWARE_SET_PLANE = 0x00048015, -+ RPI_FIRMWARE_SET_TIMING = 0x00048017, - - RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, - RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001,