+++ /dev/null
-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
-@@ -909,23 +909,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));
-@@ -1141,6 +1125,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;
-@@ -2336,6 +2353,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,
- };
-@@ -2364,6 +2382,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,
- };
-@@ -2392,6 +2411,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);
-