diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch b/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch new file mode 100644 index 0000000000..186a7c891f --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0256-drm-vc4-fkms-to-query-the-VPU-for-HDMI-clock-limits.patch @@ -0,0 +1,134 @@ +From 1a8e3d8e883b9f9b18dff052a9294d4354994992 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.org> +Date: Thu, 30 May 2019 13:56:15 +0100 +Subject: [PATCH] drm/vc4: fkms to query the VPU for HDMI clock limits + +The VPU has configured clocks for 4k (or not) via config.txt, +and will limit the choice of video modes based on that. +Make fkms query it for these limits too to avoid selecting modes +that can not be handled by the current clock setup. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> +--- + drivers/gpu/drm/vc4/vc4_drv.h | 1 + + drivers/gpu/drm/vc4/vc4_firmware_kms.c | 48 ++++++++++++++++++++++ + include/soc/bcm2835/raspberrypi-firmware.h | 1 + + 3 files changed, 50 insertions(+) + +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -81,6 +81,7 @@ struct vc4_dev { + struct vc4_dsi *dsi1; + struct vc4_vec *vec; + struct vc4_txp *txp; ++ struct vc4_fkms *fkms; + + struct vc4_hang_state *hang_state; + +--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c ++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c +@@ -32,6 +32,14 @@ + #include "vc_image_types.h" + #include <soc/bcm2835/raspberrypi-firmware.h> + ++struct get_display_cfg { ++ u32 max_pixel_clock[2]; //Max pixel clock for each display ++}; ++ ++struct vc4_fkms { ++ struct get_display_cfg cfg; ++}; ++ + #define PLANES_PER_CRTC 3 + + struct set_plane { +@@ -795,6 +803,11 @@ static void vc4_crtc_enable(struct drm_c + static enum drm_mode_status + vc4_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) + { ++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); ++ struct drm_device *dev = crtc->dev; ++ struct vc4_dev *vc4 = to_vc4_dev(dev); ++ struct vc4_fkms *fkms = vc4->fkms; ++ + /* Do not allow doublescan modes from user space */ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { + DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n", +@@ -802,6 +815,22 @@ vc4_crtc_mode_valid(struct drm_crtc *crt + return MODE_NO_DBLESCAN; + } + ++ /* Limit the pixel clock based on the HDMI clock limits from the ++ * firmware ++ */ ++ switch (vc4_crtc->display_number) { ++ case 2: /* HDMI0 */ ++ if (fkms->cfg.max_pixel_clock[0] && ++ mode->clock > fkms->cfg.max_pixel_clock[0]) ++ return MODE_CLOCK_HIGH; ++ break; ++ case 7: /* HDMI1 */ ++ if (fkms->cfg.max_pixel_clock[1] && ++ mode->clock > fkms->cfg.max_pixel_clock[1]) ++ return MODE_CLOCK_HIGH; ++ break; ++ } ++ + /* Limit the pixel clock until we can get dynamic HDMI 2.0 scrambling + * working. + */ +@@ -1295,11 +1324,16 @@ static int vc4_fkms_bind(struct device * + struct device_node *firmware_node; + struct vc4_crtc **crtc_list; + u32 num_displays, display_num; ++ struct vc4_fkms *fkms; + int ret; + u32 display_id; + + vc4->firmware_kms = true; + ++ fkms = devm_kzalloc(dev, sizeof(*fkms), GFP_KERNEL); ++ if (!fkms) ++ return -ENOMEM; ++ + /* firmware kms doesn't have precise a scanoutpos implementation, so + * we can't do the precise vblank timestamp mode. + */ +@@ -1328,6 +1362,18 @@ static int vc4_fkms_bind(struct device * + ret = 0; + } + ++ ret = rpi_firmware_property(vc4->firmware, ++ RPI_FIRMWARE_GET_DISPLAY_CFG, ++ &fkms->cfg, sizeof(fkms->cfg)); ++ ++ if (ret) ++ return -EINVAL; ++ /* The firmware works in Hz. This will be compared against kHz, so div ++ * 1000 now rather than multiple times later. ++ */ ++ fkms->cfg.max_pixel_clock[0] /= 1000; ++ fkms->cfg.max_pixel_clock[1] /= 1000; ++ + /* Allocate a list, with space for a NULL on the end */ + crtc_list = devm_kzalloc(dev, sizeof(crtc_list) * (num_displays + 1), + GFP_KERNEL); +@@ -1369,6 +1415,8 @@ static int vc4_fkms_bind(struct device * + DRM_WARN("No displays found. Consider forcing hotplug if HDMI is attached\n"); + } + ++ vc4->fkms = fkms; ++ + platform_set_drvdata(pdev, crtc_list); + + return 0; +--- a/include/soc/bcm2835/raspberrypi-firmware.h ++++ b/include/soc/bcm2835/raspberrypi-firmware.h +@@ -152,6 +152,7 @@ enum rpi_firmware_property_tag { + RPI_FIRMWARE_SET_PLANE = 0x00048015, + RPI_FIRMWARE_GET_DISPLAY_TIMING = 0x00040017, + RPI_FIRMWARE_SET_TIMING = 0x00048017, ++ RPI_FIRMWARE_GET_DISPLAY_CFG = 0x00040018, + + RPI_FIRMWARE_GET_COMMAND_LINE = 0x00050001, + RPI_FIRMWARE_GET_DMA_CHANNELS = 0x00060001, |