d8522d4ffa0a12062bad9021d2c928252f146aba
[openwrt/staging/ldir.git] /
1 From 1f8c105adca8bcd42256602e3ef9c1dbd0715e37 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Thu, 24 Mar 2022 11:57:57 +0100
4 Subject: [PATCH] drm/vc4: hdmi: Rework hdmi_enable_4kp60 detection
5 code
6
7 In order to support higher HDMI frequencies, users have to set the
8 hdmi_enable_4kp60 parameter in their config.txt file.
9
10 This will have the side-effect of raising the maximum of the core clock,
11 tied to the HVS, and managed by the HVS driver.
12
13 However, we are querying this in the HDMI driver by poking into the HVS
14 structure to get our struct clk handle.
15
16 Let's make this part of the HVS bind implementation to have all the core
17 clock related setup in the same place.
18
19 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
20 ---
21 drivers/gpu/drm/vc4/vc4_drv.h | 10 ++++++++++
22 drivers/gpu/drm/vc4/vc4_hdmi.c | 15 ++++-----------
23 drivers/gpu/drm/vc4/vc4_hdmi.h | 8 --------
24 drivers/gpu/drm/vc4/vc4_hvs.c | 23 +++++++++++++++++++++++
25 4 files changed, 37 insertions(+), 19 deletions(-)
26
27 --- a/drivers/gpu/drm/vc4/vc4_drv.h
28 +++ b/drivers/gpu/drm/vc4/vc4_drv.h
29 @@ -331,6 +331,8 @@ struct vc4_hvs {
30
31 struct clk *core_clk;
32
33 + unsigned long max_core_rate;
34 +
35 /* Memory manager for CRTCs to allocate space in the display
36 * list. Units are dwords.
37 */
38 @@ -342,6 +344,14 @@ struct vc4_hvs {
39 struct drm_mm_node mitchell_netravali_filter;
40
41 struct debugfs_regset32 regset;
42 +
43 + /*
44 + * Even if HDMI0 on the RPi4 can output modes requiring a pixel
45 + * rate higher than 297MHz, it needs some adjustments in the
46 + * config.txt file to be able to do so and thus won't always be
47 + * available.
48 + */
49 + bool vc5_hdmi_enable_hdmi_20;
50 };
51
52 struct vc4_plane {
53 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
54 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
55 @@ -46,7 +46,6 @@
56 #include <linux/pm_runtime.h>
57 #include <linux/rational.h>
58 #include <linux/reset.h>
59 -#include <soc/bcm2835/raspberrypi-clocks.h>
60 #include <sound/dmaengine_pcm.h>
61 #include <sound/hdmi-codec.h>
62 #include <sound/pcm_drm_eld.h>
63 @@ -494,6 +493,7 @@ static int vc4_hdmi_connector_detect_ctx
64 static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
65 {
66 struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
67 + struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
68 int ret = 0;
69 struct edid *edid;
70
71 @@ -517,7 +517,7 @@ static int vc4_hdmi_connector_get_modes(
72 ret = drm_add_edid_modes(connector, edid);
73 kfree(edid);
74
75 - if (vc4_hdmi->disable_4kp60) {
76 + if (!vc4->hvs->vc5_hdmi_enable_hdmi_20) {
77 struct drm_device *drm = connector->dev;
78 const struct drm_display_mode *mode;
79
80 @@ -1980,11 +1980,12 @@ vc4_hdmi_encoder_clock_valid(const struc
81 {
82 const struct drm_connector *connector = &vc4_hdmi->connector;
83 const struct drm_display_info *info = &connector->display_info;
84 + struct vc4_dev *vc4 = to_vc4_dev(connector->dev);
85
86 if (clock > vc4_hdmi->variant->max_pixel_clock)
87 return MODE_CLOCK_HIGH;
88
89 - if (vc4_hdmi->disable_4kp60 && clock > HDMI_14_MAX_TMDS_CLK)
90 + if (!vc4->hvs->vc5_hdmi_enable_hdmi_20 && clock > HDMI_14_MAX_TMDS_CLK)
91 return MODE_CLOCK_HIGH;
92
93 if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
94 @@ -3696,14 +3697,6 @@ static int vc4_hdmi_bind(struct device *
95 vc4_hdmi->disable_wifi_frequencies =
96 of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
97
98 - if (variant->max_pixel_clock == 600000000) {
99 - struct vc4_dev *vc4 = to_vc4_dev(drm);
100 - unsigned int max_rate = rpi_firmware_clk_get_max_rate(vc4->hvs->core_clk);
101 -
102 - if (max_rate < 550000000)
103 - vc4_hdmi->disable_4kp60 = true;
104 - }
105 -
106 ret = devm_pm_runtime_enable(dev);
107 if (ret)
108 return ret;
109 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
110 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
111 @@ -158,14 +158,6 @@ struct vc4_hdmi {
112 */
113 bool disable_wifi_frequencies;
114
115 - /*
116 - * Even if HDMI0 on the RPi4 can output modes requiring a pixel
117 - * rate higher than 297MHz, it needs some adjustments in the
118 - * config.txt file to be able to do so and thus won't always be
119 - * available.
120 - */
121 - bool disable_4kp60;
122 -
123 struct cec_adapter *cec_adap;
124 struct cec_msg cec_rx_msg;
125 bool cec_tx_ok;
126 --- a/drivers/gpu/drm/vc4/vc4_hvs.c
127 +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
128 @@ -28,6 +28,8 @@
129 #include <drm/drm_drv.h>
130 #include <drm/drm_vblank.h>
131
132 +#include <soc/bcm2835/raspberrypi-firmware.h>
133 +
134 #include "vc4_drv.h"
135 #include "vc4_regs.h"
136
137 @@ -1033,12 +1035,33 @@ static int vc4_hvs_bind(struct device *d
138 hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
139
140 if (vc4->is_vc5) {
141 + struct rpi_firmware *firmware;
142 + struct device_node *node;
143 + unsigned int max_rate;
144 +
145 + node = rpi_firmware_find_node();
146 + if (!node)
147 + return -EINVAL;
148 +
149 + firmware = rpi_firmware_get(node);
150 + of_node_put(node);
151 + if (!firmware)
152 + return -EPROBE_DEFER;
153 +
154 hvs->core_clk = devm_clk_get(&pdev->dev, NULL);
155 if (IS_ERR(hvs->core_clk)) {
156 dev_err(&pdev->dev, "Couldn't get core clock\n");
157 return PTR_ERR(hvs->core_clk);
158 }
159
160 + max_rate = rpi_firmware_clk_get_max_rate(firmware,
161 + RPI_FIRMWARE_CORE_CLK_ID);
162 + rpi_firmware_put(firmware);
163 + if (max_rate >= 550000000)
164 + hvs->vc5_hdmi_enable_hdmi_20 = true;
165 +
166 + hvs->max_core_rate = max_rate;
167 +
168 ret = clk_prepare_enable(hvs->core_clk);
169 if (ret) {
170 dev_err(&pdev->dev, "Couldn't enable the core clock\n");