e906ad80272e44430b486c7c6312fc29024c0fc6
[openwrt/staging/linusw.git] /
1 From e596d70725ca70113d39d9366d7b4d3e492f6449 Mon Sep 17 00:00:00 2001
2 From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
3 Date: Wed, 31 Jul 2024 19:05:29 +0100
4 Subject: [PATCH 1233/1350] drivers: drm: rp1-dsi: Implement more DSI options
5 and flags
6
7 Now implementing:
8 - Per-command selection of LP or HS for commands (previously LP)
9 - EoTp transmission option (previously EoTp was always disabled)
10 - Non-continuous clock option (previously always continuous)
11 - Per-command enabling of ACK request (in command mode only)
12
13 Make a plausible (and possibly correct) attempt to measure the
14 longest LP command that will fit into vertical blanking lines.
15
16 DON'T set both "Burst Mode" and "Sync Events" flags together.
17 This is redundant in the standard IP; in this RP1 variant it
18 would enable Sync Pulses but may break with some video timings.
19
20 Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
21 ---
22 drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c | 5 +-
23 drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h | 3 +-
24 drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c | 106 +++++++++++++++++-----
25 3 files changed, 91 insertions(+), 23 deletions(-)
26
27 --- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
28 +++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
29 @@ -396,7 +396,10 @@ ssize_t rp1dsi_host_transfer(struct mipi
30 return ret;
31 }
32
33 - rp1dsi_dsi_send(dsi, *(u32 *)(&packet.header), packet.payload_length, packet.payload);
34 + rp1dsi_dsi_send(dsi, *(u32 *)(&packet.header),
35 + packet.payload_length, packet.payload,
36 + !!(msg->flags & MIPI_DSI_MSG_USE_LPM),
37 + !!(msg->flags & MIPI_DSI_MSG_REQ_ACK));
38
39 /* Optional read back */
40 if (msg->rx_len && msg->rx_buf)
41 --- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h
42 +++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h
43 @@ -86,7 +86,8 @@ void rp1dsi_mipicfg_setup(struct rp1_dsi
44 /* Functions to control the SNPS D-PHY and DSI block setup */
45
46 void rp1dsi_dsi_setup(struct rp1_dsi *dsi, struct drm_display_mode const *mode);
47 -void rp1dsi_dsi_send(struct rp1_dsi *dsi, u32 header, int len, const u8 *buf);
48 +void rp1dsi_dsi_send(struct rp1_dsi *dsi, u32 header, int len, const u8 *buf,
49 + bool use_lpm, bool req_ack);
50 int rp1dsi_dsi_recv(struct rp1_dsi *dsi, int len, u8 *buf);
51 void rp1dsi_dsi_set_cmdmode(struct rp1_dsi *dsi, int cmd_mode);
52 void rp1dsi_dsi_stop(struct rp1_dsi *dsi);
53 --- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c
54 +++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c
55 @@ -103,6 +103,24 @@
56
57 /* And some bitfield definitions */
58
59 +#define DSI_PCKHDL_EOTP_TX_EN BIT(0)
60 +#define DSI_PCKHDL_BTA_EN BIT(2)
61 +
62 +#define DSI_VID_MODE_LP_CMD_EN BIT(15)
63 +#define DSI_VID_MODE_FRAME_BTA_ACK_EN BIT(14)
64 +#define DSI_VID_MODE_LP_HFP_EN BIT(13)
65 +#define DSI_VID_MODE_LP_HBP_EN BIT(12)
66 +#define DSI_VID_MODE_LP_VACT_EN BIT(11)
67 +#define DSI_VID_MODE_LP_VFP_EN BIT(10)
68 +#define DSI_VID_MODE_LP_VBP_EN BIT(9)
69 +#define DSI_VID_MODE_LP_VSA_EN BIT(8)
70 +#define DSI_VID_MODE_SYNC_PULSES 0
71 +#define DSI_VID_MODE_SYNC_EVENTS 1
72 +#define DSI_VID_MODE_BURST 2
73 +
74 +#define DSI_CMD_MODE_ALL_LP 0x10f7f00
75 +#define DSI_CMD_MODE_ACK_RQST_EN BIT(1)
76 +
77 #define DPHY_PWR_UP_SHUTDOWNZ_LSB 0
78 #define DPHY_PWR_UP_SHUTDOWNZ_BITS BIT(DPHY_PWR_UP_SHUTDOWNZ_LSB)
79
80 @@ -1252,8 +1270,8 @@ static u32 dphy_configure_pll(struct rp1
81 vco_freq, actual_vco_freq, m, refclk, n,
82 hsfreq_table[dsi->hsfreq_index].hsfreqrange);
83 } else {
84 - drm_warn(dsi->drm,
85 - "rp1dsi: Error configuring DPHY PLL %uHz\n", vco_freq);
86 + drm_err(dsi->drm,
87 + "rp1dsi: Error configuring DPHY PLL %uHz\n", vco_freq);
88 }
89
90 return actual_vco_freq;
91 @@ -1321,7 +1339,7 @@ static void rp1dsi_dpiclk_start(struct r
92 clk_set_rate(dsi->clocks[RP1DSI_CLOCK_DPI], (4 * lanes * byte_clock) / (bpp >> 1));
93 clk_prepare_enable(dsi->clocks[RP1DSI_CLOCK_DPI]);
94 drm_info(dsi->drm,
95 - "rp1dsi: Nominal Byte clock %u DPI clock %lu (parent rate %lu)",
96 + "rp1dsi: Nominal Byte clock %u DPI clock %lu (parent rate %lu)\n",
97 byte_clock,
98 clk_get_rate(dsi->clocks[RP1DSI_CLOCK_DPI]),
99 clk_get_rate(clk_get_parent(dsi->clocks[RP1DSI_CLOCK_DPI])));
100 @@ -1365,7 +1383,8 @@ static u32 get_colorcode(enum mipi_dsi_p
101
102 void rp1dsi_dsi_setup(struct rp1_dsi *dsi, struct drm_display_mode const *mode)
103 {
104 - u32 timeout, mask, vid_mode_cfg;
105 + int cmdtim;
106 + u32 timeout, mask, clkdiv;
107 unsigned int bpp = mipi_dsi_pixel_format_to_bpp(dsi->display_format);
108 u32 byte_clock = clamp((bpp * 125 * min(mode->clock, RP1DSI_DPI_MAX_KHZ)) / dsi->lanes,
109 RP1DSI_BYTE_CLK_MIN, RP1DSI_BYTE_CLK_MAX);
110 @@ -1374,19 +1393,31 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
111 DSI_WRITE(DSI_DPI_CFG_POL, 0);
112 DSI_WRITE(DSI_GEN_VCID, dsi->vc);
113 DSI_WRITE(DSI_DPI_COLOR_CODING, get_colorcode(dsi->display_format));
114 - /* a conservative guess (LP escape is slow!) */
115 - DSI_WRITE(DSI_DPI_LP_CMD_TIM, 0x00100000);
116
117 - /* Drop to LP where possible; use LP Escape for all commands */
118 - vid_mode_cfg = 0xbf00;
119 - if (!(dsi->display_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
120 - vid_mode_cfg |= 0x01;
121 - else if (8 * dsi->lanes > bpp)
122 - vid_mode_cfg &= ~0x400; /* PULSE && inexact DPICLK => fix HBP time */
123 + /*
124 + * Flags to configure use of LP, EoTp, Burst Mode, Sync Events/Pulses.
125 + * Note that Burst Mode implies Sync Events; the two flags need not be
126 + * set concurrently, and in this RP1 variant *should not* both be set:
127 + * doing so would (counter-intuitively) enable Sync Pulses and may fail
128 + * if there is not sufficient time to return to LP11 state during HBP.
129 + */
130 + mask = DSI_VID_MODE_LP_HFP_EN | DSI_VID_MODE_LP_HBP_EN |
131 + DSI_VID_MODE_LP_VACT_EN | DSI_VID_MODE_LP_VFP_EN |
132 + DSI_VID_MODE_LP_VBP_EN | DSI_VID_MODE_LP_VSA_EN;
133 + if (dsi->display_flags & MIPI_DSI_MODE_LPM)
134 + mask |= DSI_VID_MODE_LP_CMD_EN;
135 if (dsi->display_flags & MIPI_DSI_MODE_VIDEO_BURST)
136 - vid_mode_cfg |= 0x02;
137 - DSI_WRITE(DSI_VID_MODE_CFG, vid_mode_cfg);
138 - DSI_WRITE(DSI_CMD_MODE_CFG, 0x10F7F00);
139 + mask |= DSI_VID_MODE_BURST;
140 + else if (!(dsi->display_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
141 + mask |= DSI_VID_MODE_SYNC_EVENTS;
142 + else if (8 * dsi->lanes > bpp)
143 + mask &= ~DSI_VID_MODE_LP_HBP_EN; /* PULSE && inexact DPICLK => fix HBP time */
144 + DSI_WRITE(DSI_VID_MODE_CFG, mask);
145 + DSI_WRITE(DSI_CMD_MODE_CFG,
146 + (dsi->display_flags & MIPI_DSI_MODE_LPM) ? DSI_CMD_MODE_ALL_LP : 0);
147 + DSI_WRITE(DSI_PCKHDL_CFG,
148 + DSI_PCKHDL_BTA_EN |
149 + ((dsi->display_flags & MIPI_DSI_MODE_NO_EOT_PACKET) ? 0 : DSI_PCKHDL_EOTP_TX_EN));
150
151 /* Select Command Mode */
152 DSI_WRITE(DSI_MODE_CFG, 1);
153 @@ -1397,9 +1428,9 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
154 timeout = 0;
155 DSI_WRITE(DSI_TO_CNT_CFG, (timeout << 16) | RP1DSI_LPRX_TO_VAL);
156 DSI_WRITE(DSI_BTA_TO_CNT, RP1DSI_BTA_TO_VAL);
157 + clkdiv = max(2u, 1u + byte_clock / RP1DSI_ESC_CLK_MAX); /* byte clocks per escape clock */
158 DSI_WRITE(DSI_CLKMGR_CFG,
159 - (RP1DSI_TO_CLK_DIV << 8) |
160 - max(2u, 1u + byte_clock / RP1DSI_ESC_CLK_MAX));
161 + (RP1DSI_TO_CLK_DIV << 8) | clkdiv);
162
163 /* Configure video timings */
164 DSI_WRITE(DSI_VID_PKT_SIZE, mode->hdisplay);
165 @@ -1425,6 +1456,18 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
166 (hsfreq_table[dsi->hsfreq_index].data_lp2hs << DSI_PHY_TMR_LP2HS_LSB) |
167 (hsfreq_table[dsi->hsfreq_index].data_hs2lp << DSI_PHY_TMR_HS2LP_LSB));
168
169 + /* Estimate how many LP bytes can be sent during vertical blanking (Databook 3.6.2.1) */
170 + cmdtim = mode->htotal;
171 + if (dsi->display_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
172 + cmdtim -= mode->hsync_end - mode->hsync_start;
173 + cmdtim = (bpp * cmdtim - 64) / (8 * dsi->lanes); /* byte clocks after HSS and EoTp */
174 + cmdtim -= hsfreq_table[dsi->hsfreq_index].data_hs2lp;
175 + cmdtim -= hsfreq_table[dsi->hsfreq_index].data_lp2hs;
176 + cmdtim = (cmdtim / clkdiv) - 24; /* escape clocks for commands */
177 + cmdtim = max(0, cmdtim >> 4); /* bytes (at 2 clocks per bit) */
178 + drm_info(dsi->drm, "rp1dsi: Command time (outvact): %d\n", cmdtim);
179 + DSI_WRITE(DSI_DPI_LP_CMD_TIM, cmdtim << 16);
180 +
181 /* Wait for PLL lock */
182 for (timeout = (1 << 14); timeout != 0; --timeout) {
183 usleep_range(10, 50);
184 @@ -1434,9 +1477,9 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
185 if (timeout == 0)
186 drm_err(dsi->drm, "RP1DSI: Time out waiting for PLL\n");
187
188 - DSI_WRITE(DSI_LPCLK_CTRL, 0x1); /* configure the requesthsclk */
189 + DSI_WRITE(DSI_LPCLK_CTRL,
190 + (dsi->display_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0x3 : 0x1);
191 DSI_WRITE(DSI_PHY_TST_CTRL0, 0x2);
192 - DSI_WRITE(DSI_PCKHDL_CFG, 1 << 2); /* allow bus turnaround */
193 DSI_WRITE(DSI_PWR_UP, 0x1); /* power up */
194
195 /* Now it should be safe to start the external DPI clock divider */
196 @@ -1460,7 +1503,8 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
197 mask, DSI_READ(DSI_PHY_STATUS));
198 }
199
200 -void rp1dsi_dsi_send(struct rp1_dsi *dsi, u32 hdr, int len, const u8 *buf)
201 +void rp1dsi_dsi_send(struct rp1_dsi *dsi, u32 hdr, int len, const u8 *buf,
202 + bool use_lpm, bool req_ack)
203 {
204 u32 val;
205
206 @@ -1471,6 +1515,24 @@ void rp1dsi_dsi_send(struct rp1_dsi *dsi
207 usleep_range(100, 150);
208 }
209
210 + /*
211 + * Update global configuration flags for LP/HS and ACK options.
212 + * XXX It's not clear if having empty FIFOs (checked above and below) guarantees that
213 + * the last command has completed and been ACKed, or how closely these control registers
214 + * align with command/payload FIFO writes (as each is an independent clock-crossing)?
215 + */
216 + val = DSI_READ(DSI_VID_MODE_CFG);
217 + if (use_lpm)
218 + val |= DSI_VID_MODE_LP_CMD_EN;
219 + else
220 + val &= ~DSI_VID_MODE_LP_CMD_EN;
221 + DSI_WRITE(DSI_VID_MODE_CFG, val);
222 + val = (use_lpm) ? DSI_CMD_MODE_ALL_LP : 0;
223 + if (req_ack)
224 + val |= DSI_CMD_MODE_ACK_RQST_EN;
225 + DSI_WRITE(DSI_CMD_MODE_CFG, val);
226 + (void)DSI_READ(DSI_CMD_MODE_CFG);
227 +
228 /* Write payload (in 32-bit words) and header */
229 for (; len > 0; len -= 4) {
230 val = *buf++;
231 @@ -1504,8 +1566,10 @@ int rp1dsi_dsi_recv(struct rp1_dsi *dsi,
232 break;
233 usleep_range(100, 150);
234 }
235 - if (i == 0)
236 + if (!i) {
237 + drm_warn(dsi->drm, "Receive failed\n");
238 return -EIO;
239 + }
240
241 for (i = 0; i < len; i += 4) {
242 /* Read fifo must not be empty before all bytes are read */