drm/vc4: hdmi: Adjust HSM clock rate depending on pixel rate 83/243883/1
authorMaxime Ripard <maxime@cerno.tech>
Tue, 25 Aug 2020 08:31:56 +0000 (17:31 +0900)
committerHoegeun Kwon <hoegeun.kwon@samsung.com>
Fri, 11 Sep 2020 01:44:50 +0000 (10:44 +0900)
The HSM clock needs to be setup at around 101% of the pixel rate. This
was done previously by setting the clock rate to 163.7MHz at probe time and
only check in mode_valid whether the mode pixel clock was under the pixel
clock +1% or not.

However, with 4k we need to change that frequency to a higher frequency
than 163.7MHz, and yet want to have the lowest clock as possible to have a
decent power saving.

Let's change that logic a bit by setting the clock rate of the HSM clock
to the pixel rate at encoder_enable time. This would work for the
BCM2711 that support 4k resolutions and has a clock that can provide it,
but we still have to take care of a 4k panel plugged on a BCM283x SoCs
that wouldn't be able to use those modes, so let's define the limit in
the variant.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Tested-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://patchwork.freedesktop.org/patch/msgid/7e692ddc231d33dd671e70ea04dd1dcf56c1ecb3.1599120059.git-series.maxime@cerno.tech
[hoegeun.kwon: Applied missing code, needed to troubleshoot page flip
timed out issue.]
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
Change-Id: I43328575d59a0bbccac8d4153ac5ed54f029550b

drivers/gpu/drm/vc4/vc4_hdmi.c

index 77c05ae..1c20561 100644 (file)
@@ -612,7 +612,23 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
                return;
        }
 
-       hsm_rate = vc4_hdmi->variant->calc_hsm_clock(vc4_hdmi, 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.
+        */
+       hsm_rate = max_t(unsigned long, 120000000, (pixel_rate / 100) * 101);
        ret = clk_set_rate(vc4_hdmi->hsm_clock, hsm_rate);
        if (ret) {
                DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
@@ -757,22 +773,6 @@ static enum drm_mode_status
 vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
                            const struct drm_display_mode *mode)
 {
-       /*
-        * 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.
-        */
        struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
 
        if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock)
@@ -794,7 +794,7 @@ static u32 vc4_hdmi_get_hsm_clock(struct vc4_hdmi *vc4_hdmi)
 
 static u32 vc5_hdmi_get_hsm_clock(struct vc4_hdmi *vc4_hdmi)
 {
-       return 108000000;
+       return 120000000;
 }
 
 static u32 vc4_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate)
@@ -815,7 +815,7 @@ static u32 vc5_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixe
         * Use 101% as this is what the firmware uses.
         */
 
-       return max_t(unsigned long, 108000000, (pixel_rate / 100) * 101);
+       return max_t(unsigned long, 120000000, (pixel_rate / 100) * 101);
 }
 
 static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)