diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0654-drm-vc4-hdmi-Use-a-fixed-rate-for-the-HSM-clock-on-B.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.10/950-0654-drm-vc4-hdmi-Use-a-fixed-rate-for-the-HSM-clock-on-B.patch | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0654-drm-vc4-hdmi-Use-a-fixed-rate-for-the-HSM-clock-on-B.patch b/target/linux/bcm27xx/patches-5.10/950-0654-drm-vc4-hdmi-Use-a-fixed-rate-for-the-HSM-clock-on-B.patch new file mode 100644 index 0000000000..c9d5f3f0a2 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.10/950-0654-drm-vc4-hdmi-Use-a-fixed-rate-for-the-HSM-clock-on-B.patch @@ -0,0 +1,140 @@ +From 0e0118339ce920d988c550d9013333c5d948ab08 Mon Sep 17 00:00:00 2001 +From: Dom Cobley <popcornmix@gmail.com> +Date: Mon, 28 Jun 2021 16:07:16 +0200 +Subject: [PATCH] drm/vc4: hdmi: Use a fixed rate for the HSM clock on + BCM2835 + +Before the introduction of the BCM2711 support, the HSM clock rate was +fixed, and was the CEC and audio clock source on the SoCs previously +supported. + +The HSM clock is also the source of the internal state machine of the +controller and needs to run faster than the pixel clock. All these +requirements were met by running at 101% of the maximum pixel rate, +meeting the fixed clock requirement for audio and CEC, while remaining +faster than any pixel clock we might need. + +However, the BCM2711 brought support for 4k and therefore increased +significantly the rate needed for the HSM, and new, independant, clocks +to feed the audio and CEC clocks. Since the HSM clock can also run much +higher, we also need to lower its rate if possible to reduce its power +consumption. + +The CEC support code changes its clock divider when the HSM clock rate +is changed, but the audio support never had a similar feature and will +glitch out if audio is played back during a mode set. + +Since the HSM rate was meant to be fixed on the SoCs prior to the +BCM2711 anyway, let's introduce back a fixed HSM rate and fix audio. + +Fixes: cd4cb49dc5bb ("drm/vc4: hdmi: Adjust HSM clock rate depending on pixel rate") +Signed-off-by: Dom Cobley <popcornmix@gmail.com> +Signed-off-by: Maxime Ripard <maxime@cerno.tech> +--- + drivers/gpu/drm/vc4/vc4_hdmi.c | 54 +++++++++++++++++++++++----------- + drivers/gpu/drm/vc4/vc4_hdmi.h | 3 ++ + 2 files changed, 40 insertions(+), 17 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_hdmi.c ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c +@@ -908,23 +908,7 @@ static void vc4_hdmi_encoder_pre_crtc_co + return; + } + +- /* +- * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must +- * be faster than pixel clock, infinitesimally faster, tested in +- * simulation. Otherwise, exact value is unimportant for HDMI +- * operation." This conflicts with bcm2835's vc4 documentation, which +- * states HSM's clock has to be at least 108% of the pixel clock. +- * +- * Real life tests reveal that vc4's firmware statement holds up, and +- * users are able to use pixel clocks closer to HSM's, namely for +- * 1920x1200@60Hz. So it was decided to have leave a 1% margin between +- * both clocks. Which, for RPi0-3 implies a maximum pixel clock of +- * 162MHz. +- * +- * Additionally, the AXI clock needs to be at least 25% of +- * pixel clock, but HSM ends up being the limiting factor. +- */ +- hsm_rate = max_t(unsigned long, 120000000, (pixel_rate / 100) * 101); ++ hsm_rate = vc4_hdmi->variant->calc_hsm_clock(vc4_hdmi, pixel_rate); + vc4_hdmi->hsm_req = clk_request_start(vc4_hdmi->hsm_clock, hsm_rate); + if (IS_ERR(vc4_hdmi->hsm_req)) { + DRM_ERROR("Failed to set HSM clock rate: %ld\n", PTR_ERR(vc4_hdmi->hsm_req)); +@@ -1140,6 +1124,39 @@ static const struct drm_encoder_helper_f + .enable = vc4_hdmi_encoder_enable, + }; + ++static u32 vc4_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate) ++{ ++ /* ++ * Whilst this can vary, all the CEC timings are derived from this ++ * clock, so make it constant to avoid having to reconfigure CEC on ++ * every mode change. ++ */ ++ ++ return 163682864; ++} ++ ++static u32 vc5_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate) ++{ ++ /* ++ * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must ++ * be faster than pixel clock, infinitesimally faster, tested in ++ * simulation. Otherwise, exact value is unimportant for HDMI ++ * operation." This conflicts with bcm2835's vc4 documentation, which ++ * states HSM's clock has to be at least 108% of the pixel clock. ++ * ++ * Real life tests reveal that vc4's firmware statement holds up, and ++ * users are able to use pixel clocks closer to HSM's, namely for ++ * 1920x1200@60Hz. So it was decided to have leave a 1% margin between ++ * both clocks. Which, for RPi0-3 implies a maximum pixel clock of ++ * 162MHz. ++ * ++ * Additionally, the AXI clock needs to be at least 25% of ++ * pixel clock, but HSM ends up being the limiting factor. ++ */ ++ ++ return max_t(unsigned long, 120000000, (pixel_rate / 100) * 101); ++} ++ + static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask) + { + int i; +@@ -2322,6 +2339,7 @@ static const struct vc4_hdmi_variant bcm + .phy_disable = vc4_hdmi_phy_disable, + .phy_rng_enable = vc4_hdmi_phy_rng_enable, + .phy_rng_disable = vc4_hdmi_phy_rng_disable, ++ .calc_hsm_clock = vc4_hdmi_calc_hsm_clock, + .channel_map = vc4_hdmi_channel_map, + .supports_hdr = false, + }; +@@ -2350,6 +2368,7 @@ static const struct vc4_hdmi_variant bcm + .phy_disable = vc5_hdmi_phy_disable, + .phy_rng_enable = vc5_hdmi_phy_rng_enable, + .phy_rng_disable = vc5_hdmi_phy_rng_disable, ++ .calc_hsm_clock = vc5_hdmi_calc_hsm_clock, + .channel_map = vc5_hdmi_channel_map, + .supports_hdr = true, + }; +@@ -2378,6 +2397,7 @@ static const struct vc4_hdmi_variant bcm + .phy_disable = vc5_hdmi_phy_disable, + .phy_rng_enable = vc5_hdmi_phy_rng_enable, + .phy_rng_disable = vc5_hdmi_phy_rng_disable, ++ .calc_hsm_clock = vc5_hdmi_calc_hsm_clock, + .channel_map = vc5_hdmi_channel_map, + .supports_hdr = true, + }; +--- a/drivers/gpu/drm/vc4/vc4_hdmi.h ++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h +@@ -97,6 +97,9 @@ struct vc4_hdmi_variant { + /* Callback to disable the RNG in the PHY */ + void (*phy_rng_disable)(struct vc4_hdmi *vc4_hdmi); + ++ /* Callback to calculate hsm clock */ ++ u32 (*calc_hsm_clock)(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate); ++ + /* Callback to get channel map */ + u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask); + |