bcm27xx: update patches from RPi foundation
[openwrt/staging/luka.git] / target / linux / bcm27xx / patches-5.4 / 950-0684-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch
diff --git a/target/linux/bcm27xx/patches-5.4/950-0684-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch b/target/linux/bcm27xx/patches-5.4/950-0684-vc4_hdmi-BCM2835-requires-a-fixed-hsm-clock-for-CEC-.patch
new file mode 100644 (file)
index 0000000..0ea80ae
--- /dev/null
@@ -0,0 +1,93 @@
+From af3f381a59c10f6bd49d86a5ff2325b6ebeb79e9 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 27 Apr 2020 19:07:50 +0100
+Subject: [PATCH] vc4_hdmi: BCM2835 requires a fixed hsm clock for CEC
+ to work
+
+Signed-off-by: popcornmix <popcornmix@gmail.com>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 32 ++++++++++++++++++++++++++------
+ drivers/gpu/drm/vc4/vc4_hdmi.h |  3 +++
+ 2 files changed, 29 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -580,12 +580,7 @@ static void vc4_hdmi_encoder_enable(stru
+               return;
+       }
+-      /*
+-       * The HSM rate needs to be slightly greater than the pixel clock, with
+-       * a minimum of 108MHz.
+-       * Use 101% as this is what the firmware uses.
+-       */
+-      hsm_rate = max_t(unsigned long, 108000000, (pixel_rate / 100) * 101);
++      hsm_rate = vc4_hdmi->variant->calc_hsm_clock(vc4_hdmi, pixel_rate);
+       ret = clk_set_rate(vc4_hdmi->hsm_clock, hsm_rate);
+       if (ret) {
+               DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
+@@ -753,6 +748,28 @@ static u32 vc5_hdmi_get_hsm_clock(struct
+       return 108000000;
+ }
++static u32 vc4_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate)
++{
++      /*
++       * This is the rate that is set by the firmware.  The number
++       * needs to be a bit higher than the pixel clock rate
++       * (generally 148.5Mhz).
++       */
++
++      return 163682864;
++}
++
++static u32 vc5_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate)
++{
++      /*
++       * The HSM rate needs to be slightly greater than the pixel clock, with
++       * a minimum of 108MHz.
++       * Use 101% as this is what the firmware uses.
++       */
++
++      return max_t(unsigned long, 108000000, (pixel_rate / 100) * 101);
++}
++
+ static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
+ {
+       int i;
+@@ -1748,6 +1765,7 @@ static const struct vc4_hdmi_variant bcm
+       .phy_rng_enable         = vc4_hdmi_phy_rng_enable,
+       .phy_rng_disable        = vc4_hdmi_phy_rng_disable,
+       .get_hsm_clock          = vc4_hdmi_get_hsm_clock,
++      .calc_hsm_clock         = vc4_hdmi_calc_hsm_clock,
+       .channel_map            = vc4_hdmi_channel_map,
+ };
+@@ -1772,6 +1790,7 @@ static const struct vc4_hdmi_variant bcm
+       .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
+       .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
+       .get_hsm_clock          = vc5_hdmi_get_hsm_clock,
++      .calc_hsm_clock         = vc5_hdmi_calc_hsm_clock,
+       .channel_map            = vc5_hdmi_channel_map,
+ };
+@@ -1796,6 +1815,7 @@ static const struct vc4_hdmi_variant bcm
+       .phy_rng_enable         = vc5_hdmi_phy_rng_enable,
+       .phy_rng_disable        = vc5_hdmi_phy_rng_disable,
+       .get_hsm_clock          = vc5_hdmi_get_hsm_clock,
++      .calc_hsm_clock         = vc5_hdmi_calc_hsm_clock,
+       .channel_map            = vc5_hdmi_channel_map,
+ };
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -92,6 +92,9 @@ struct vc4_hdmi_variant {
+       /* Callback to get hsm clock */
+       u32 (*get_hsm_clock)(struct vc4_hdmi *vc4_hdmi);
++      /* Callback to get 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);
+ };