1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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);
};
|