e5ffc3e96ffe4ce616adb16b74fe63c9598d4278
[openwrt/staging/981213.git] /
1 From af3f381a59c10f6bd49d86a5ff2325b6ebeb79e9 Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Mon, 27 Apr 2020 19:07:50 +0100
4 Subject: [PATCH] vc4_hdmi: BCM2835 requires a fixed hsm clock for CEC
5 to work
6
7 Signed-off-by: popcornmix <popcornmix@gmail.com>
8 ---
9 drivers/gpu/drm/vc4/vc4_hdmi.c | 32 ++++++++++++++++++++++++++------
10 drivers/gpu/drm/vc4/vc4_hdmi.h | 3 +++
11 2 files changed, 29 insertions(+), 6 deletions(-)
12
13 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
14 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
15 @@ -580,12 +580,7 @@ static void vc4_hdmi_encoder_enable(stru
16 return;
17 }
18
19 - /*
20 - * The HSM rate needs to be slightly greater than the pixel clock, with
21 - * a minimum of 108MHz.
22 - * Use 101% as this is what the firmware uses.
23 - */
24 - hsm_rate = max_t(unsigned long, 108000000, (pixel_rate / 100) * 101);
25 + hsm_rate = vc4_hdmi->variant->calc_hsm_clock(vc4_hdmi, pixel_rate);
26 ret = clk_set_rate(vc4_hdmi->hsm_clock, hsm_rate);
27 if (ret) {
28 DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
29 @@ -753,6 +748,28 @@ static u32 vc5_hdmi_get_hsm_clock(struct
30 return 108000000;
31 }
32
33 +static u32 vc4_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate)
34 +{
35 + /*
36 + * This is the rate that is set by the firmware. The number
37 + * needs to be a bit higher than the pixel clock rate
38 + * (generally 148.5Mhz).
39 + */
40 +
41 + return 163682864;
42 +}
43 +
44 +static u32 vc5_hdmi_calc_hsm_clock(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate)
45 +{
46 + /*
47 + * The HSM rate needs to be slightly greater than the pixel clock, with
48 + * a minimum of 108MHz.
49 + * Use 101% as this is what the firmware uses.
50 + */
51 +
52 + return max_t(unsigned long, 108000000, (pixel_rate / 100) * 101);
53 +}
54 +
55 static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
56 {
57 int i;
58 @@ -1749,6 +1766,7 @@ static const struct vc4_hdmi_variant bcm
59 .phy_rng_enable = vc4_hdmi_phy_rng_enable,
60 .phy_rng_disable = vc4_hdmi_phy_rng_disable,
61 .get_hsm_clock = vc4_hdmi_get_hsm_clock,
62 + .calc_hsm_clock = vc4_hdmi_calc_hsm_clock,
63 .channel_map = vc4_hdmi_channel_map,
64 };
65
66 @@ -1773,6 +1791,7 @@ static const struct vc4_hdmi_variant bcm
67 .phy_rng_enable = vc5_hdmi_phy_rng_enable,
68 .phy_rng_disable = vc5_hdmi_phy_rng_disable,
69 .get_hsm_clock = vc5_hdmi_get_hsm_clock,
70 + .calc_hsm_clock = vc5_hdmi_calc_hsm_clock,
71 .channel_map = vc5_hdmi_channel_map,
72 };
73
74 @@ -1797,6 +1816,7 @@ static const struct vc4_hdmi_variant bcm
75 .phy_rng_enable = vc5_hdmi_phy_rng_enable,
76 .phy_rng_disable = vc5_hdmi_phy_rng_disable,
77 .get_hsm_clock = vc5_hdmi_get_hsm_clock,
78 + .calc_hsm_clock = vc5_hdmi_calc_hsm_clock,
79 .channel_map = vc5_hdmi_channel_map,
80 };
81
82 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
83 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
84 @@ -92,6 +92,9 @@ struct vc4_hdmi_variant {
85 /* Callback to get hsm clock */
86 u32 (*get_hsm_clock)(struct vc4_hdmi *vc4_hdmi);
87
88 + /* Callback to get hsm clock */
89 + u32 (*calc_hsm_clock)(struct vc4_hdmi *vc4_hdmi, unsigned long pixel_rate);
90 +
91 /* Callback to get channel map */
92 u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask);
93 };