1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright: 2017 Cadence Design Systems, Inc.
4 *
5 * Author: Boris Brezillon <boris.brezillon@bootlin.com>
6 */
7
8#include <drm/drm_atomic_helper.h>
9#include <drm/drm_drv.h>
10#include <drm/drm_probe_helper.h>
11#include <video/mipi_display.h>
12#include <video/videomode.h>
13
14#include <linux/clk.h>
15#include <linux/interrupt.h>
16#include <linux/iopoll.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_graph.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/reset.h>
23
24#include <linux/phy/phy-mipi-dphy.h>
25
26#include "cdns-dsi-core.h"
27#ifdef CONFIG_DRM_CDNS_DSI_J721E
28#include "cdns-dsi-j721e.h"
29#endif
30
31#define IP_CONF 0x0
32#define SP_HS_FIFO_DEPTH(x) (((x) & GENMASK(30, 26)) >> 26)
33#define SP_LP_FIFO_DEPTH(x) (((x) & GENMASK(25, 21)) >> 21)
34#define VRS_FIFO_DEPTH(x) (((x) & GENMASK(20, 16)) >> 16)
35#define DIRCMD_FIFO_DEPTH(x) (((x) & GENMASK(15, 13)) >> 13)
36#define SDI_IFACE_32 BIT(12)
37#define INTERNAL_DATAPATH_32 (0 << 10)
38#define INTERNAL_DATAPATH_16 (1 << 10)
39#define INTERNAL_DATAPATH_8 (3 << 10)
40#define INTERNAL_DATAPATH_SIZE ((x) & GENMASK(11, 10))
41#define NUM_IFACE(x) ((((x) & GENMASK(9, 8)) >> 8) + 1)
42#define MAX_LANE_NB(x) (((x) & GENMASK(7, 6)) >> 6)
43#define RX_FIFO_DEPTH(x) ((x) & GENMASK(5, 0))
44
45#define MCTL_MAIN_DATA_CTL 0x4
46#define TE_MIPI_POLLING_EN BIT(25)
47#define TE_HW_POLLING_EN BIT(24)
48#define DISP_EOT_GEN BIT(18)
49#define HOST_EOT_GEN BIT(17)
50#define DISP_GEN_CHECKSUM BIT(16)
51#define DISP_GEN_ECC BIT(15)
52#define BTA_EN BIT(14)
53#define READ_EN BIT(13)
54#define REG_TE_EN BIT(12)
55#define IF_TE_EN(x) BIT(8 + (x))
56#define TVG_SEL BIT(6)
57#define VID_EN BIT(5)
58#define IF_VID_SELECT(x) ((x) << 2)
59#define IF_VID_SELECT_MASK GENMASK(3, 2)
60#define IF_VID_MODE BIT(1)
61#define LINK_EN BIT(0)
62
63#define MCTL_MAIN_PHY_CTL 0x8
64#define HS_INVERT_DAT(x) BIT(19 + ((x) * 2))
65#define SWAP_PINS_DAT(x) BIT(18 + ((x) * 2))
66#define HS_INVERT_CLK BIT(17)
67#define SWAP_PINS_CLK BIT(16)
68#define HS_SKEWCAL_EN BIT(15)
69#define WAIT_BURST_TIME(x) ((x) << 10)
70#define DATA_ULPM_EN(x) BIT(6 + (x))
71#define CLK_ULPM_EN BIT(5)
72#define CLK_CONTINUOUS BIT(4)
73#define DATA_LANE_EN(x) BIT((x) - 1)
74
75#define MCTL_MAIN_EN 0xc
76#define DATA_FORCE_STOP BIT(17)
77#define CLK_FORCE_STOP BIT(16)
78#define IF_EN(x) BIT(13 + (x))
79#define DATA_LANE_ULPM_REQ(l) BIT(9 + (l))
80#define CLK_LANE_ULPM_REQ BIT(8)
81#define DATA_LANE_START(x) BIT(4 + (x))
82#define CLK_LANE_EN BIT(3)
83#define PLL_START BIT(0)
84
85#define MCTL_DPHY_CFG0 0x10
86#define DPHY_C_RSTB BIT(20)
87#define DPHY_D_RSTB(x) GENMASK(15 + (x), 16)
88#define DPHY_PLL_PDN BIT(10)
89#define DPHY_CMN_PDN BIT(9)
90#define DPHY_C_PDN BIT(8)
91#define DPHY_D_PDN(x) GENMASK(3 + (x), 4)
92#define DPHY_ALL_D_PDN GENMASK(7, 4)
93#define DPHY_PLL_PSO BIT(1)
94#define DPHY_CMN_PSO BIT(0)
95
96#define MCTL_DPHY_TIMEOUT1 0x14
97#define HSTX_TIMEOUT(x) ((x) << 4)
98#define HSTX_TIMEOUT_MAX GENMASK(17, 0)
99#define CLK_DIV(x) (x)
100#define CLK_DIV_MAX GENMASK(3, 0)
101
102#define MCTL_DPHY_TIMEOUT2 0x18
103#define LPRX_TIMEOUT(x) (x)
104
105#define MCTL_ULPOUT_TIME 0x1c
106#define DATA_LANE_ULPOUT_TIME(x) ((x) << 9)
107#define CLK_LANE_ULPOUT_TIME(x) (x)
108
109#define MCTL_3DVIDEO_CTL 0x20
110#define VID_VSYNC_3D_EN BIT(7)
111#define VID_VSYNC_3D_LR BIT(5)
112#define VID_VSYNC_3D_SECOND_EN BIT(4)
113#define VID_VSYNC_3DFORMAT_LINE (0 << 2)
114#define VID_VSYNC_3DFORMAT_FRAME (1 << 2)
115#define VID_VSYNC_3DFORMAT_PIXEL (2 << 2)
116#define VID_VSYNC_3DMODE_OFF 0
117#define VID_VSYNC_3DMODE_PORTRAIT 1
118#define VID_VSYNC_3DMODE_LANDSCAPE 2
119
120#define MCTL_MAIN_STS 0x24
121#define MCTL_MAIN_STS_CTL 0x130
122#define MCTL_MAIN_STS_CLR 0x150
123#define MCTL_MAIN_STS_FLAG 0x170
124#define HS_SKEWCAL_DONE BIT(11)
125#define IF_UNTERM_PKT_ERR(x) BIT(8 + (x))
126#define LPRX_TIMEOUT_ERR BIT(7)
127#define HSTX_TIMEOUT_ERR BIT(6)
128#define DATA_LANE_RDY(l) BIT(2 + (l))
129#define CLK_LANE_RDY BIT(1)
130#define PLL_LOCKED BIT(0)
131
132#define MCTL_DPHY_ERR 0x28
133#define MCTL_DPHY_ERR_CTL1 0x148
134#define MCTL_DPHY_ERR_CLR 0x168
135#define MCTL_DPHY_ERR_FLAG 0x188
136#define ERR_CONT_LP(x, l) BIT(18 + ((x) * 4) + (l))
137#define ERR_CONTROL(l) BIT(14 + (l))
138#define ERR_SYNESC(l) BIT(10 + (l))
139#define ERR_ESC(l) BIT(6 + (l))
140
141#define MCTL_DPHY_ERR_CTL2 0x14c
142#define ERR_CONT_LP_EDGE(x, l) BIT(12 + ((x) * 4) + (l))
143#define ERR_CONTROL_EDGE(l) BIT(8 + (l))
144#define ERR_SYN_ESC_EDGE(l) BIT(4 + (l))
145#define ERR_ESC_EDGE(l) BIT(0 + (l))
146
147#define MCTL_LANE_STS 0x2c
148#define PPI_C_TX_READY_HS BIT(18)
149#define DPHY_PLL_LOCK BIT(17)
150#define PPI_D_RX_ULPS_ESC(x) (((x) & GENMASK(15, 12)) >> 12)
151#define LANE_STATE_START 0
152#define LANE_STATE_IDLE 1
153#define LANE_STATE_WRITE 2
154#define LANE_STATE_ULPM 3
155#define LANE_STATE_READ 4
156#define DATA_LANE_STATE(l, val) \
157 (((val) >> (2 + 2 * (l) + ((l) ? 1 : 0))) & GENMASK((l) ? 1 : 2, 0))
158#define CLK_LANE_STATE_HS 2
159#define CLK_LANE_STATE(val) ((val) & GENMASK(1, 0))
160
161#define DSC_MODE_CTL 0x30
162#define DSC_MODE_EN BIT(0)
163
164#define DSC_CMD_SEND 0x34
165#define DSC_SEND_PPS BIT(0)
166#define DSC_EXECUTE_QUEUE BIT(1)
167
168#define DSC_PPS_WRDAT 0x38
169
170#define DSC_MODE_STS 0x3c
171#define DSC_PPS_DONE BIT(1)
172#define DSC_EXEC_DONE BIT(2)
173
174#define CMD_MODE_CTL 0x70
175#define IF_LP_EN(x) BIT(9 + (x))
176#define IF_VCHAN_ID(x, c) ((c) << ((x) * 2))
177
178#define CMD_MODE_CTL2 0x74
179#define TE_TIMEOUT(x) ((x) << 11)
180#define FILL_VALUE(x) ((x) << 3)
181#define ARB_IF_WITH_HIGHEST_PRIORITY(x) ((x) << 1)
182#define ARB_ROUND_ROBIN_MODE BIT(0)
183
184#define CMD_MODE_STS 0x78
185#define CMD_MODE_STS_CTL 0x134
186#define CMD_MODE_STS_CLR 0x154
187#define CMD_MODE_STS_FLAG 0x174
188#define ERR_IF_UNDERRUN(x) BIT(4 + (x))
189#define ERR_UNWANTED_READ BIT(3)
190#define ERR_TE_MISS BIT(2)
191#define ERR_NO_TE BIT(1)
192#define CSM_RUNNING BIT(0)
193
194#define DIRECT_CMD_SEND 0x80
195
196#define DIRECT_CMD_MAIN_SETTINGS 0x84
197#define TRIGGER_VAL(x) ((x) << 25)
198#define CMD_LP_EN BIT(24)
199#define CMD_SIZE(x) ((x) << 16)
200#define CMD_VCHAN_ID(x) ((x) << 14)
201#define CMD_DATATYPE(x) ((x) << 8)
202#define CMD_LONG BIT(3)
203#define WRITE_CMD 0
204#define READ_CMD 1
205#define TE_REQ 4
206#define TRIGGER_REQ 5
207#define BTA_REQ 6
208
209#define DIRECT_CMD_STS 0x88
210#define DIRECT_CMD_STS_CTL 0x138
211#define DIRECT_CMD_STS_CLR 0x158
212#define DIRECT_CMD_STS_FLAG 0x178
213#define RCVD_ACK_VAL(val) ((val) >> 16)
214#define RCVD_TRIGGER_VAL(val) (((val) & GENMASK(14, 11)) >> 11)
215#define READ_COMPLETED_WITH_ERR BIT(10)
216#define BTA_FINISHED BIT(9)
217#define BTA_COMPLETED BIT(8)
218#define TE_RCVD BIT(7)
219#define TRIGGER_RCVD BIT(6)
220#define ACK_WITH_ERR_RCVD BIT(5)
221#define ACK_RCVD BIT(4)
222#define READ_COMPLETED BIT(3)
223#define TRIGGER_COMPLETED BIT(2)
224#define WRITE_COMPLETED BIT(1)
225#define SENDING_CMD BIT(0)
226
227#define DIRECT_CMD_STOP_READ 0x8c
228
229#define DIRECT_CMD_WRDATA 0x90
230
231#define DIRECT_CMD_FIFO_RST 0x94
232
233#define DIRECT_CMD_RDDATA 0xa0
234
235#define DIRECT_CMD_RD_PROPS 0xa4
236#define RD_DCS BIT(18)
237#define RD_VCHAN_ID(val) (((val) >> 16) & GENMASK(1, 0))
238#define RD_SIZE(val) ((val) & GENMASK(15, 0))
239
240#define DIRECT_CMD_RD_STS 0xa8
241#define DIRECT_CMD_RD_STS_CTL 0x13c
242#define DIRECT_CMD_RD_STS_CLR 0x15c
243#define DIRECT_CMD_RD_STS_FLAG 0x17c
244#define ERR_EOT_WITH_ERR BIT(8)
245#define ERR_MISSING_EOT BIT(7)
246#define ERR_WRONG_LENGTH BIT(6)
247#define ERR_OVERSIZE BIT(5)
248#define ERR_RECEIVE BIT(4)
249#define ERR_UNDECODABLE BIT(3)
250#define ERR_CHECKSUM BIT(2)
251#define ERR_UNCORRECTABLE BIT(1)
252#define ERR_FIXED BIT(0)
253
254#define VID_MAIN_CTL 0xb0
255#define VID_IGNORE_MISS_VSYNC BIT(31)
256#define VID_FIELD_SW BIT(28)
257#define VID_INTERLACED_EN BIT(27)
258#define RECOVERY_MODE(x) ((x) << 25)
259#define RECOVERY_MODE_NEXT_HSYNC 0
260#define RECOVERY_MODE_NEXT_STOP_POINT 2
261#define RECOVERY_MODE_NEXT_VSYNC 3
262#define REG_BLKEOL_MODE(x) ((x) << 23)
263#define REG_BLKLINE_MODE(x) ((x) << 21)
264#define REG_BLK_MODE_NULL_PKT 0
265#define REG_BLK_MODE_BLANKING_PKT 1
266#define REG_BLK_MODE_LP 2
267#define SYNC_PULSE_HORIZONTAL BIT(20)
268#define SYNC_PULSE_ACTIVE BIT(19)
269#define BURST_MODE BIT(18)
270#define VID_PIXEL_MODE_MASK GENMASK(17, 14)
271#define VID_PIXEL_MODE_RGB565 (0 << 14)
272#define VID_PIXEL_MODE_RGB666_PACKED (1 << 14)
273#define VID_PIXEL_MODE_RGB666 (2 << 14)
274#define VID_PIXEL_MODE_RGB888 (3 << 14)
275#define VID_PIXEL_MODE_RGB101010 (4 << 14)
276#define VID_PIXEL_MODE_RGB121212 (5 << 14)
277#define VID_PIXEL_MODE_YUV420 (8 << 14)
278#define VID_PIXEL_MODE_YUV422_PACKED (9 << 14)
279#define VID_PIXEL_MODE_YUV422 (10 << 14)
280#define VID_PIXEL_MODE_YUV422_24B (11 << 14)
281#define VID_PIXEL_MODE_DSC_COMP (12 << 14)
282#define VID_DATATYPE(x) ((x) << 8)
283#define VID_VIRTCHAN_ID(iface, x) ((x) << (4 + (iface) * 2))
284#define STOP_MODE(x) ((x) << 2)
285#define START_MODE(x) (x)
286
287#define VID_VSIZE1 0xb4
288#define VFP_LEN(x) ((x) << 12)
289#define VBP_LEN(x) ((x) << 6)
290#define VSA_LEN(x) (x)
291
292#define VID_VSIZE2 0xb8
293#define VACT_LEN(x) (x)
294
295#define VID_HSIZE1 0xc0
296#define HBP_LEN(x) ((x) << 16)
297#define HSA_LEN(x) (x)
298
299#define VID_HSIZE2 0xc4
300#define HFP_LEN(x) ((x) << 16)
301#define HACT_LEN(x) (x)
302
303#define VID_BLKSIZE1 0xcc
304#define BLK_EOL_PKT_LEN(x) ((x) << 15)
305#define BLK_LINE_EVENT_PKT_LEN(x) (x)
306
307#define VID_BLKSIZE2 0xd0
308#define BLK_LINE_PULSE_PKT_LEN(x) (x)
309
310#define VID_PKT_TIME 0xd8
311#define BLK_EOL_DURATION(x) (x)
312
313#define VID_DPHY_TIME 0xdc
314#define REG_WAKEUP_TIME(x) ((x) << 17)
315#define REG_LINE_DURATION(x) (x)
316
317#define VID_ERR_COLOR1 0xe0
318#define COL_GREEN(x) ((x) << 12)
319#define COL_RED(x) (x)
320
321#define VID_ERR_COLOR2 0xe4
322#define PAD_VAL(x) ((x) << 12)
323#define COL_BLUE(x) (x)
324
325#define VID_VPOS 0xe8
326#define LINE_VAL(val) (((val) & GENMASK(14, 2)) >> 2)
327#define LINE_POS(val) ((val) & GENMASK(1, 0))
328
329#define VID_HPOS 0xec
330#define HORIZ_VAL(val) (((val) & GENMASK(17, 3)) >> 3)
331#define HORIZ_POS(val) ((val) & GENMASK(2, 0))
332
333#define VID_MODE_STS 0xf0
334#define VID_MODE_STS_CTL 0x140
335#define VID_MODE_STS_CLR 0x160
336#define VID_MODE_STS_FLAG 0x180
337#define VSG_RECOVERY BIT(10)
338#define ERR_VRS_WRONG_LEN BIT(9)
339#define ERR_LONG_READ BIT(8)
340#define ERR_LINE_WRITE BIT(7)
341#define ERR_BURST_WRITE BIT(6)
342#define ERR_SMALL_HEIGHT BIT(5)
343#define ERR_SMALL_LEN BIT(4)
344#define ERR_MISSING_VSYNC BIT(3)
345#define ERR_MISSING_HSYNC BIT(2)
346#define ERR_MISSING_DATA BIT(1)
347#define VSG_RUNNING BIT(0)
348
349#define VID_VCA_SETTING1 0xf4
350#define BURST_LP BIT(16)
351#define MAX_BURST_LIMIT(x) (x)
352
353#define VID_VCA_SETTING2 0xf8
354#define MAX_LINE_LIMIT(x) ((x) << 16)
355#define EXACT_BURST_LIMIT(x) (x)
356
357#define TVG_CTL 0xfc
358#define TVG_STRIPE_SIZE(x) ((x) << 5)
359#define TVG_MODE_MASK GENMASK(4, 3)
360#define TVG_MODE_SINGLE_COLOR (0 << 3)
361#define TVG_MODE_VSTRIPES (2 << 3)
362#define TVG_MODE_HSTRIPES (3 << 3)
363#define TVG_STOPMODE_MASK GENMASK(2, 1)
364#define TVG_STOPMODE_EOF (0 << 1)
365#define TVG_STOPMODE_EOL (1 << 1)
366#define TVG_STOPMODE_NOW (2 << 1)
367#define TVG_RUN BIT(0)
368
369#define TVG_IMG_SIZE 0x100
370#define TVG_NBLINES(x) ((x) << 16)
371#define TVG_LINE_SIZE(x) (x)
372
373#define TVG_COLOR1 0x104
374#define TVG_COL1_GREEN(x) ((x) << 12)
375#define TVG_COL1_RED(x) (x)
376
377#define TVG_COLOR1_BIS 0x108
378#define TVG_COL1_BLUE(x) (x)
379
380#define TVG_COLOR2 0x10c
381#define TVG_COL2_GREEN(x) ((x) << 12)
382#define TVG_COL2_RED(x) (x)
383
384#define TVG_COLOR2_BIS 0x110
385#define TVG_COL2_BLUE(x) (x)
386
387#define TVG_STS 0x114
388#define TVG_STS_CTL 0x144
389#define TVG_STS_CLR 0x164
390#define TVG_STS_FLAG 0x184
391#define TVG_STS_RUNNING BIT(0)
392
393#define STS_CTL_EDGE(e) ((e) << 16)
394
395#define DPHY_LANES_MAP 0x198
396#define DAT_REMAP_CFG(b, l) ((l) << ((b) * 8))
397
398#define DPI_IRQ_EN 0x1a0
399#define DPI_IRQ_CLR 0x1a4
400#define DPI_IRQ_STS 0x1a8
401#define PIXEL_BUF_OVERFLOW BIT(0)
402
403#define DPI_CFG 0x1ac
404#define DPI_CFG_FIFO_DEPTH(x) ((x) >> 16)
405#define DPI_CFG_FIFO_LEVEL(x) ((x) & GENMASK(15, 0))
406
407#define TEST_GENERIC 0x1f0
408#define TEST_STATUS(x) ((x) >> 16)
409#define TEST_CTRL(x) (x)
410
411#define ID_REG 0x1fc
412#define REV_VENDOR_ID(x) (((x) & GENMASK(31, 20)) >> 20)
413#define REV_PRODUCT_ID(x) (((x) & GENMASK(19, 12)) >> 12)
414#define REV_HW(x) (((x) & GENMASK(11, 8)) >> 8)
415#define REV_MAJOR(x) (((x) & GENMASK(7, 4)) >> 4)
416#define REV_MINOR(x) ((x) & GENMASK(3, 0))
417
418#define DSI_OUTPUT_PORT 0
419#define DSI_INPUT_PORT(inputid) (1 + (inputid))
420
421#define DSI_HBP_FRAME_PULSE_OVERHEAD 12
422#define DSI_HBP_FRAME_EVENT_OVERHEAD 16
423#define DSI_HSA_FRAME_OVERHEAD 14
424#define DSI_HFP_FRAME_OVERHEAD 6
425#define DSI_HSS_VSS_VSE_FRAME_OVERHEAD 4
426#define DSI_BLANKING_FRAME_OVERHEAD 6
427#define DSI_NULL_FRAME_OVERHEAD 6
428#define DSI_EOT_PKT_SIZE 4
429
430struct cdns_dsi_bridge_state {
431 struct drm_bridge_state base;
432 struct cdns_dsi_cfg dsi_cfg;
433};
434
435static inline struct cdns_dsi_bridge_state *
436to_cdns_dsi_bridge_state(struct drm_bridge_state *bridge_state)
437{
438 return container_of(bridge_state, struct cdns_dsi_bridge_state, base);
439}
440
441static inline struct cdns_dsi *input_to_dsi(struct cdns_dsi_input *input)
442{
443 return container_of(input, struct cdns_dsi, input);
444}
445
446static inline struct cdns_dsi *to_cdns_dsi(struct mipi_dsi_host *host)
447{
448 return container_of(host, struct cdns_dsi, base);
449}
450
451static inline struct cdns_dsi_input *
452bridge_to_cdns_dsi_input(struct drm_bridge *bridge)
453{
454 return container_of(bridge, struct cdns_dsi_input, bridge);
455}
456
457static unsigned int dpi_to_dsi_timing(unsigned int dpi_timing,
458 unsigned int dpi_bpp,
459 unsigned int dsi_pkt_overhead)
460{
461 unsigned int dsi_timing = DIV_ROUND_UP(dpi_timing * dpi_bpp, 8);
462
463 if (dsi_timing < dsi_pkt_overhead)
464 dsi_timing = 0;
465 else
466 dsi_timing -= dsi_pkt_overhead;
467
468 return dsi_timing;
469}
470
471static int cdns_dsi_mode2cfg(struct cdns_dsi *dsi,
472 const struct videomode *vm,
473 struct cdns_dsi_cfg *dsi_cfg)
474{
475 struct cdns_dsi_output *output = &dsi->output;
476 u32 dpi_hsa, dpi_hbp, dpi_hfp, dpi_hact;
477 bool sync_pulse;
478 int bpp;
479
480 dpi_hsa = vm->hsync_len;
481 dpi_hbp = vm->hback_porch;
482 dpi_hfp = vm->hfront_porch;
483 dpi_hact = vm->hactive;
484
485 memset(dsi_cfg, 0, sizeof(*dsi_cfg));
486
487 sync_pulse = output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
488
489 bpp = mipi_dsi_pixel_format_to_bpp(fmt: output->dev->format);
490
491 if (sync_pulse) {
492 dsi_cfg->hbp = dpi_to_dsi_timing(dpi_timing: dpi_hbp, dpi_bpp: bpp,
493 DSI_HBP_FRAME_PULSE_OVERHEAD);
494
495 dsi_cfg->hsa = dpi_to_dsi_timing(dpi_timing: dpi_hsa, dpi_bpp: bpp,
496 DSI_HSA_FRAME_OVERHEAD);
497 } else {
498 dsi_cfg->hbp = dpi_to_dsi_timing(dpi_timing: dpi_hbp + dpi_hsa, dpi_bpp: bpp,
499 DSI_HBP_FRAME_EVENT_OVERHEAD);
500
501 dsi_cfg->hsa = 0;
502 }
503
504 dsi_cfg->hact = dpi_to_dsi_timing(dpi_timing: dpi_hact, dpi_bpp: bpp, dsi_pkt_overhead: 0);
505
506 dsi_cfg->hfp = dpi_to_dsi_timing(dpi_timing: dpi_hfp, dpi_bpp: bpp, DSI_HFP_FRAME_OVERHEAD);
507
508 dsi_cfg->htotal = dsi_cfg->hact + dsi_cfg->hfp + DSI_HFP_FRAME_OVERHEAD;
509
510 if (sync_pulse) {
511 dsi_cfg->htotal += dsi_cfg->hbp + DSI_HBP_FRAME_PULSE_OVERHEAD;
512 dsi_cfg->htotal += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
513 } else {
514 dsi_cfg->htotal += dsi_cfg->hbp + DSI_HBP_FRAME_EVENT_OVERHEAD;
515 }
516
517 return 0;
518}
519
520static int cdns_dsi_check_conf(struct cdns_dsi *dsi,
521 const struct videomode *vm,
522 struct cdns_dsi_cfg *dsi_cfg)
523{
524 struct cdns_dsi_output *output = &dsi->output;
525 struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy;
526 unsigned int nlanes = output->dev->lanes;
527 int ret;
528
529 ret = cdns_dsi_mode2cfg(dsi, vm, dsi_cfg);
530 if (ret)
531 return ret;
532
533 ret = phy_mipi_dphy_get_default_config(pixel_clock: vm->pixelclock,
534 bpp: mipi_dsi_pixel_format_to_bpp(fmt: output->dev->format),
535 lanes: nlanes, cfg: phy_cfg);
536 if (ret)
537 return ret;
538
539 ret = phy_validate(phy: dsi->dphy, mode: PHY_MODE_MIPI_DPHY, submode: 0, opts: &output->phy_opts);
540 if (ret)
541 return ret;
542
543 return 0;
544}
545
546static int cdns_dsi_bridge_attach(struct drm_bridge *bridge,
547 struct drm_encoder *encoder,
548 enum drm_bridge_attach_flags flags)
549{
550 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
551 struct cdns_dsi *dsi = input_to_dsi(input);
552 struct cdns_dsi_output *output = &dsi->output;
553
554 if (!drm_core_check_feature(dev: bridge->dev, feature: DRIVER_ATOMIC)) {
555 dev_err(dsi->base.dev,
556 "cdns-dsi driver is only compatible with DRM devices supporting atomic updates");
557 return -ENOTSUPP;
558 }
559
560 return drm_bridge_attach(encoder, bridge: output->bridge, previous: bridge,
561 flags);
562}
563
564static enum drm_mode_status
565cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
566 const struct drm_display_info *info,
567 const struct drm_display_mode *mode)
568{
569 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
570 struct cdns_dsi *dsi = input_to_dsi(input);
571 struct cdns_dsi_output *output = &dsi->output;
572 int bpp;
573
574 /*
575 * VFP_DSI should be less than VFP_DPI and VFP_DSI should be at
576 * least 1.
577 */
578 if (mode->vtotal - mode->vsync_end < 2)
579 return MODE_V_ILLEGAL;
580
581 /* VSA_DSI = VSA_DPI and must be at least 2. */
582 if (mode->vsync_end - mode->vsync_start < 2)
583 return MODE_V_ILLEGAL;
584
585 /* HACT must be 32-bits aligned. */
586 bpp = mipi_dsi_pixel_format_to_bpp(fmt: output->dev->format);
587 if ((mode->hdisplay * bpp) % 32)
588 return MODE_H_ILLEGAL;
589
590 return MODE_OK;
591}
592
593static void cdns_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge,
594 struct drm_atomic_state *state)
595{
596 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
597 struct cdns_dsi *dsi = input_to_dsi(input);
598 u32 val;
599
600 /*
601 * The cdns-dsi controller needs to be disabled after it's DPI source
602 * has stopped streaming. If this is not followed, there is a brief
603 * window before DPI source is disabled and after cdns-dsi controller
604 * has been disabled where the DPI stream is still on, but the cdns-dsi
605 * controller is not ready anymore to accept the incoming signals. This
606 * is one of the reasons why a shift in pixel colors is observed on
607 * displays that have cdns-dsi as one of the bridges.
608 *
609 * To mitigate this, disable this bridge from the bridge post_disable()
610 * hook, instead of the bridge _disable() hook. The bridge post_disable()
611 * hook gets called after the CRTC disable, where often many DPI sources
612 * disable their streams.
613 */
614
615 val = readl(addr: dsi->regs + MCTL_MAIN_DATA_CTL);
616 val &= ~(IF_VID_SELECT_MASK | IF_VID_MODE | VID_EN | HOST_EOT_GEN |
617 DISP_EOT_GEN);
618 writel(val, addr: dsi->regs + MCTL_MAIN_DATA_CTL);
619
620 val = readl(addr: dsi->regs + MCTL_MAIN_EN) & ~IF_EN(input->id);
621 writel(val, addr: dsi->regs + MCTL_MAIN_EN);
622
623 if (dsi->platform_ops && dsi->platform_ops->disable)
624 dsi->platform_ops->disable(dsi);
625
626 dsi->phy_initialized = false;
627 dsi->link_initialized = false;
628 phy_power_off(phy: dsi->dphy);
629 phy_exit(phy: dsi->dphy);
630
631 pm_runtime_put(dev: dsi->base.dev);
632}
633
634static void cdns_dsi_hs_init(struct cdns_dsi *dsi)
635{
636 struct cdns_dsi_output *output = &dsi->output;
637 u32 status;
638
639 if (dsi->phy_initialized)
640 return;
641 /*
642 * Power all internal DPHY blocks down and maintain their reset line
643 * asserted before changing the DPHY config.
644 */
645 writel(DPHY_CMN_PSO | DPHY_PLL_PSO | DPHY_ALL_D_PDN | DPHY_C_PDN |
646 DPHY_CMN_PDN | DPHY_PLL_PDN,
647 addr: dsi->regs + MCTL_DPHY_CFG0);
648
649 phy_init(phy: dsi->dphy);
650 phy_set_mode(dsi->dphy, PHY_MODE_MIPI_DPHY);
651 phy_configure(phy: dsi->dphy, opts: &output->phy_opts);
652 phy_power_on(phy: dsi->dphy);
653
654 /* Activate the PLL and wait until it's locked. */
655 writel(PLL_LOCKED, addr: dsi->regs + MCTL_MAIN_STS_CLR);
656 writel(DPHY_CMN_PSO | DPHY_ALL_D_PDN | DPHY_C_PDN | DPHY_CMN_PDN,
657 addr: dsi->regs + MCTL_DPHY_CFG0);
658 WARN_ON_ONCE(readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status,
659 status & PLL_LOCKED, 100, 100));
660 /* De-assert data and clock reset lines. */
661 writel(DPHY_CMN_PSO | DPHY_ALL_D_PDN | DPHY_C_PDN | DPHY_CMN_PDN |
662 DPHY_D_RSTB(output->dev->lanes) | DPHY_C_RSTB,
663 addr: dsi->regs + MCTL_DPHY_CFG0);
664 dsi->phy_initialized = true;
665}
666
667static void cdns_dsi_init_link(struct cdns_dsi *dsi)
668{
669 struct cdns_dsi_output *output = &dsi->output;
670 unsigned long sysclk_period, ulpout;
671 u32 val;
672 int i;
673
674 if (dsi->link_initialized)
675 return;
676
677 val = 0;
678 for (i = 1; i < output->dev->lanes; i++)
679 val |= DATA_LANE_EN(i);
680
681 if (!(output->dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
682 val |= CLK_CONTINUOUS;
683
684 writel(val, addr: dsi->regs + MCTL_MAIN_PHY_CTL);
685
686 /* ULPOUT should be set to 1ms and is expressed in sysclk cycles. */
687 sysclk_period = NSEC_PER_SEC / clk_get_rate(clk: dsi->dsi_sys_clk);
688 ulpout = DIV_ROUND_UP(NSEC_PER_MSEC, sysclk_period);
689 writel(CLK_LANE_ULPOUT_TIME(ulpout) | DATA_LANE_ULPOUT_TIME(ulpout),
690 addr: dsi->regs + MCTL_ULPOUT_TIME);
691
692 writel(LINK_EN, addr: dsi->regs + MCTL_MAIN_DATA_CTL);
693
694 val = CLK_LANE_EN | PLL_START;
695 for (i = 0; i < output->dev->lanes; i++)
696 val |= DATA_LANE_START(i);
697
698 writel(val, addr: dsi->regs + MCTL_MAIN_EN);
699
700 dsi->link_initialized = true;
701}
702
703static void cdns_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
704 struct drm_atomic_state *state)
705{
706 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
707 struct cdns_dsi *dsi = input_to_dsi(input);
708 struct cdns_dsi_output *output = &dsi->output;
709 struct drm_connector_state *conn_state;
710 struct drm_crtc_state *crtc_state;
711 struct cdns_dsi_bridge_state *dsi_state;
712 struct drm_bridge_state *new_bridge_state;
713 struct drm_display_mode *mode;
714 struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy;
715 struct drm_connector *connector;
716 unsigned long tx_byte_period;
717 struct cdns_dsi_cfg dsi_cfg;
718 u32 tmp, reg_wakeup, div, status;
719 int nlanes;
720
721 /*
722 * The cdns-dsi controller needs to be enabled before it's DPI source
723 * has begun streaming. If this is not followed, there is a brief window
724 * after DPI source enable and before cdns-dsi controller enable where
725 * the DPI stream is on, but the cdns-dsi controller is not ready to
726 * accept the incoming signals. This is one of the reasons why a shift
727 * in pixel colors is observed on displays that have cdns-dsi as one of
728 * the bridges.
729 *
730 * To mitigate this, enable this bridge from the bridge pre_enable()
731 * hook, instead of the bridge _enable() hook. The bridge pre_enable()
732 * hook gets called before the CRTC enable, where often many DPI sources
733 * enable their streams.
734 */
735
736 if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0))
737 return;
738
739 new_bridge_state = drm_atomic_get_new_bridge_state(state, bridge);
740 if (WARN_ON(!new_bridge_state))
741 return;
742
743 dsi_state = to_cdns_dsi_bridge_state(bridge_state: new_bridge_state);
744 dsi_cfg = dsi_state->dsi_cfg;
745
746 if (dsi->platform_ops && dsi->platform_ops->enable)
747 dsi->platform_ops->enable(dsi);
748
749 connector = drm_atomic_get_new_connector_for_encoder(state, encoder: bridge->encoder);
750 conn_state = drm_atomic_get_new_connector_state(state, connector);
751 crtc_state = drm_atomic_get_new_crtc_state(state, crtc: conn_state->crtc);
752 mode = &crtc_state->adjusted_mode;
753 nlanes = output->dev->lanes;
754
755 cdns_dsi_init_link(dsi);
756 cdns_dsi_hs_init(dsi);
757
758 /*
759 * Now that the DSI Link and DSI Phy are initialized,
760 * wait for the CLK and Data Lanes to be ready.
761 */
762 tmp = CLK_LANE_RDY;
763 for (int i = 0; i < nlanes; i++)
764 tmp |= DATA_LANE_RDY(i);
765
766 if (readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status,
767 (tmp == (status & tmp)), 100, 500000))
768 dev_err(dsi->base.dev,
769 "Timed Out: DSI-DPhy Clock and Data Lanes not ready.\n");
770
771 writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa),
772 addr: dsi->regs + VID_HSIZE1);
773 writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact),
774 addr: dsi->regs + VID_HSIZE2);
775
776 writel(VBP_LEN(mode->crtc_vtotal - mode->crtc_vsync_end - 1) |
777 VFP_LEN(mode->crtc_vsync_start - mode->crtc_vdisplay) |
778 VSA_LEN(mode->crtc_vsync_end - mode->crtc_vsync_start + 1),
779 addr: dsi->regs + VID_VSIZE1);
780 writel(val: mode->crtc_vdisplay, addr: dsi->regs + VID_VSIZE2);
781
782 tmp = dsi_cfg.htotal -
783 (dsi_cfg.hsa + DSI_BLANKING_FRAME_OVERHEAD +
784 DSI_HSA_FRAME_OVERHEAD);
785 writel(BLK_LINE_PULSE_PKT_LEN(tmp), addr: dsi->regs + VID_BLKSIZE2);
786 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
787 writel(MAX_LINE_LIMIT(tmp - DSI_NULL_FRAME_OVERHEAD),
788 addr: dsi->regs + VID_VCA_SETTING2);
789
790 tmp = dsi_cfg.htotal -
791 (DSI_HSS_VSS_VSE_FRAME_OVERHEAD + DSI_BLANKING_FRAME_OVERHEAD);
792 writel(BLK_LINE_EVENT_PKT_LEN(tmp), addr: dsi->regs + VID_BLKSIZE1);
793 if (!(output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE))
794 writel(MAX_LINE_LIMIT(tmp - DSI_NULL_FRAME_OVERHEAD),
795 addr: dsi->regs + VID_VCA_SETTING2);
796
797 tmp = DIV_ROUND_UP(dsi_cfg.htotal, nlanes) -
798 DIV_ROUND_UP(dsi_cfg.hsa, nlanes);
799
800 if (!(output->dev->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET))
801 tmp -= DIV_ROUND_UP(DSI_EOT_PKT_SIZE, nlanes);
802
803 tx_byte_period = DIV_ROUND_DOWN_ULL((u64)NSEC_PER_SEC * 8,
804 phy_cfg->hs_clk_rate);
805
806 /*
807 * Estimated time [in clock cycles] to perform LP->HS on D-PHY.
808 * It is not clear how to calculate this, so for now,
809 * set it to 1/10 of the total number of clocks in a line.
810 */
811 reg_wakeup = dsi_cfg.htotal / nlanes / 10;
812 writel(REG_WAKEUP_TIME(reg_wakeup) | REG_LINE_DURATION(tmp),
813 addr: dsi->regs + VID_DPHY_TIME);
814
815 /*
816 * HSTX and LPRX timeouts are both expressed in TX byte clk cycles and
817 * both should be set to at least the time it takes to transmit a
818 * frame.
819 */
820 tmp = NSEC_PER_SEC / drm_mode_vrefresh(mode);
821 tmp /= tx_byte_period;
822
823 for (div = 0; div <= CLK_DIV_MAX; div++) {
824 if (tmp <= HSTX_TIMEOUT_MAX)
825 break;
826
827 tmp >>= 1;
828 }
829
830 if (tmp > HSTX_TIMEOUT_MAX)
831 tmp = HSTX_TIMEOUT_MAX;
832
833 writel(CLK_DIV(div) | HSTX_TIMEOUT(tmp),
834 addr: dsi->regs + MCTL_DPHY_TIMEOUT1);
835
836 writel(LPRX_TIMEOUT(tmp), addr: dsi->regs + MCTL_DPHY_TIMEOUT2);
837
838 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO) {
839 switch (output->dev->format) {
840 case MIPI_DSI_FMT_RGB888:
841 tmp = VID_PIXEL_MODE_RGB888 |
842 VID_DATATYPE(MIPI_DSI_PACKED_PIXEL_STREAM_24);
843 break;
844
845 case MIPI_DSI_FMT_RGB666:
846 tmp = VID_PIXEL_MODE_RGB666 |
847 VID_DATATYPE(MIPI_DSI_PIXEL_STREAM_3BYTE_18);
848 break;
849
850 case MIPI_DSI_FMT_RGB666_PACKED:
851 tmp = VID_PIXEL_MODE_RGB666_PACKED |
852 VID_DATATYPE(MIPI_DSI_PACKED_PIXEL_STREAM_18);
853 break;
854
855 case MIPI_DSI_FMT_RGB565:
856 tmp = VID_PIXEL_MODE_RGB565 |
857 VID_DATATYPE(MIPI_DSI_PACKED_PIXEL_STREAM_16);
858 break;
859
860 default:
861 dev_err(dsi->base.dev, "Unsupported DSI format\n");
862 return;
863 }
864
865 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
866 tmp |= SYNC_PULSE_ACTIVE | SYNC_PULSE_HORIZONTAL;
867
868 tmp |= REG_BLKLINE_MODE(REG_BLK_MODE_BLANKING_PKT) |
869 REG_BLKEOL_MODE(REG_BLK_MODE_BLANKING_PKT) |
870 RECOVERY_MODE(RECOVERY_MODE_NEXT_HSYNC) |
871 VID_IGNORE_MISS_VSYNC;
872
873 writel(val: tmp, addr: dsi->regs + VID_MAIN_CTL);
874 }
875
876 tmp = readl(addr: dsi->regs + MCTL_MAIN_DATA_CTL);
877 tmp &= ~(IF_VID_SELECT_MASK | HOST_EOT_GEN | IF_VID_MODE);
878
879 if (!(output->dev->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET))
880 tmp |= HOST_EOT_GEN;
881
882 if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO)
883 tmp |= IF_VID_MODE | IF_VID_SELECT(input->id) | VID_EN;
884
885 writel(val: tmp, addr: dsi->regs + MCTL_MAIN_DATA_CTL);
886
887 tmp = readl(addr: dsi->regs + MCTL_MAIN_EN) | IF_EN(input->id);
888 writel(val: tmp, addr: dsi->regs + MCTL_MAIN_EN);
889}
890
891static u32 *cdns_dsi_bridge_get_input_bus_fmts(struct drm_bridge *bridge,
892 struct drm_bridge_state *bridge_state,
893 struct drm_crtc_state *crtc_state,
894 struct drm_connector_state *conn_state,
895 u32 output_fmt,
896 unsigned int *num_input_fmts)
897{
898 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
899 struct cdns_dsi *dsi = input_to_dsi(input);
900 struct cdns_dsi_output *output = &dsi->output;
901 u32 *input_fmts;
902
903 *num_input_fmts = 0;
904
905 input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL);
906 if (!input_fmts)
907 return NULL;
908
909 input_fmts[0] = drm_mipi_dsi_get_input_bus_fmt(dsi_format: output->dev->format);
910 if (!input_fmts[0])
911 return NULL;
912
913 *num_input_fmts = 1;
914
915 return input_fmts;
916}
917
918static long cdns_dsi_round_pclk(struct cdns_dsi *dsi, unsigned long pclk)
919{
920 struct cdns_dsi_output *output = &dsi->output;
921 unsigned int nlanes = output->dev->lanes;
922 union phy_configure_opts phy_opts = { 0 };
923 u32 bitspp;
924 int ret;
925
926 bitspp = mipi_dsi_pixel_format_to_bpp(fmt: output->dev->format);
927
928 ret = phy_mipi_dphy_get_default_config(pixel_clock: pclk, bpp: bitspp, lanes: nlanes,
929 cfg: &phy_opts.mipi_dphy);
930 if (ret)
931 return ret;
932
933 ret = phy_validate(phy: dsi->dphy, mode: PHY_MODE_MIPI_DPHY, submode: 0, opts: &phy_opts);
934 if (ret)
935 return ret;
936
937 return div_u64(dividend: (u64)phy_opts.mipi_dphy.hs_clk_rate * nlanes, divisor: bitspp);
938}
939
940static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge,
941 struct drm_bridge_state *bridge_state,
942 struct drm_crtc_state *crtc_state,
943 struct drm_connector_state *conn_state)
944{
945 struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
946 struct cdns_dsi *dsi = input_to_dsi(input);
947 struct cdns_dsi_bridge_state *dsi_state = to_cdns_dsi_bridge_state(bridge_state);
948 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
949 struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg;
950 struct videomode vm;
951 long pclk;
952
953 /* cdns-dsi requires negative syncs */
954 adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
955 adjusted_mode->flags |= DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC;
956
957 /*
958 * The DPHY PLL has quite a coarsely grained clock rate options. See
959 * what hsclk rate we can achieve based on the pixel clock, convert it
960 * back to pixel clock, set that to the adjusted_mode->clock. This is
961 * all in hopes that the CRTC will be able to provide us the requested
962 * clock, as otherwise the DPI and DSI clocks will be out of sync.
963 */
964
965 pclk = cdns_dsi_round_pclk(dsi, pclk: adjusted_mode->clock * 1000);
966 if (pclk < 0)
967 return (int)pclk;
968
969 adjusted_mode->clock = pclk / 1000;
970
971 drm_display_mode_to_videomode(dmode: adjusted_mode, vm: &vm);
972
973 return cdns_dsi_check_conf(dsi, vm: &vm, dsi_cfg);
974}
975
976static struct drm_bridge_state *
977cdns_dsi_bridge_atomic_duplicate_state(struct drm_bridge *bridge)
978{
979 struct cdns_dsi_bridge_state *dsi_state, *old_dsi_state;
980 struct drm_bridge_state *bridge_state;
981
982 if (WARN_ON(!bridge->base.state))
983 return NULL;
984
985 bridge_state = drm_priv_to_bridge_state(priv: bridge->base.state);
986 old_dsi_state = to_cdns_dsi_bridge_state(bridge_state);
987
988 dsi_state = kzalloc(sizeof(*dsi_state), GFP_KERNEL);
989 if (!dsi_state)
990 return NULL;
991
992 __drm_atomic_helper_bridge_duplicate_state(bridge, state: &dsi_state->base);
993
994 memcpy(&dsi_state->dsi_cfg, &old_dsi_state->dsi_cfg,
995 sizeof(dsi_state->dsi_cfg));
996
997 return &dsi_state->base;
998}
999
1000static void
1001cdns_dsi_bridge_atomic_destroy_state(struct drm_bridge *bridge,
1002 struct drm_bridge_state *state)
1003{
1004 struct cdns_dsi_bridge_state *dsi_state;
1005
1006 dsi_state = to_cdns_dsi_bridge_state(bridge_state: state);
1007
1008 kfree(objp: dsi_state);
1009}
1010
1011static struct drm_bridge_state *
1012cdns_dsi_bridge_atomic_reset(struct drm_bridge *bridge)
1013{
1014 struct cdns_dsi_bridge_state *dsi_state;
1015
1016 dsi_state = kzalloc(sizeof(*dsi_state), GFP_KERNEL);
1017 if (!dsi_state)
1018 return NULL;
1019
1020 memset(dsi_state, 0, sizeof(*dsi_state));
1021 dsi_state->base.bridge = bridge;
1022
1023 return &dsi_state->base;
1024}
1025
1026static const struct drm_bridge_funcs cdns_dsi_bridge_funcs = {
1027 .attach = cdns_dsi_bridge_attach,
1028 .mode_valid = cdns_dsi_bridge_mode_valid,
1029 .atomic_pre_enable = cdns_dsi_bridge_atomic_pre_enable,
1030 .atomic_post_disable = cdns_dsi_bridge_atomic_post_disable,
1031 .atomic_check = cdns_dsi_bridge_atomic_check,
1032 .atomic_reset = cdns_dsi_bridge_atomic_reset,
1033 .atomic_duplicate_state = cdns_dsi_bridge_atomic_duplicate_state,
1034 .atomic_destroy_state = cdns_dsi_bridge_atomic_destroy_state,
1035 .atomic_get_input_bus_fmts = cdns_dsi_bridge_get_input_bus_fmts,
1036};
1037
1038static int cdns_dsi_attach(struct mipi_dsi_host *host,
1039 struct mipi_dsi_device *dev)
1040{
1041 struct cdns_dsi *dsi = to_cdns_dsi(host);
1042 struct cdns_dsi_output *output = &dsi->output;
1043 struct cdns_dsi_input *input = &dsi->input;
1044 struct drm_bridge *bridge;
1045 int ret;
1046
1047 /*
1048 * We currently do not support connecting several DSI devices to the
1049 * same host. In order to support that we'd need the DRM bridge
1050 * framework to allow dynamic reconfiguration of the bridge chain.
1051 */
1052 if (output->dev)
1053 return -EBUSY;
1054
1055 /*
1056 * The host <-> device link might be described using an OF-graph
1057 * representation, in this case we extract the device of_node from
1058 * this representation.
1059 */
1060 bridge = devm_drm_of_get_bridge(dev: dsi->base.dev, node: dsi->base.dev->of_node,
1061 DSI_OUTPUT_PORT, endpoint: dev->channel);
1062 if (IS_ERR(ptr: bridge)) {
1063 ret = PTR_ERR(ptr: bridge);
1064 dev_err(host->dev, "failed to add DSI device %s (err = %d)",
1065 dev->name, ret);
1066 return ret;
1067 }
1068
1069 output->dev = dev;
1070 output->bridge = bridge;
1071
1072 /*
1073 * The DSI output has been properly configured, we can now safely
1074 * register the input to the bridge framework so that it can take place
1075 * in a display pipeline.
1076 */
1077 drm_bridge_add(bridge: &input->bridge);
1078
1079 return 0;
1080}
1081
1082static int cdns_dsi_detach(struct mipi_dsi_host *host,
1083 struct mipi_dsi_device *dev)
1084{
1085 struct cdns_dsi *dsi = to_cdns_dsi(host);
1086 struct cdns_dsi_input *input = &dsi->input;
1087
1088 drm_bridge_remove(bridge: &input->bridge);
1089
1090 return 0;
1091}
1092
1093static irqreturn_t cdns_dsi_interrupt(int irq, void *data)
1094{
1095 struct cdns_dsi *dsi = data;
1096 irqreturn_t ret = IRQ_NONE;
1097 u32 flag, ctl;
1098
1099 flag = readl(addr: dsi->regs + DIRECT_CMD_STS_FLAG);
1100 if (flag) {
1101 ctl = readl(addr: dsi->regs + DIRECT_CMD_STS_CTL);
1102 ctl &= ~flag;
1103 writel(val: ctl, addr: dsi->regs + DIRECT_CMD_STS_CTL);
1104 complete(&dsi->direct_cmd_comp);
1105 ret = IRQ_HANDLED;
1106 }
1107
1108 return ret;
1109}
1110
1111static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host,
1112 const struct mipi_dsi_msg *msg)
1113{
1114 struct cdns_dsi *dsi = to_cdns_dsi(host);
1115 u32 cmd, sts, val, wait = WRITE_COMPLETED, ctl = 0;
1116 struct mipi_dsi_packet packet;
1117 int ret, i, tx_len, rx_len;
1118
1119 ret = pm_runtime_resume_and_get(dev: host->dev);
1120 if (ret < 0)
1121 return ret;
1122
1123 cdns_dsi_init_link(dsi);
1124
1125 ret = mipi_dsi_create_packet(packet: &packet, msg);
1126 if (ret)
1127 goto out;
1128
1129 tx_len = msg->tx_buf ? msg->tx_len : 0;
1130 rx_len = msg->rx_buf ? msg->rx_len : 0;
1131
1132 /* For read operations, the maximum TX len is 2. */
1133 if (rx_len && tx_len > 2) {
1134 ret = -ENOTSUPP;
1135 goto out;
1136 }
1137
1138 /* TX len is limited by the CMD FIFO depth. */
1139 if (tx_len > dsi->direct_cmd_fifo_depth) {
1140 ret = -ENOTSUPP;
1141 goto out;
1142 }
1143
1144 /* RX len is limited by the RX FIFO depth. */
1145 if (rx_len > dsi->rx_fifo_depth) {
1146 ret = -ENOTSUPP;
1147 goto out;
1148 }
1149
1150 cmd = CMD_SIZE(tx_len) | CMD_VCHAN_ID(msg->channel) |
1151 CMD_DATATYPE(msg->type);
1152
1153 if (msg->flags & MIPI_DSI_MSG_USE_LPM)
1154 cmd |= CMD_LP_EN;
1155
1156 if (mipi_dsi_packet_format_is_long(type: msg->type))
1157 cmd |= CMD_LONG;
1158
1159 if (rx_len) {
1160 cmd |= READ_CMD;
1161 wait = READ_COMPLETED_WITH_ERR | READ_COMPLETED;
1162 ctl = READ_EN | BTA_EN;
1163 } else if (msg->flags & MIPI_DSI_MSG_REQ_ACK) {
1164 cmd |= BTA_REQ;
1165 wait = ACK_WITH_ERR_RCVD | ACK_RCVD;
1166 ctl = BTA_EN;
1167 }
1168
1169 writel(readl(addr: dsi->regs + MCTL_MAIN_DATA_CTL) | ctl,
1170 addr: dsi->regs + MCTL_MAIN_DATA_CTL);
1171
1172 writel(val: cmd, addr: dsi->regs + DIRECT_CMD_MAIN_SETTINGS);
1173
1174 for (i = 0; i < tx_len; i += 4) {
1175 const u8 *buf = msg->tx_buf;
1176 int j;
1177
1178 val = 0;
1179 for (j = 0; j < 4 && j + i < tx_len; j++)
1180 val |= (u32)buf[i + j] << (8 * j);
1181
1182 writel(val, addr: dsi->regs + DIRECT_CMD_WRDATA);
1183 }
1184
1185 /* Clear status flags before sending the command. */
1186 writel(val: wait, addr: dsi->regs + DIRECT_CMD_STS_CLR);
1187 writel(val: wait, addr: dsi->regs + DIRECT_CMD_STS_CTL);
1188 reinit_completion(x: &dsi->direct_cmd_comp);
1189 writel(val: 0, addr: dsi->regs + DIRECT_CMD_SEND);
1190
1191 wait_for_completion_timeout(x: &dsi->direct_cmd_comp,
1192 timeout: msecs_to_jiffies(m: 1000));
1193
1194 sts = readl(addr: dsi->regs + DIRECT_CMD_STS);
1195 writel(val: wait, addr: dsi->regs + DIRECT_CMD_STS_CLR);
1196 writel(val: 0, addr: dsi->regs + DIRECT_CMD_STS_CTL);
1197
1198 writel(readl(addr: dsi->regs + MCTL_MAIN_DATA_CTL) & ~ctl,
1199 addr: dsi->regs + MCTL_MAIN_DATA_CTL);
1200
1201 /* We did not receive the events we were waiting for. */
1202 if (!(sts & wait)) {
1203 ret = -ETIMEDOUT;
1204 goto out;
1205 }
1206
1207 /* 'READ' or 'WRITE with ACK' failed. */
1208 if (sts & (READ_COMPLETED_WITH_ERR | ACK_WITH_ERR_RCVD)) {
1209 ret = -EIO;
1210 goto out;
1211 }
1212
1213 for (i = 0; i < rx_len; i += 4) {
1214 u8 *buf = msg->rx_buf;
1215 int j;
1216
1217 val = readl(addr: dsi->regs + DIRECT_CMD_RDDATA);
1218 for (j = 0; j < 4 && j + i < rx_len; j++)
1219 buf[i + j] = val >> (8 * j);
1220 }
1221
1222out:
1223 pm_runtime_put(dev: host->dev);
1224 return ret;
1225}
1226
1227static const struct mipi_dsi_host_ops cdns_dsi_ops = {
1228 .attach = cdns_dsi_attach,
1229 .detach = cdns_dsi_detach,
1230 .transfer = cdns_dsi_transfer,
1231};
1232
1233static int __maybe_unused cdns_dsi_resume(struct device *dev)
1234{
1235 struct cdns_dsi *dsi = dev_get_drvdata(dev);
1236
1237 reset_control_deassert(rstc: dsi->dsi_p_rst);
1238 clk_prepare_enable(clk: dsi->dsi_p_clk);
1239 clk_prepare_enable(clk: dsi->dsi_sys_clk);
1240
1241 return 0;
1242}
1243
1244static int __maybe_unused cdns_dsi_suspend(struct device *dev)
1245{
1246 struct cdns_dsi *dsi = dev_get_drvdata(dev);
1247
1248 clk_disable_unprepare(clk: dsi->dsi_sys_clk);
1249 clk_disable_unprepare(clk: dsi->dsi_p_clk);
1250 reset_control_assert(rstc: dsi->dsi_p_rst);
1251 return 0;
1252}
1253
1254static UNIVERSAL_DEV_PM_OPS(cdns_dsi_pm_ops, cdns_dsi_suspend, cdns_dsi_resume,
1255 NULL);
1256
1257static int cdns_dsi_drm_probe(struct platform_device *pdev)
1258{
1259 struct cdns_dsi *dsi;
1260 struct cdns_dsi_input *input;
1261 int ret, irq;
1262 u32 val;
1263
1264 dsi = devm_drm_bridge_alloc(&pdev->dev, struct cdns_dsi, input.bridge,
1265 &cdns_dsi_bridge_funcs);
1266 if (IS_ERR(ptr: dsi))
1267 return PTR_ERR(ptr: dsi);
1268
1269 platform_set_drvdata(pdev, data: dsi);
1270
1271 input = &dsi->input;
1272
1273 dsi->regs = devm_platform_ioremap_resource(pdev, index: 0);
1274 if (IS_ERR(ptr: dsi->regs))
1275 return PTR_ERR(ptr: dsi->regs);
1276
1277 dsi->dsi_p_clk = devm_clk_get(dev: &pdev->dev, id: "dsi_p_clk");
1278 if (IS_ERR(ptr: dsi->dsi_p_clk))
1279 return PTR_ERR(ptr: dsi->dsi_p_clk);
1280
1281 dsi->dsi_p_rst = devm_reset_control_get_optional_exclusive(dev: &pdev->dev,
1282 id: "dsi_p_rst");
1283 if (IS_ERR(ptr: dsi->dsi_p_rst))
1284 return PTR_ERR(ptr: dsi->dsi_p_rst);
1285
1286 dsi->dsi_sys_clk = devm_clk_get(dev: &pdev->dev, id: "dsi_sys_clk");
1287 if (IS_ERR(ptr: dsi->dsi_sys_clk))
1288 return PTR_ERR(ptr: dsi->dsi_sys_clk);
1289
1290 irq = platform_get_irq(pdev, 0);
1291 if (irq < 0)
1292 return irq;
1293
1294 dsi->dphy = devm_phy_get(dev: &pdev->dev, string: "dphy");
1295 if (IS_ERR(ptr: dsi->dphy))
1296 return PTR_ERR(ptr: dsi->dphy);
1297
1298 ret = clk_prepare_enable(clk: dsi->dsi_p_clk);
1299 if (ret)
1300 return ret;
1301
1302 val = readl(addr: dsi->regs + ID_REG);
1303 if (REV_VENDOR_ID(val) != 0xcad) {
1304 dev_err(&pdev->dev, "invalid vendor id\n");
1305 ret = -EINVAL;
1306 goto err_disable_pclk;
1307 }
1308
1309 dsi->platform_ops = of_device_get_match_data(dev: &pdev->dev);
1310
1311 val = readl(addr: dsi->regs + IP_CONF);
1312 dsi->direct_cmd_fifo_depth = 1 << (DIRCMD_FIFO_DEPTH(val) + 2);
1313 dsi->rx_fifo_depth = RX_FIFO_DEPTH(val);
1314 init_completion(x: &dsi->direct_cmd_comp);
1315
1316 writel(val: 0, addr: dsi->regs + MCTL_MAIN_DATA_CTL);
1317 writel(val: 0, addr: dsi->regs + MCTL_MAIN_EN);
1318 writel(val: 0, addr: dsi->regs + MCTL_MAIN_PHY_CTL);
1319
1320 /*
1321 * We only support the DPI input, so force input->id to
1322 * CDNS_DPI_INPUT.
1323 */
1324 input->id = CDNS_DPI_INPUT;
1325 input->bridge.of_node = pdev->dev.of_node;
1326
1327 /* Mask all interrupts before registering the IRQ handler. */
1328 writel(val: 0, addr: dsi->regs + MCTL_MAIN_STS_CTL);
1329 writel(val: 0, addr: dsi->regs + MCTL_DPHY_ERR_CTL1);
1330 writel(val: 0, addr: dsi->regs + CMD_MODE_STS_CTL);
1331 writel(val: 0, addr: dsi->regs + DIRECT_CMD_STS_CTL);
1332 writel(val: 0, addr: dsi->regs + DIRECT_CMD_RD_STS_CTL);
1333 writel(val: 0, addr: dsi->regs + VID_MODE_STS_CTL);
1334 writel(val: 0, addr: dsi->regs + TVG_STS_CTL);
1335 writel(val: 0, addr: dsi->regs + DPI_IRQ_EN);
1336 ret = devm_request_irq(dev: &pdev->dev, irq, handler: cdns_dsi_interrupt, irqflags: 0,
1337 devname: dev_name(dev: &pdev->dev), dev_id: dsi);
1338 if (ret)
1339 goto err_disable_pclk;
1340
1341 pm_runtime_enable(dev: &pdev->dev);
1342 dsi->base.dev = &pdev->dev;
1343 dsi->base.ops = &cdns_dsi_ops;
1344
1345 if (dsi->platform_ops && dsi->platform_ops->init) {
1346 ret = dsi->platform_ops->init(dsi);
1347 if (ret != 0) {
1348 dev_err(&pdev->dev, "platform initialization failed: %d\n",
1349 ret);
1350 goto err_disable_runtime_pm;
1351 }
1352 }
1353
1354 ret = mipi_dsi_host_register(host: &dsi->base);
1355 if (ret)
1356 goto err_deinit_platform;
1357
1358 clk_disable_unprepare(clk: dsi->dsi_p_clk);
1359
1360 return 0;
1361
1362err_deinit_platform:
1363 if (dsi->platform_ops && dsi->platform_ops->deinit)
1364 dsi->platform_ops->deinit(dsi);
1365
1366err_disable_runtime_pm:
1367 pm_runtime_disable(dev: &pdev->dev);
1368
1369err_disable_pclk:
1370 clk_disable_unprepare(clk: dsi->dsi_p_clk);
1371
1372 return ret;
1373}
1374
1375static void cdns_dsi_drm_remove(struct platform_device *pdev)
1376{
1377 struct cdns_dsi *dsi = platform_get_drvdata(pdev);
1378
1379 mipi_dsi_host_unregister(host: &dsi->base);
1380
1381 if (dsi->platform_ops && dsi->platform_ops->deinit)
1382 dsi->platform_ops->deinit(dsi);
1383
1384 pm_runtime_disable(dev: &pdev->dev);
1385}
1386
1387static const struct of_device_id cdns_dsi_of_match[] = {
1388 { .compatible = "cdns,dsi" },
1389#ifdef CONFIG_DRM_CDNS_DSI_J721E
1390 { .compatible = "ti,j721e-dsi", .data = &dsi_ti_j721e_ops, },
1391#endif
1392 { },
1393};
1394MODULE_DEVICE_TABLE(of, cdns_dsi_of_match);
1395
1396static struct platform_driver cdns_dsi_platform_driver = {
1397 .probe = cdns_dsi_drm_probe,
1398 .remove = cdns_dsi_drm_remove,
1399 .driver = {
1400 .name = "cdns-dsi",
1401 .of_match_table = cdns_dsi_of_match,
1402 .pm = &cdns_dsi_pm_ops,
1403 },
1404};
1405module_platform_driver(cdns_dsi_platform_driver);
1406
1407MODULE_AUTHOR("Boris Brezillon <boris.brezillon@bootlin.com>");
1408MODULE_DESCRIPTION("Cadence DSI driver");
1409MODULE_LICENSE("GPL");
1410MODULE_ALIAS("platform:cdns-dsi");
1411

source code of linux/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c