5b836f8bf8a57f742d2316dc6b3633bce014542b
[openwrt/staging/ansuel.git] /
1 From 3c33724058852d7c58d77d03e11ca545fb04256a Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Mon, 10 Feb 2020 15:23:06 +0100
4 Subject: [PATCH] drm/vc4: hdmi: Adjust HSM clock rate depending on
5 pixel rate
6
7 The HSM clock needs to be setup at around 110% of the pixel rate. This
8 was done previously by setting the clock rate to 148.5MHz * 108% at
9 probe time and only check in mode_valid whether the mode pixel clock was
10 under 148.5MHz or not.
11
12 However, with 4k we need to change that frequency to a higher frequency
13 than 148.5MHz.
14
15 Let's change that logic a bit by setting the clock rate of the HSM clock
16 to the pixel rate at encoder_enable time. This would work for the
17 BCM2711 that support 4k resolutions and has a clock that can provide it,
18 but we still have to take care of a 4k panel plugged on a BCM283x SoCs
19 that wouldn't be able to use those modes, so let's define the limit in
20 the variant.
21
22 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
23 ---
24 drivers/gpu/drm/vc4/vc4_hdmi.c | 51 +++++++++++++++++-----------------
25 drivers/gpu/drm/vc4/vc4_hdmi.h | 3 ++
26 2 files changed, 29 insertions(+), 25 deletions(-)
27
28 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
29 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
30 @@ -52,7 +52,6 @@
31 #include "vc4_hdmi_regs.h"
32 #include "vc4_regs.h"
33
34 -#define HSM_CLOCK_FREQ 163682864
35 #define CEC_CLOCK_FREQ 40000
36
37 static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
38 @@ -329,6 +328,7 @@ static void vc4_hdmi_encoder_disable(str
39 HDMI_WRITE(HDMI_VID_CTL,
40 HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
41
42 + clk_disable_unprepare(vc4_hdmi->hsm_clock);
43 clk_disable_unprepare(vc4_hdmi->pixel_clock);
44
45 ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
46 @@ -426,6 +426,7 @@ static void vc4_hdmi_encoder_enable(stru
47 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
48 struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
49 bool debug_dump_regs = false;
50 + unsigned long pixel_rate, hsm_rate;
51 int ret;
52
53 ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
54 @@ -434,9 +435,8 @@ static void vc4_hdmi_encoder_enable(stru
55 return;
56 }
57
58 - ret = clk_set_rate(vc4_hdmi->pixel_clock,
59 - mode->clock * 1000 *
60 - ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
61 + pixel_rate = mode->clock * 1000 * ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1);
62 + ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
63 if (ret) {
64 DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
65 return;
66 @@ -448,6 +448,24 @@ static void vc4_hdmi_encoder_enable(stru
67 return;
68 }
69
70 + /*
71 + * The HSM rate needs to be at 108% of the pixel clock, with a
72 + * minimum of 108MHz.
73 + */
74 + hsm_rate = max_t(unsigned long, 108000000, (pixel_rate / 100) * 108);
75 + ret = clk_set_rate(vc4_hdmi->hsm_clock, hsm_rate);
76 + if (ret) {
77 + DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
78 + return;
79 + }
80 +
81 + ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
82 + if (ret) {
83 + DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
84 + clk_disable_unprepare(vc4_hdmi->pixel_clock);
85 + return;
86 + }
87 +
88 if (vc4_hdmi->variant->reset)
89 vc4_hdmi->variant->reset(vc4_hdmi);
90
91 @@ -578,7 +596,9 @@ vc4_hdmi_encoder_mode_valid(struct drm_e
92 * Additionally, the AXI clock needs to be at least 25% of
93 * pixel clock, but HSM ends up being the limiting factor.
94 */
95 - if (mode->clock > HSM_CLOCK_FREQ / (1000 * 101 / 100))
96 + struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
97 +
98 + if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock)
99 return MODE_CLOCK_HIGH;
100
101 return MODE_OK;
102 @@ -1354,23 +1374,6 @@ static int vc4_hdmi_bind(struct device *
103 return -EPROBE_DEFER;
104 }
105
106 - /* This is the rate that is set by the firmware. The number
107 - * needs to be a bit higher than the pixel clock rate
108 - * (generally 148.5Mhz).
109 - */
110 - ret = clk_set_rate(vc4_hdmi->hsm_clock, HSM_CLOCK_FREQ);
111 - if (ret) {
112 - DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
113 - goto err_put_i2c;
114 - }
115 -
116 - ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
117 - if (ret) {
118 - DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
119 - ret);
120 - goto err_put_i2c;
121 - }
122 -
123 /* Only use the GPIO HPD pin if present in the DT, otherwise
124 * we'll use the HDMI core's register.
125 */
126 @@ -1428,9 +1431,7 @@ err_destroy_conn:
127 err_destroy_encoder:
128 vc4_hdmi_encoder_destroy(encoder);
129 err_unprepare_hsm:
130 - clk_disable_unprepare(vc4_hdmi->hsm_clock);
131 pm_runtime_disable(dev);
132 -err_put_i2c:
133 put_device(&vc4_hdmi->ddc->dev);
134
135 return ret;
136 @@ -1453,7 +1454,6 @@ static void vc4_hdmi_unbind(struct devic
137 vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
138 vc4_hdmi_encoder_destroy(&vc4_hdmi->encoder.base.base);
139
140 - clk_disable_unprepare(vc4_hdmi->hsm_clock);
141 pm_runtime_disable(dev);
142
143 put_device(&vc4_hdmi->ddc->dev);
144 @@ -1476,6 +1476,7 @@ static int vc4_hdmi_dev_remove(struct pl
145 }
146
147 static const struct vc4_hdmi_variant bcm2835_variant = {
148 + .max_pixel_clock = 148500000,
149 .audio_available = true,
150 .cec_available = true,
151 .registers = vc4_hdmi_fields,
152 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
153 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
154 @@ -38,6 +38,9 @@ struct vc4_hdmi_variant {
155 /* Set to true when the CEC support is available */
156 bool cec_available;
157
158 + /* Maximum pixel clock supported by the controller (in Hz) */
159 + unsigned long long max_pixel_clock;
160 +
161 /* List of the registers available on that variant */
162 const struct vc4_hdmi_register *registers;
163