]> git.ipfire.org Git - thirdparty/openwrt.git/blob
a80af9839dd7eb1c45e2a238afb405206bb7f3ac
[thirdparty/openwrt.git] /
1 From f5de8d46da4b40f2180be502c1e547fe8c9b2ac2 Mon Sep 17 00:00:00 2001
2 From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
3 Date: Fri, 10 May 2024 15:48:15 +0100
4 Subject: [PATCH 1179/1215] drm: rp1: rp1-dsi: Switch to PLL_SYS source for DPI
5 when 8 * lanes > bpp
6
7 To support 4 lanes, re-parent DPI clock source between DSI byteclock
8 (using the new "variable sources" defined in clk-rp1) and PLL_SYS.
9 This is to cover cases in which byteclock < pixclock <= 200MHz.
10
11 Tidying: All frequencies now in Hz (not kHz), where DSI speed is now
12 represented by byteclock to simplify arithmetic. Clamp DPI and byte
13 clocks to their legal ranges; fix up HSTX timeout to avoid an unsafe
14 assumption that it would return to LP state for every scanline.
15
16 Because of RP1's clock topology, the ratio between DSI and DPI clocks
17 may not be exact with 3 or 4 lanes, leading to slightly irregular
18 timings each time DSI switches between HS and LP states. Tweak to
19 inhibit LP during Horizontal BP when sync pulses were requested.
20
21 Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
22 ---
23 drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c | 3 +-
24 drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h | 3 +-
25 drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c | 130 +++++++++++++---------
26 3 files changed, 80 insertions(+), 56 deletions(-)
27
28 --- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
29 +++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
30 @@ -54,6 +54,7 @@ static void rp1_dsi_bridge_pre_enable(st
31 struct rp1_dsi *dsi = bridge_to_rp1_dsi(bridge);
32
33 rp1dsi_dsi_setup(dsi, &dsi->pipe.crtc.state->adjusted_mode);
34 + dsi->dsi_running = true;
35 }
36
37 static void rp1_dsi_bridge_enable(struct drm_bridge *bridge,
38 @@ -443,7 +444,7 @@ static int rp1dsi_platform_probe(struct
39 /* Hardware resources */
40 for (i = 0; i < RP1DSI_NUM_CLOCKS; i++) {
41 static const char * const myclocknames[RP1DSI_NUM_CLOCKS] = {
42 - "cfgclk", "dpiclk", "byteclk", "refclk"
43 + "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys"
44 };
45 dsi->clocks[i] = devm_clk_get(dev, myclocknames[i]);
46 if (IS_ERR(dsi->clocks[i])) {
47 --- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h
48 +++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h
49 @@ -30,7 +30,8 @@
50 #define RP1DSI_CLOCK_DPI 1
51 #define RP1DSI_CLOCK_BYTE 2
52 #define RP1DSI_CLOCK_REF 3
53 -#define RP1DSI_NUM_CLOCKS 4
54 +#define RP1DSI_CLOCK_PLLSYS 4
55 +#define RP1DSI_NUM_CLOCKS 5
56
57 /* ---------------------------------------------------------------------- */
58
59 --- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c
60 +++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c
61 @@ -7,6 +7,7 @@
62
63 #include <linux/delay.h>
64 #include <linux/errno.h>
65 +#include <linux/math64.h>
66 #include <linux/platform_device.h>
67 #include <linux/rp1_platform.h>
68 #include "drm/drm_print.h"
69 @@ -1111,7 +1112,7 @@ static void dphy_transaction(struct rp1_
70 DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
71 }
72
73 -static uint8_t dphy_get_div(u32 refclk_khz, u32 vco_freq_khz, u32 *ptr_m, u32 *ptr_n)
74 +static u64 dphy_get_div(u32 refclk, u64 vco_freq, u32 *ptr_m, u32 *ptr_n)
75 {
76 /*
77 * See pg 77-78 of dphy databook
78 @@ -1124,19 +1125,23 @@ static uint8_t dphy_get_div(u32 refclk_k
79 * In practice, given a 50MHz reference clock, it can produce any
80 * multiple of 10MHz, 11.1111MHz, 12.5MHz, 14.286MHz or 16.667MHz
81 * with < 1% error for all frequencies above 495MHz.
82 + *
83 + * vco_freq should be set to the lane bit rate (not the MIPI clock
84 + * which is half of this). These frequencies are now measured in Hz.
85 + * They should fit within u32, but u64 is needed for calculations.
86 */
87
88 - static const u32 REF_DIVN_MAX = 40000u;
89 - static const u32 REF_DIVN_MIN = 5000u;
90 - u32 best_n, best_m, best_err = 0x7fffffff;
91 - unsigned int n;
92 + static const u32 REF_DIVN_MAX = 40000000;
93 + static const u32 REF_DIVN_MIN = 5000000;
94 + u32 n, best_n, best_m;
95 + u64 best_err = vco_freq;
96
97 - for (n = 1 + refclk_khz / REF_DIVN_MAX; n * REF_DIVN_MIN <= refclk_khz && n < 100; ++n) {
98 - u32 half_m = (n * vco_freq_khz + refclk_khz) / (2 * refclk_khz);
99 + for (n = 1 + refclk / REF_DIVN_MAX; n * REF_DIVN_MIN <= refclk && n < 100; ++n) {
100 + u32 half_m = DIV_U64_ROUND_CLOSEST(n * vco_freq, 2 * refclk);
101
102 if (half_m < 150) {
103 - u32 f = (2 * half_m * refclk_khz) / n;
104 - u32 err = (f > vco_freq_khz) ? f - vco_freq_khz : vco_freq_khz - f;
105 + u64 f = div_u64(mul_u32_u32(2 * half_m, refclk), n);
106 + u64 err = (f > vco_freq) ? f - vco_freq : vco_freq - f;
107
108 if (err < best_err) {
109 best_n = n;
110 @@ -1148,12 +1153,12 @@ static uint8_t dphy_get_div(u32 refclk_k
111 }
112 }
113
114 - if (64 * best_err < vco_freq_khz) { /* tolerate small error */
115 - *ptr_n = best_n;
116 - *ptr_m = best_m;
117 - return 1;
118 - }
119 - return 0;
120 + if (64 * best_err >= vco_freq)
121 + return 0;
122 +
123 + *ptr_n = best_n;
124 + *ptr_m = best_m;
125 + return div_u64(mul_u32_u32(best_m, refclk), best_n);
126 }
127
128 struct hsfreq_range {
129 @@ -1226,13 +1231,14 @@ static void dphy_set_hsfreqrange(struct
130 hsfreq_table[i].hsfreqrange << 1);
131 }
132
133 -static void dphy_configure_pll(struct rp1_dsi *dsi, u32 refclk_khz, u32 vco_freq_khz)
134 +static u32 dphy_configure_pll(struct rp1_dsi *dsi, u32 refclk, u32 vco_freq)
135 {
136 u32 m = 0;
137 u32 n = 0;
138 + u32 actual_vco_freq = dphy_get_div(refclk, vco_freq, &m, &n);
139
140 - if (dphy_get_div(refclk_khz, vco_freq_khz, &m, &n)) {
141 - dphy_set_hsfreqrange(dsi, vco_freq_khz / 1000);
142 + if (actual_vco_freq) {
143 + dphy_set_hsfreqrange(dsi, actual_vco_freq / 1000000);
144 /* Program m,n from registers */
145 dphy_transaction(dsi, DPHY_PLL_DIV_CTRL_OFFSET, 0x30);
146 /* N (program N-1) */
147 @@ -1242,18 +1248,21 @@ static void dphy_configure_pll(struct rp
148 /* M[4:0] (program M-1) */
149 dphy_transaction(dsi, DPHY_PLL_LOOP_DIV_OFFSET, ((m - 1) & 0x1F));
150 drm_dbg_driver(dsi->drm,
151 - "DPHY: vco freq want %dkHz got %dkHz = %d * (%dkHz / %d), hsfreqrange = 0x%02x\r\n",
152 - vco_freq_khz, refclk_khz * m / n, m, refclk_khz,
153 - n, hsfreq_table[dsi->hsfreq_index].hsfreqrange);
154 + "DPHY: vco freq want %uHz got %uHz = %d * (%uHz / %d), hsfreqrange = 0x%02x\n",
155 + vco_freq, actual_vco_freq, m, refclk, n,
156 + hsfreq_table[dsi->hsfreq_index].hsfreqrange);
157 } else {
158 - drm_info(dsi->drm,
159 - "rp1dsi: Error configuring DPHY PLL! %dkHz = %d * (%dkHz / %d)\r\n",
160 - vco_freq_khz, m, refclk_khz, n);
161 + drm_warn(dsi->drm,
162 + "rp1dsi: Error configuring DPHY PLL %uHz\n", vco_freq);
163 }
164 +
165 + return actual_vco_freq;
166 }
167
168 -static void dphy_init_khz(struct rp1_dsi *dsi, u32 ref_freq, u32 vco_freq)
169 +static u32 dphy_init(struct rp1_dsi *dsi, u32 ref_freq, u32 vco_freq)
170 {
171 + u32 actual_vco_freq;
172 +
173 /* Reset the PHY */
174 DSI_WRITE(DSI_PHYRSTZ, 0);
175 DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
176 @@ -1263,13 +1272,15 @@ static void dphy_init_khz(struct rp1_dsi
177 DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
178 udelay(1);
179 /* Since we are in DSI (not CSI2) mode here, start the PLL */
180 - dphy_configure_pll(dsi, ref_freq, vco_freq);
181 + actual_vco_freq = dphy_configure_pll(dsi, ref_freq, vco_freq);
182 udelay(1);
183 /* Unreset */
184 DSI_WRITE(DSI_PHYRSTZ, DSI_PHYRSTZ_SHUTDOWNZ_BITS);
185 udelay(1);
186 DSI_WRITE(DSI_PHYRSTZ, (DSI_PHYRSTZ_SHUTDOWNZ_BITS | DSI_PHYRSTZ_RSTZ_BITS));
187 udelay(1); /* so we can see PLL coming up? */
188 +
189 + return actual_vco_freq;
190 }
191
192 void rp1dsi_mipicfg_setup(struct rp1_dsi *dsi)
193 @@ -1290,23 +1301,30 @@ static unsigned long rp1dsi_refclk_freq(
194 return u;
195 }
196
197 -static void rp1dsi_dpiclk_start(struct rp1_dsi *dsi, unsigned int bpp, unsigned int lanes)
198 +static void rp1dsi_dpiclk_start(struct rp1_dsi *dsi, u32 byte_clock,
199 + unsigned int bpp, unsigned int lanes)
200 {
201 - unsigned long u;
202 -
203 - if (dsi->clocks[RP1DSI_CLOCK_DPI]) {
204 - u = (dsi->clocks[RP1DSI_CLOCK_BYTE]) ?
205 - clk_get_rate(dsi->clocks[RP1DSI_CLOCK_BYTE]) : 0;
206 - drm_info(dsi->drm,
207 - "rp1dsi: Nominal byte clock %lu; scale by %u/%u",
208 - u, 4 * lanes, (bpp >> 1));
209 - if (u < 1 || u >= (1ul << 28))
210 - u = 72000000ul; /* default DUMMY frequency for byteclock */
211 + /* Dummy clk_set_rate() to declare the actual DSI byte-clock rate */
212 + clk_set_rate(dsi->clocks[RP1DSI_CLOCK_BYTE], byte_clock);
213
214 + /*
215 + * Prefer the DSI byte-clock source where possible, so that DSI and DPI
216 + * clocks will be in an exact ratio and downstream devices can recover
217 + * perfect timings. But when DPI clock is faster, fall back on PLL_SYS.
218 + * To defeat rounding errors, specify explicitly which source to use.
219 + */
220 + if (bpp >= 8 * lanes)
221 clk_set_parent(dsi->clocks[RP1DSI_CLOCK_DPI], dsi->clocks[RP1DSI_CLOCK_BYTE]);
222 - clk_set_rate(dsi->clocks[RP1DSI_CLOCK_DPI], (4 * lanes * u) / (bpp >> 1));
223 - clk_prepare_enable(dsi->clocks[RP1DSI_CLOCK_DPI]);
224 - }
225 + else if (dsi->clocks[RP1DSI_CLOCK_PLLSYS])
226 + clk_set_parent(dsi->clocks[RP1DSI_CLOCK_DPI], dsi->clocks[RP1DSI_CLOCK_PLLSYS]);
227 +
228 + clk_set_rate(dsi->clocks[RP1DSI_CLOCK_DPI], (4 * lanes * byte_clock) / (bpp >> 1));
229 + clk_prepare_enable(dsi->clocks[RP1DSI_CLOCK_DPI]);
230 + drm_info(dsi->drm,
231 + "rp1dsi: Nominal Byte clock %u DPI clock %lu (parent rate %lu)",
232 + byte_clock,
233 + clk_get_rate(dsi->clocks[RP1DSI_CLOCK_DPI]),
234 + clk_get_rate(clk_get_parent(dsi->clocks[RP1DSI_CLOCK_DPI])));
235 }
236
237 static void rp1dsi_dpiclk_stop(struct rp1_dsi *dsi)
238 @@ -1336,18 +1354,21 @@ static u32 get_colorcode(enum mipi_dsi_p
239 return 0x005;
240 }
241
242 -/* Maximum frequency for LP escape clock (20MHz), and some magic numbers */
243 -#define RP1DSI_ESC_CLK_KHZ 20000
244 -#define RP1DSI_TO_CLK_DIV 5
245 -#define RP1DSI_HSTX_TO_MIN 0x200
246 -#define RP1DSI_LPRX_TO_VAL 0x400
247 +/* Frequency limits for DPI, HS and LP clocks, and some magic numbers */
248 +#define RP1DSI_DPI_MAX_KHZ 200000
249 +#define RP1DSI_BYTE_CLK_MIN 10000000
250 +#define RP1DSI_BYTE_CLK_MAX 187500000
251 +#define RP1DSI_ESC_CLK_MAX 20000000
252 +#define RP1DSI_TO_CLK_DIV 0x50
253 +#define RP1DSI_LPRX_TO_VAL 0x40
254 #define RP1DSI_BTA_TO_VAL 0xd00
255
256 void rp1dsi_dsi_setup(struct rp1_dsi *dsi, struct drm_display_mode const *mode)
257 {
258 u32 timeout, mask, vid_mode_cfg;
259 - int lane_kbps;
260 unsigned int bpp = mipi_dsi_pixel_format_to_bpp(dsi->display_format);
261 + u32 byte_clock = clamp((bpp * 125 * min(mode->clock, RP1DSI_DPI_MAX_KHZ)) / dsi->lanes,
262 + RP1DSI_BYTE_CLK_MIN, RP1DSI_BYTE_CLK_MAX);
263
264 DSI_WRITE(DSI_PHY_IF_CFG, dsi->lanes - 1);
265 DSI_WRITE(DSI_DPI_CFG_POL, 0);
266 @@ -1360,6 +1381,8 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
267 vid_mode_cfg = 0xbf00;
268 if (!(dsi->display_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
269 vid_mode_cfg |= 0x01;
270 + else if (8 * dsi->lanes > bpp)
271 + vid_mode_cfg &= ~0x400; /* PULSE && inexact DPICLK => fix HBP time */
272 if (dsi->display_flags & MIPI_DSI_MODE_VIDEO_BURST)
273 vid_mode_cfg |= 0x02;
274 DSI_WRITE(DSI_VID_MODE_CFG, vid_mode_cfg);
275 @@ -1369,15 +1392,14 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
276 DSI_WRITE(DSI_MODE_CFG, 1);
277
278 /* Set timeouts and clock dividers */
279 - DSI_WRITE(DSI_TO_CNT_CFG,
280 - (max((bpp * mode->htotal) / (7 * RP1DSI_TO_CLK_DIV * dsi->lanes),
281 - RP1DSI_HSTX_TO_MIN) << 16) |
282 - RP1DSI_LPRX_TO_VAL);
283 + timeout = (bpp * mode->htotal * mode->vdisplay) / (7 * RP1DSI_TO_CLK_DIV * dsi->lanes);
284 + if (timeout > 0xFFFFu)
285 + timeout = 0;
286 + DSI_WRITE(DSI_TO_CNT_CFG, (timeout << 16) | RP1DSI_LPRX_TO_VAL);
287 DSI_WRITE(DSI_BTA_TO_CNT, RP1DSI_BTA_TO_VAL);
288 - lane_kbps = (bpp * mode->clock) / dsi->lanes;
289 DSI_WRITE(DSI_CLKMGR_CFG,
290 (RP1DSI_TO_CLK_DIV << 8) |
291 - max(2, lane_kbps / (8 * RP1DSI_ESC_CLK_KHZ) + 1));
292 + max(2u, 1u + byte_clock / RP1DSI_ESC_CLK_MAX));
293
294 /* Configure video timings */
295 DSI_WRITE(DSI_VID_PKT_SIZE, mode->hdisplay);
296 @@ -1394,7 +1416,7 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
297 DSI_WRITE(DSI_VID_VACTIVE_LINES, mode->vdisplay);
298
299 /* Init PHY */
300 - dphy_init_khz(dsi, rp1dsi_refclk_freq(dsi) / 1000, lane_kbps);
301 + byte_clock = dphy_init(dsi, rp1dsi_refclk_freq(dsi), 8 * byte_clock) >> 3;
302
303 DSI_WRITE(DSI_PHY_TMR_LPCLK_CFG,
304 (hsfreq_table[dsi->hsfreq_index].clk_lp2hs << DSI_PHY_TMR_LP2HS_LSB) |
305 @@ -1418,7 +1440,7 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
306 DSI_WRITE(DSI_PWR_UP, 0x1); /* power up */
307
308 /* Now it should be safe to start the external DPI clock divider */
309 - rp1dsi_dpiclk_start(dsi, bpp, dsi->lanes);
310 + rp1dsi_dpiclk_start(dsi, byte_clock, bpp, dsi->lanes);
311
312 /* Wait for all lane(s) to be in Stopstate */
313 mask = (1 << 4);