xref: /linux/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c (revision 6fdcba32711044c35c0e1b094cbd8f3f0b4472c9)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2016 Allwinnertech Co., Ltd.
4  * Copyright (C) 2017-2018 Bootlin
5  *
6  * Maxime Ripard <maxime.ripard@bootlin.com>
7  */
8 
9 #include <linux/clk.h>
10 #include <linux/component.h>
11 #include <linux/crc-ccitt.h>
12 #include <linux/module.h>
13 #include <linux/of_address.h>
14 #include <linux/phy/phy-mipi-dphy.h>
15 #include <linux/phy/phy.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/regmap.h>
19 #include <linux/regulator/consumer.h>
20 #include <linux/reset.h>
21 #include <linux/slab.h>
22 
23 #include <drm/drm_atomic_helper.h>
24 #include <drm/drm_mipi_dsi.h>
25 #include <drm/drm_panel.h>
26 #include <drm/drm_print.h>
27 #include <drm/drm_probe_helper.h>
28 
29 #include "sun4i_crtc.h"
30 #include "sun4i_drv.h"
31 #include "sun4i_tcon.h"
32 #include "sun6i_mipi_dsi.h"
33 
34 #include <video/mipi_display.h>
35 
36 #define SUN6I_DSI_CTL_REG		0x000
37 #define SUN6I_DSI_CTL_EN			BIT(0)
38 
39 #define SUN6I_DSI_BASIC_CTL_REG		0x00c
40 #define SUN6I_DSI_BASIC_CTL_TRAIL_INV(n)		(((n) & 0xf) << 4)
41 #define SUN6I_DSI_BASIC_CTL_TRAIL_FILL		BIT(3)
42 #define SUN6I_DSI_BASIC_CTL_HBP_DIS		BIT(2)
43 #define SUN6I_DSI_BASIC_CTL_HSA_HSE_DIS		BIT(1)
44 #define SUN6I_DSI_BASIC_CTL_VIDEO_BURST		BIT(0)
45 
46 #define SUN6I_DSI_BASIC_CTL0_REG	0x010
47 #define SUN6I_DSI_BASIC_CTL0_HS_EOTP_EN		BIT(18)
48 #define SUN6I_DSI_BASIC_CTL0_CRC_EN		BIT(17)
49 #define SUN6I_DSI_BASIC_CTL0_ECC_EN		BIT(16)
50 #define SUN6I_DSI_BASIC_CTL0_INST_ST		BIT(0)
51 
52 #define SUN6I_DSI_BASIC_CTL1_REG	0x014
53 #define SUN6I_DSI_BASIC_CTL1_VIDEO_ST_DELAY(n)	(((n) & 0x1fff) << 4)
54 #define SUN6I_DSI_BASIC_CTL1_VIDEO_FILL		BIT(2)
55 #define SUN6I_DSI_BASIC_CTL1_VIDEO_PRECISION	BIT(1)
56 #define SUN6I_DSI_BASIC_CTL1_VIDEO_MODE		BIT(0)
57 
58 #define SUN6I_DSI_BASIC_SIZE0_REG	0x018
59 #define SUN6I_DSI_BASIC_SIZE0_VBP(n)		(((n) & 0xfff) << 16)
60 #define SUN6I_DSI_BASIC_SIZE0_VSA(n)		((n) & 0xfff)
61 
62 #define SUN6I_DSI_BASIC_SIZE1_REG	0x01c
63 #define SUN6I_DSI_BASIC_SIZE1_VT(n)		(((n) & 0xfff) << 16)
64 #define SUN6I_DSI_BASIC_SIZE1_VACT(n)		((n) & 0xfff)
65 
66 #define SUN6I_DSI_INST_FUNC_REG(n)	(0x020 + (n) * 0x04)
67 #define SUN6I_DSI_INST_FUNC_INST_MODE(n)	(((n) & 0xf) << 28)
68 #define SUN6I_DSI_INST_FUNC_ESCAPE_ENTRY(n)	(((n) & 0xf) << 24)
69 #define SUN6I_DSI_INST_FUNC_TRANS_PACKET(n)	(((n) & 0xf) << 20)
70 #define SUN6I_DSI_INST_FUNC_LANE_CEN		BIT(4)
71 #define SUN6I_DSI_INST_FUNC_LANE_DEN(n)		((n) & 0xf)
72 
73 #define SUN6I_DSI_INST_LOOP_SEL_REG	0x040
74 
75 #define SUN6I_DSI_INST_LOOP_NUM_REG(n)	(0x044 + (n) * 0x10)
76 #define SUN6I_DSI_INST_LOOP_NUM_N1(n)		(((n) & 0xfff) << 16)
77 #define SUN6I_DSI_INST_LOOP_NUM_N0(n)		((n) & 0xfff)
78 
79 #define SUN6I_DSI_INST_JUMP_SEL_REG	0x048
80 
81 #define SUN6I_DSI_INST_JUMP_CFG_REG(n)	(0x04c + (n) * 0x04)
82 #define SUN6I_DSI_INST_JUMP_CFG_TO(n)		(((n) & 0xf) << 20)
83 #define SUN6I_DSI_INST_JUMP_CFG_POINT(n)	(((n) & 0xf) << 16)
84 #define SUN6I_DSI_INST_JUMP_CFG_NUM(n)		((n) & 0xffff)
85 
86 #define SUN6I_DSI_TRANS_START_REG	0x060
87 
88 #define SUN6I_DSI_TRANS_ZERO_REG	0x078
89 
90 #define SUN6I_DSI_TCON_DRQ_REG		0x07c
91 #define SUN6I_DSI_TCON_DRQ_ENABLE_MODE		BIT(28)
92 #define SUN6I_DSI_TCON_DRQ_SET(n)		((n) & 0x3ff)
93 
94 #define SUN6I_DSI_PIXEL_CTL0_REG	0x080
95 #define SUN6I_DSI_PIXEL_CTL0_PD_PLUG_DISABLE	BIT(16)
96 #define SUN6I_DSI_PIXEL_CTL0_FORMAT(n)		((n) & 0xf)
97 
98 #define SUN6I_DSI_PIXEL_CTL1_REG	0x084
99 
100 #define SUN6I_DSI_PIXEL_PH_REG		0x090
101 #define SUN6I_DSI_PIXEL_PH_ECC(n)		(((n) & 0xff) << 24)
102 #define SUN6I_DSI_PIXEL_PH_WC(n)		(((n) & 0xffff) << 8)
103 #define SUN6I_DSI_PIXEL_PH_VC(n)		(((n) & 3) << 6)
104 #define SUN6I_DSI_PIXEL_PH_DT(n)		((n) & 0x3f)
105 
106 #define SUN6I_DSI_PIXEL_PF0_REG		0x098
107 #define SUN6I_DSI_PIXEL_PF0_CRC_FORCE(n)	((n) & 0xffff)
108 
109 #define SUN6I_DSI_PIXEL_PF1_REG		0x09c
110 #define SUN6I_DSI_PIXEL_PF1_CRC_INIT_LINEN(n)	(((n) & 0xffff) << 16)
111 #define SUN6I_DSI_PIXEL_PF1_CRC_INIT_LINE0(n)	((n) & 0xffff)
112 
113 #define SUN6I_DSI_SYNC_HSS_REG		0x0b0
114 
115 #define SUN6I_DSI_SYNC_HSE_REG		0x0b4
116 
117 #define SUN6I_DSI_SYNC_VSS_REG		0x0b8
118 
119 #define SUN6I_DSI_SYNC_VSE_REG		0x0bc
120 
121 #define SUN6I_DSI_BLK_HSA0_REG		0x0c0
122 
123 #define SUN6I_DSI_BLK_HSA1_REG		0x0c4
124 #define SUN6I_DSI_BLK_PF(n)			(((n) & 0xffff) << 16)
125 #define SUN6I_DSI_BLK_PD(n)			((n) & 0xff)
126 
127 #define SUN6I_DSI_BLK_HBP0_REG		0x0c8
128 
129 #define SUN6I_DSI_BLK_HBP1_REG		0x0cc
130 
131 #define SUN6I_DSI_BLK_HFP0_REG		0x0d0
132 
133 #define SUN6I_DSI_BLK_HFP1_REG		0x0d4
134 
135 #define SUN6I_DSI_BLK_HBLK0_REG		0x0e0
136 
137 #define SUN6I_DSI_BLK_HBLK1_REG		0x0e4
138 
139 #define SUN6I_DSI_BLK_VBLK0_REG		0x0e8
140 
141 #define SUN6I_DSI_BLK_VBLK1_REG		0x0ec
142 
143 #define SUN6I_DSI_BURST_LINE_REG	0x0f0
144 #define SUN6I_DSI_BURST_LINE_SYNC_POINT(n)	(((n) & 0xffff) << 16)
145 #define SUN6I_DSI_BURST_LINE_NUM(n)		((n) & 0xffff)
146 
147 #define SUN6I_DSI_BURST_DRQ_REG		0x0f4
148 #define SUN6I_DSI_BURST_DRQ_EDGE1(n)		(((n) & 0xffff) << 16)
149 #define SUN6I_DSI_BURST_DRQ_EDGE0(n)		((n) & 0xffff)
150 
151 #define SUN6I_DSI_CMD_CTL_REG		0x200
152 #define SUN6I_DSI_CMD_CTL_RX_OVERFLOW		BIT(26)
153 #define SUN6I_DSI_CMD_CTL_RX_FLAG		BIT(25)
154 #define SUN6I_DSI_CMD_CTL_TX_FLAG		BIT(9)
155 
156 #define SUN6I_DSI_CMD_RX_REG(n)		(0x240 + (n) * 0x04)
157 
158 #define SUN6I_DSI_DEBUG_DATA_REG	0x2f8
159 
160 #define SUN6I_DSI_CMD_TX_REG(n)		(0x300 + (n) * 0x04)
161 
162 #define SUN6I_DSI_SYNC_POINT		40
163 
164 enum sun6i_dsi_start_inst {
165 	DSI_START_LPRX,
166 	DSI_START_LPTX,
167 	DSI_START_HSC,
168 	DSI_START_HSD,
169 };
170 
171 enum sun6i_dsi_inst_id {
172 	DSI_INST_ID_LP11	= 0,
173 	DSI_INST_ID_TBA,
174 	DSI_INST_ID_HSC,
175 	DSI_INST_ID_HSD,
176 	DSI_INST_ID_LPDT,
177 	DSI_INST_ID_HSCEXIT,
178 	DSI_INST_ID_NOP,
179 	DSI_INST_ID_DLY,
180 	DSI_INST_ID_END		= 15,
181 };
182 
183 enum sun6i_dsi_inst_mode {
184 	DSI_INST_MODE_STOP	= 0,
185 	DSI_INST_MODE_TBA,
186 	DSI_INST_MODE_HS,
187 	DSI_INST_MODE_ESCAPE,
188 	DSI_INST_MODE_HSCEXIT,
189 	DSI_INST_MODE_NOP,
190 };
191 
192 enum sun6i_dsi_inst_escape {
193 	DSI_INST_ESCA_LPDT	= 0,
194 	DSI_INST_ESCA_ULPS,
195 	DSI_INST_ESCA_UN1,
196 	DSI_INST_ESCA_UN2,
197 	DSI_INST_ESCA_RESET,
198 	DSI_INST_ESCA_UN3,
199 	DSI_INST_ESCA_UN4,
200 	DSI_INST_ESCA_UN5,
201 };
202 
203 enum sun6i_dsi_inst_packet {
204 	DSI_INST_PACK_PIXEL	= 0,
205 	DSI_INST_PACK_COMMAND,
206 };
207 
208 static const u32 sun6i_dsi_ecc_array[] = {
209 	[0] = (BIT(0) | BIT(1) | BIT(2) | BIT(4) | BIT(5) | BIT(7) | BIT(10) |
210 	       BIT(11) | BIT(13) | BIT(16) | BIT(20) | BIT(21) | BIT(22) |
211 	       BIT(23)),
212 	[1] = (BIT(0) | BIT(1) | BIT(3) | BIT(4) | BIT(6) | BIT(8) | BIT(10) |
213 	       BIT(12) | BIT(14) | BIT(17) | BIT(20) | BIT(21) | BIT(22) |
214 	       BIT(23)),
215 	[2] = (BIT(0) | BIT(2) | BIT(3) | BIT(5) | BIT(6) | BIT(9) | BIT(11) |
216 	       BIT(12) | BIT(15) | BIT(18) | BIT(20) | BIT(21) | BIT(22)),
217 	[3] = (BIT(1) | BIT(2) | BIT(3) | BIT(7) | BIT(8) | BIT(9) | BIT(13) |
218 	       BIT(14) | BIT(15) | BIT(19) | BIT(20) | BIT(21) | BIT(23)),
219 	[4] = (BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(16) |
220 	       BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(22) | BIT(23)),
221 	[5] = (BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) |
222 	       BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(21) | BIT(22) |
223 	       BIT(23)),
224 };
225 
226 static u32 sun6i_dsi_ecc_compute(unsigned int data)
227 {
228 	int i;
229 	u8 ecc = 0;
230 
231 	for (i = 0; i < ARRAY_SIZE(sun6i_dsi_ecc_array); i++) {
232 		u32 field = sun6i_dsi_ecc_array[i];
233 		bool init = false;
234 		u8 val = 0;
235 		int j;
236 
237 		for (j = 0; j < 24; j++) {
238 			if (!(BIT(j) & field))
239 				continue;
240 
241 			if (!init) {
242 				val = (BIT(j) & data) ? 1 : 0;
243 				init = true;
244 			} else {
245 				val ^= (BIT(j) & data) ? 1 : 0;
246 			}
247 		}
248 
249 		ecc |= val << i;
250 	}
251 
252 	return ecc;
253 }
254 
255 static u16 sun6i_dsi_crc_compute(u8 const *buffer, size_t len)
256 {
257 	return crc_ccitt(0xffff, buffer, len);
258 }
259 
260 static u16 sun6i_dsi_crc_repeat(u8 pd, u8 *buffer, size_t len)
261 {
262 	memset(buffer, pd, len);
263 
264 	return sun6i_dsi_crc_compute(buffer, len);
265 }
266 
267 static u32 sun6i_dsi_build_sync_pkt(u8 dt, u8 vc, u8 d0, u8 d1)
268 {
269 	u32 val = dt & 0x3f;
270 
271 	val |= (vc & 3) << 6;
272 	val |= (d0 & 0xff) << 8;
273 	val |= (d1 & 0xff) << 16;
274 	val |= sun6i_dsi_ecc_compute(val) << 24;
275 
276 	return val;
277 }
278 
279 static u32 sun6i_dsi_build_blk0_pkt(u8 vc, u16 wc)
280 {
281 	return sun6i_dsi_build_sync_pkt(MIPI_DSI_BLANKING_PACKET, vc,
282 					wc & 0xff, wc >> 8);
283 }
284 
285 static u32 sun6i_dsi_build_blk1_pkt(u16 pd, u8 *buffer, size_t len)
286 {
287 	u32 val = SUN6I_DSI_BLK_PD(pd);
288 
289 	return val | SUN6I_DSI_BLK_PF(sun6i_dsi_crc_repeat(pd, buffer, len));
290 }
291 
292 static void sun6i_dsi_inst_abort(struct sun6i_dsi *dsi)
293 {
294 	regmap_update_bits(dsi->regs, SUN6I_DSI_BASIC_CTL0_REG,
295 			   SUN6I_DSI_BASIC_CTL0_INST_ST, 0);
296 }
297 
298 static void sun6i_dsi_inst_commit(struct sun6i_dsi *dsi)
299 {
300 	regmap_update_bits(dsi->regs, SUN6I_DSI_BASIC_CTL0_REG,
301 			   SUN6I_DSI_BASIC_CTL0_INST_ST,
302 			   SUN6I_DSI_BASIC_CTL0_INST_ST);
303 }
304 
305 static int sun6i_dsi_inst_wait_for_completion(struct sun6i_dsi *dsi)
306 {
307 	u32 val;
308 
309 	return regmap_read_poll_timeout(dsi->regs, SUN6I_DSI_BASIC_CTL0_REG,
310 					val,
311 					!(val & SUN6I_DSI_BASIC_CTL0_INST_ST),
312 					100, 5000);
313 }
314 
315 static void sun6i_dsi_inst_setup(struct sun6i_dsi *dsi,
316 				 enum sun6i_dsi_inst_id id,
317 				 enum sun6i_dsi_inst_mode mode,
318 				 bool clock, u8 data,
319 				 enum sun6i_dsi_inst_packet packet,
320 				 enum sun6i_dsi_inst_escape escape)
321 {
322 	regmap_write(dsi->regs, SUN6I_DSI_INST_FUNC_REG(id),
323 		     SUN6I_DSI_INST_FUNC_INST_MODE(mode) |
324 		     SUN6I_DSI_INST_FUNC_ESCAPE_ENTRY(escape) |
325 		     SUN6I_DSI_INST_FUNC_TRANS_PACKET(packet) |
326 		     (clock ? SUN6I_DSI_INST_FUNC_LANE_CEN : 0) |
327 		     SUN6I_DSI_INST_FUNC_LANE_DEN(data));
328 }
329 
330 static void sun6i_dsi_inst_init(struct sun6i_dsi *dsi,
331 				struct mipi_dsi_device *device)
332 {
333 	u8 lanes_mask = GENMASK(device->lanes - 1, 0);
334 
335 	sun6i_dsi_inst_setup(dsi, DSI_INST_ID_LP11, DSI_INST_MODE_STOP,
336 			     true, lanes_mask, 0, 0);
337 
338 	sun6i_dsi_inst_setup(dsi, DSI_INST_ID_TBA, DSI_INST_MODE_TBA,
339 			     false, 1, 0, 0);
340 
341 	sun6i_dsi_inst_setup(dsi, DSI_INST_ID_HSC, DSI_INST_MODE_HS,
342 			     true, 0, DSI_INST_PACK_PIXEL, 0);
343 
344 	sun6i_dsi_inst_setup(dsi, DSI_INST_ID_HSD, DSI_INST_MODE_HS,
345 			     false, lanes_mask, DSI_INST_PACK_PIXEL, 0);
346 
347 	sun6i_dsi_inst_setup(dsi, DSI_INST_ID_LPDT, DSI_INST_MODE_ESCAPE,
348 			     false, 1, DSI_INST_PACK_COMMAND,
349 			     DSI_INST_ESCA_LPDT);
350 
351 	sun6i_dsi_inst_setup(dsi, DSI_INST_ID_HSCEXIT, DSI_INST_MODE_HSCEXIT,
352 			     true, 0, 0, 0);
353 
354 	sun6i_dsi_inst_setup(dsi, DSI_INST_ID_NOP, DSI_INST_MODE_STOP,
355 			     false, lanes_mask, 0, 0);
356 
357 	sun6i_dsi_inst_setup(dsi, DSI_INST_ID_DLY, DSI_INST_MODE_NOP,
358 			     true, lanes_mask, 0, 0);
359 
360 	regmap_write(dsi->regs, SUN6I_DSI_INST_JUMP_CFG_REG(0),
361 		     SUN6I_DSI_INST_JUMP_CFG_POINT(DSI_INST_ID_NOP) |
362 		     SUN6I_DSI_INST_JUMP_CFG_TO(DSI_INST_ID_HSCEXIT) |
363 		     SUN6I_DSI_INST_JUMP_CFG_NUM(1));
364 };
365 
366 static u16 sun6i_dsi_get_video_start_delay(struct sun6i_dsi *dsi,
367 					   struct drm_display_mode *mode)
368 {
369 	u16 delay = mode->vtotal - (mode->vsync_start - mode->vdisplay) + 1;
370 
371 	if (delay > mode->vtotal)
372 		delay = delay % mode->vtotal;
373 
374 	return max_t(u16, delay, 1);
375 }
376 
377 static u16 sun6i_dsi_get_line_num(struct sun6i_dsi *dsi,
378 				  struct drm_display_mode *mode)
379 {
380 	struct mipi_dsi_device *device = dsi->device;
381 	unsigned int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
382 
383 	return mode->htotal * Bpp / device->lanes;
384 }
385 
386 static u16 sun6i_dsi_get_drq_edge0(struct sun6i_dsi *dsi,
387 				   struct drm_display_mode *mode,
388 				   u16 line_num, u16 edge1)
389 {
390 	u16 edge0 = edge1;
391 
392 	edge0 += (mode->hdisplay + 40) * SUN6I_DSI_TCON_DIV / 8;
393 
394 	if (edge0 > line_num)
395 		return edge0 - line_num;
396 
397 	return 1;
398 }
399 
400 static u16 sun6i_dsi_get_drq_edge1(struct sun6i_dsi *dsi,
401 				   struct drm_display_mode *mode,
402 				   u16 line_num)
403 {
404 	struct mipi_dsi_device *device = dsi->device;
405 	unsigned int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
406 	unsigned int hbp = mode->htotal - mode->hsync_end;
407 	u16 edge1;
408 
409 	edge1 = SUN6I_DSI_SYNC_POINT;
410 	edge1 += (mode->hdisplay + hbp + 20) * Bpp / device->lanes;
411 
412 	if (edge1 > line_num)
413 		return line_num;
414 
415 	return edge1;
416 }
417 
418 static void sun6i_dsi_setup_burst(struct sun6i_dsi *dsi,
419 				  struct drm_display_mode *mode)
420 {
421 	struct mipi_dsi_device *device = dsi->device;
422 	u32 val = 0;
423 
424 	if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
425 		u16 line_num = sun6i_dsi_get_line_num(dsi, mode);
426 		u16 edge0, edge1;
427 
428 		edge1 = sun6i_dsi_get_drq_edge1(dsi, mode, line_num);
429 		edge0 = sun6i_dsi_get_drq_edge0(dsi, mode, line_num, edge1);
430 
431 		regmap_write(dsi->regs, SUN6I_DSI_BURST_DRQ_REG,
432 			     SUN6I_DSI_BURST_DRQ_EDGE0(edge0) |
433 			     SUN6I_DSI_BURST_DRQ_EDGE1(edge1));
434 
435 		regmap_write(dsi->regs, SUN6I_DSI_BURST_LINE_REG,
436 			     SUN6I_DSI_BURST_LINE_NUM(line_num) |
437 			     SUN6I_DSI_BURST_LINE_SYNC_POINT(SUN6I_DSI_SYNC_POINT));
438 
439 		val = SUN6I_DSI_TCON_DRQ_ENABLE_MODE;
440 	} else if ((mode->hsync_start - mode->hdisplay) > 20) {
441 		/* Maaaaaagic */
442 		u16 drq = (mode->hsync_start - mode->hdisplay) - 20;
443 
444 		drq *= mipi_dsi_pixel_format_to_bpp(device->format);
445 		drq /= 32;
446 
447 		val = (SUN6I_DSI_TCON_DRQ_ENABLE_MODE |
448 		       SUN6I_DSI_TCON_DRQ_SET(drq));
449 	}
450 
451 	regmap_write(dsi->regs, SUN6I_DSI_TCON_DRQ_REG, val);
452 }
453 
454 static void sun6i_dsi_setup_inst_loop(struct sun6i_dsi *dsi,
455 				      struct drm_display_mode *mode)
456 {
457 	struct mipi_dsi_device *device = dsi->device;
458 	u16 delay = 50 - 1;
459 
460 	if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
461 		u32 hsync_porch = (mode->htotal - mode->hdisplay) * 150;
462 
463 		delay = (hsync_porch / ((mode->clock / 1000) * 8));
464 		delay -= 50;
465 	}
466 
467 	regmap_write(dsi->regs, SUN6I_DSI_INST_LOOP_SEL_REG,
468 		     2 << (4 * DSI_INST_ID_LP11) |
469 		     3 << (4 * DSI_INST_ID_DLY));
470 
471 	regmap_write(dsi->regs, SUN6I_DSI_INST_LOOP_NUM_REG(0),
472 		     SUN6I_DSI_INST_LOOP_NUM_N0(50 - 1) |
473 		     SUN6I_DSI_INST_LOOP_NUM_N1(delay));
474 	regmap_write(dsi->regs, SUN6I_DSI_INST_LOOP_NUM_REG(1),
475 		     SUN6I_DSI_INST_LOOP_NUM_N0(50 - 1) |
476 		     SUN6I_DSI_INST_LOOP_NUM_N1(delay));
477 }
478 
479 static void sun6i_dsi_setup_format(struct sun6i_dsi *dsi,
480 				   struct drm_display_mode *mode)
481 {
482 	struct mipi_dsi_device *device = dsi->device;
483 	u32 val = SUN6I_DSI_PIXEL_PH_VC(device->channel);
484 	u8 dt, fmt;
485 	u16 wc;
486 
487 	/*
488 	 * TODO: The format defines are only valid in video mode and
489 	 * change in command mode.
490 	 */
491 	switch (device->format) {
492 	case MIPI_DSI_FMT_RGB888:
493 		dt = MIPI_DSI_PACKED_PIXEL_STREAM_24;
494 		fmt = 8;
495 		break;
496 	case MIPI_DSI_FMT_RGB666:
497 		dt = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
498 		fmt = 9;
499 		break;
500 	case MIPI_DSI_FMT_RGB666_PACKED:
501 		dt = MIPI_DSI_PACKED_PIXEL_STREAM_18;
502 		fmt = 10;
503 		break;
504 	case MIPI_DSI_FMT_RGB565:
505 		dt = MIPI_DSI_PACKED_PIXEL_STREAM_16;
506 		fmt = 11;
507 		break;
508 	default:
509 		return;
510 	}
511 	val |= SUN6I_DSI_PIXEL_PH_DT(dt);
512 
513 	wc = mode->hdisplay * mipi_dsi_pixel_format_to_bpp(device->format) / 8;
514 	val |= SUN6I_DSI_PIXEL_PH_WC(wc);
515 	val |= SUN6I_DSI_PIXEL_PH_ECC(sun6i_dsi_ecc_compute(val));
516 
517 	regmap_write(dsi->regs, SUN6I_DSI_PIXEL_PH_REG, val);
518 
519 	regmap_write(dsi->regs, SUN6I_DSI_PIXEL_PF0_REG,
520 		     SUN6I_DSI_PIXEL_PF0_CRC_FORCE(0xffff));
521 
522 	regmap_write(dsi->regs, SUN6I_DSI_PIXEL_PF1_REG,
523 		     SUN6I_DSI_PIXEL_PF1_CRC_INIT_LINE0(0xffff) |
524 		     SUN6I_DSI_PIXEL_PF1_CRC_INIT_LINEN(0xffff));
525 
526 	regmap_write(dsi->regs, SUN6I_DSI_PIXEL_CTL0_REG,
527 		     SUN6I_DSI_PIXEL_CTL0_PD_PLUG_DISABLE |
528 		     SUN6I_DSI_PIXEL_CTL0_FORMAT(fmt));
529 }
530 
531 static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
532 				    struct drm_display_mode *mode)
533 {
534 	struct mipi_dsi_device *device = dsi->device;
535 	unsigned int Bpp = mipi_dsi_pixel_format_to_bpp(device->format) / 8;
536 	u16 hbp = 0, hfp = 0, hsa = 0, hblk = 0, vblk = 0;
537 	u32 basic_ctl = 0;
538 	size_t bytes;
539 	u8 *buffer;
540 
541 	/* Do all timing calculations up front to allocate buffer space */
542 
543 	if (device->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
544 		hblk = mode->hdisplay * Bpp;
545 		basic_ctl = SUN6I_DSI_BASIC_CTL_VIDEO_BURST |
546 			    SUN6I_DSI_BASIC_CTL_HSA_HSE_DIS |
547 			    SUN6I_DSI_BASIC_CTL_HBP_DIS;
548 
549 		if (device->lanes == 4)
550 			basic_ctl |= SUN6I_DSI_BASIC_CTL_TRAIL_FILL |
551 				     SUN6I_DSI_BASIC_CTL_TRAIL_INV(0xc);
552 	} else {
553 		/*
554 		 * A sync period is composed of a blanking packet (4
555 		 * bytes + payload + 2 bytes) and a sync event packet
556 		 * (4 bytes). Its minimal size is therefore 10 bytes
557 		 */
558 #define HSA_PACKET_OVERHEAD	10
559 		hsa = max((unsigned int)HSA_PACKET_OVERHEAD,
560 			  (mode->hsync_end - mode->hsync_start) * Bpp - HSA_PACKET_OVERHEAD);
561 
562 		/*
563 		 * The backporch is set using a blanking packet (4
564 		 * bytes + payload + 2 bytes). Its minimal size is
565 		 * therefore 6 bytes
566 		 */
567 #define HBP_PACKET_OVERHEAD	6
568 		hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
569 			  (mode->htotal - mode->hsync_end) * Bpp - HBP_PACKET_OVERHEAD);
570 
571 		/*
572 		 * The frontporch is set using a sync event (4 bytes)
573 		 * and two blanking packets (each one is 4 bytes +
574 		 * payload + 2 bytes). Its minimal size is therefore
575 		 * 16 bytes
576 		 */
577 #define HFP_PACKET_OVERHEAD	16
578 		hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
579 			  (mode->hsync_start - mode->hdisplay) * Bpp - HFP_PACKET_OVERHEAD);
580 
581 		/*
582 		 * The blanking is set using a sync event (4 bytes)
583 		 * and a blanking packet (4 bytes + payload + 2
584 		 * bytes). Its minimal size is therefore 10 bytes.
585 		 */
586 #define HBLK_PACKET_OVERHEAD	10
587 		hblk = max((unsigned int)HBLK_PACKET_OVERHEAD,
588 			   (mode->htotal - (mode->hsync_end - mode->hsync_start)) * Bpp -
589 			   HBLK_PACKET_OVERHEAD);
590 
591 		/*
592 		 * And I'm not entirely sure what vblk is about. The driver in
593 		 * Allwinner BSP is using a rather convoluted calculation
594 		 * there only for 4 lanes. However, using 0 (the !4 lanes
595 		 * case) even with a 4 lanes screen seems to work...
596 		 */
597 		vblk = 0;
598 	}
599 
600 	/* How many bytes do we need to send all payloads? */
601 	bytes = max_t(size_t, max(max(hfp, hblk), max(hsa, hbp)), vblk);
602 	buffer = kmalloc(bytes, GFP_KERNEL);
603 	if (WARN_ON(!buffer))
604 		return;
605 
606 	regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL_REG, basic_ctl);
607 
608 	regmap_write(dsi->regs, SUN6I_DSI_SYNC_HSS_REG,
609 		     sun6i_dsi_build_sync_pkt(MIPI_DSI_H_SYNC_START,
610 					      device->channel,
611 					      0, 0));
612 
613 	regmap_write(dsi->regs, SUN6I_DSI_SYNC_HSE_REG,
614 		     sun6i_dsi_build_sync_pkt(MIPI_DSI_H_SYNC_END,
615 					      device->channel,
616 					      0, 0));
617 
618 	regmap_write(dsi->regs, SUN6I_DSI_SYNC_VSS_REG,
619 		     sun6i_dsi_build_sync_pkt(MIPI_DSI_V_SYNC_START,
620 					      device->channel,
621 					      0, 0));
622 
623 	regmap_write(dsi->regs, SUN6I_DSI_SYNC_VSE_REG,
624 		     sun6i_dsi_build_sync_pkt(MIPI_DSI_V_SYNC_END,
625 					      device->channel,
626 					      0, 0));
627 
628 	regmap_write(dsi->regs, SUN6I_DSI_BASIC_SIZE0_REG,
629 		     SUN6I_DSI_BASIC_SIZE0_VSA(mode->vsync_end -
630 					       mode->vsync_start) |
631 		     SUN6I_DSI_BASIC_SIZE0_VBP(mode->vtotal -
632 					       mode->vsync_end));
633 
634 	regmap_write(dsi->regs, SUN6I_DSI_BASIC_SIZE1_REG,
635 		     SUN6I_DSI_BASIC_SIZE1_VACT(mode->vdisplay) |
636 		     SUN6I_DSI_BASIC_SIZE1_VT(mode->vtotal));
637 
638 	/* sync */
639 	regmap_write(dsi->regs, SUN6I_DSI_BLK_HSA0_REG,
640 		     sun6i_dsi_build_blk0_pkt(device->channel, hsa));
641 	regmap_write(dsi->regs, SUN6I_DSI_BLK_HSA1_REG,
642 		     sun6i_dsi_build_blk1_pkt(0, buffer, hsa));
643 
644 	/* backporch */
645 	regmap_write(dsi->regs, SUN6I_DSI_BLK_HBP0_REG,
646 		     sun6i_dsi_build_blk0_pkt(device->channel, hbp));
647 	regmap_write(dsi->regs, SUN6I_DSI_BLK_HBP1_REG,
648 		     sun6i_dsi_build_blk1_pkt(0, buffer, hbp));
649 
650 	/* frontporch */
651 	regmap_write(dsi->regs, SUN6I_DSI_BLK_HFP0_REG,
652 		     sun6i_dsi_build_blk0_pkt(device->channel, hfp));
653 	regmap_write(dsi->regs, SUN6I_DSI_BLK_HFP1_REG,
654 		     sun6i_dsi_build_blk1_pkt(0, buffer, hfp));
655 
656 	/* hblk */
657 	regmap_write(dsi->regs, SUN6I_DSI_BLK_HBLK0_REG,
658 		     sun6i_dsi_build_blk0_pkt(device->channel, hblk));
659 	regmap_write(dsi->regs, SUN6I_DSI_BLK_HBLK1_REG,
660 		     sun6i_dsi_build_blk1_pkt(0, buffer, hblk));
661 
662 	/* vblk */
663 	regmap_write(dsi->regs, SUN6I_DSI_BLK_VBLK0_REG,
664 		     sun6i_dsi_build_blk0_pkt(device->channel, vblk));
665 	regmap_write(dsi->regs, SUN6I_DSI_BLK_VBLK1_REG,
666 		     sun6i_dsi_build_blk1_pkt(0, buffer, vblk));
667 
668 	kfree(buffer);
669 }
670 
671 static int sun6i_dsi_start(struct sun6i_dsi *dsi,
672 			   enum sun6i_dsi_start_inst func)
673 {
674 	switch (func) {
675 	case DSI_START_LPTX:
676 		regmap_write(dsi->regs, SUN6I_DSI_INST_JUMP_SEL_REG,
677 			     DSI_INST_ID_LPDT << (4 * DSI_INST_ID_LP11) |
678 			     DSI_INST_ID_END  << (4 * DSI_INST_ID_LPDT));
679 		break;
680 	case DSI_START_LPRX:
681 		regmap_write(dsi->regs, SUN6I_DSI_INST_JUMP_SEL_REG,
682 			     DSI_INST_ID_LPDT << (4 * DSI_INST_ID_LP11) |
683 			     DSI_INST_ID_DLY  << (4 * DSI_INST_ID_LPDT) |
684 			     DSI_INST_ID_TBA  << (4 * DSI_INST_ID_DLY) |
685 			     DSI_INST_ID_END  << (4 * DSI_INST_ID_TBA));
686 		break;
687 	case DSI_START_HSC:
688 		regmap_write(dsi->regs, SUN6I_DSI_INST_JUMP_SEL_REG,
689 			     DSI_INST_ID_HSC  << (4 * DSI_INST_ID_LP11) |
690 			     DSI_INST_ID_END  << (4 * DSI_INST_ID_HSC));
691 		break;
692 	case DSI_START_HSD:
693 		regmap_write(dsi->regs, SUN6I_DSI_INST_JUMP_SEL_REG,
694 			     DSI_INST_ID_NOP  << (4 * DSI_INST_ID_LP11) |
695 			     DSI_INST_ID_HSD  << (4 * DSI_INST_ID_NOP) |
696 			     DSI_INST_ID_DLY  << (4 * DSI_INST_ID_HSD) |
697 			     DSI_INST_ID_NOP  << (4 * DSI_INST_ID_DLY) |
698 			     DSI_INST_ID_END  << (4 * DSI_INST_ID_HSCEXIT));
699 		break;
700 	default:
701 		regmap_write(dsi->regs, SUN6I_DSI_INST_JUMP_SEL_REG,
702 			     DSI_INST_ID_END  << (4 * DSI_INST_ID_LP11));
703 		break;
704 	}
705 
706 	sun6i_dsi_inst_abort(dsi);
707 	sun6i_dsi_inst_commit(dsi);
708 
709 	if (func == DSI_START_HSC)
710 		regmap_write_bits(dsi->regs,
711 				  SUN6I_DSI_INST_FUNC_REG(DSI_INST_ID_LP11),
712 				  SUN6I_DSI_INST_FUNC_LANE_CEN, 0);
713 
714 	return 0;
715 }
716 
717 static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
718 {
719 	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
720 	struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
721 	struct mipi_dsi_device *device = dsi->device;
722 	union phy_configure_opts opts = { 0 };
723 	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
724 	u16 delay;
725 
726 	DRM_DEBUG_DRIVER("Enabling DSI output\n");
727 
728 	pm_runtime_get_sync(dsi->dev);
729 
730 	delay = sun6i_dsi_get_video_start_delay(dsi, mode);
731 	regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL1_REG,
732 		     SUN6I_DSI_BASIC_CTL1_VIDEO_ST_DELAY(delay) |
733 		     SUN6I_DSI_BASIC_CTL1_VIDEO_FILL |
734 		     SUN6I_DSI_BASIC_CTL1_VIDEO_PRECISION |
735 		     SUN6I_DSI_BASIC_CTL1_VIDEO_MODE);
736 
737 	sun6i_dsi_setup_burst(dsi, mode);
738 	sun6i_dsi_setup_inst_loop(dsi, mode);
739 	sun6i_dsi_setup_format(dsi, mode);
740 	sun6i_dsi_setup_timings(dsi, mode);
741 
742 	phy_init(dsi->dphy);
743 
744 	phy_mipi_dphy_get_default_config(mode->clock * 1000,
745 					 mipi_dsi_pixel_format_to_bpp(device->format),
746 					 device->lanes, cfg);
747 
748 	phy_set_mode(dsi->dphy, PHY_MODE_MIPI_DPHY);
749 	phy_configure(dsi->dphy, &opts);
750 	phy_power_on(dsi->dphy);
751 
752 	if (!IS_ERR(dsi->panel))
753 		drm_panel_prepare(dsi->panel);
754 
755 	/*
756 	 * FIXME: This should be moved after the switch to HS mode.
757 	 *
758 	 * Unfortunately, once in HS mode, it seems like we're not
759 	 * able to send DCS commands anymore, which would prevent any
760 	 * panel to send any DCS command as part as their enable
761 	 * method, which is quite common.
762 	 *
763 	 * I haven't seen any artifact due to that sub-optimal
764 	 * ordering on the panels I've tested it with, so I guess this
765 	 * will do for now, until that IP is better understood.
766 	 */
767 	if (!IS_ERR(dsi->panel))
768 		drm_panel_enable(dsi->panel);
769 
770 	sun6i_dsi_start(dsi, DSI_START_HSC);
771 
772 	udelay(1000);
773 
774 	sun6i_dsi_start(dsi, DSI_START_HSD);
775 }
776 
777 static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder)
778 {
779 	struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
780 
781 	DRM_DEBUG_DRIVER("Disabling DSI output\n");
782 
783 	if (!IS_ERR(dsi->panel)) {
784 		drm_panel_disable(dsi->panel);
785 		drm_panel_unprepare(dsi->panel);
786 	}
787 
788 	phy_power_off(dsi->dphy);
789 	phy_exit(dsi->dphy);
790 
791 	pm_runtime_put(dsi->dev);
792 }
793 
794 static int sun6i_dsi_get_modes(struct drm_connector *connector)
795 {
796 	struct sun6i_dsi *dsi = connector_to_sun6i_dsi(connector);
797 
798 	return drm_panel_get_modes(dsi->panel, connector);
799 }
800 
801 static struct drm_connector_helper_funcs sun6i_dsi_connector_helper_funcs = {
802 	.get_modes	= sun6i_dsi_get_modes,
803 };
804 
805 static enum drm_connector_status
806 sun6i_dsi_connector_detect(struct drm_connector *connector, bool force)
807 {
808 	return connector_status_connected;
809 }
810 
811 static const struct drm_connector_funcs sun6i_dsi_connector_funcs = {
812 	.detect			= sun6i_dsi_connector_detect,
813 	.fill_modes		= drm_helper_probe_single_connector_modes,
814 	.destroy		= drm_connector_cleanup,
815 	.reset			= drm_atomic_helper_connector_reset,
816 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
817 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
818 };
819 
820 static const struct drm_encoder_helper_funcs sun6i_dsi_enc_helper_funcs = {
821 	.disable	= sun6i_dsi_encoder_disable,
822 	.enable		= sun6i_dsi_encoder_enable,
823 };
824 
825 static const struct drm_encoder_funcs sun6i_dsi_enc_funcs = {
826 	.destroy	= drm_encoder_cleanup,
827 };
828 
829 static u32 sun6i_dsi_dcs_build_pkt_hdr(struct sun6i_dsi *dsi,
830 				       const struct mipi_dsi_msg *msg)
831 {
832 	u32 pkt = msg->type;
833 
834 	if (msg->type == MIPI_DSI_DCS_LONG_WRITE) {
835 		pkt |= ((msg->tx_len) & 0xffff) << 8;
836 		pkt |= (((msg->tx_len) >> 8) & 0xffff) << 16;
837 	} else {
838 		pkt |= (((u8 *)msg->tx_buf)[0] << 8);
839 		if (msg->tx_len > 1)
840 			pkt |= (((u8 *)msg->tx_buf)[1] << 16);
841 	}
842 
843 	pkt |= sun6i_dsi_ecc_compute(pkt) << 24;
844 
845 	return pkt;
846 }
847 
848 static int sun6i_dsi_dcs_write_short(struct sun6i_dsi *dsi,
849 				     const struct mipi_dsi_msg *msg)
850 {
851 	regmap_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(0),
852 		     sun6i_dsi_dcs_build_pkt_hdr(dsi, msg));
853 	regmap_write_bits(dsi->regs, SUN6I_DSI_CMD_CTL_REG,
854 			  0xff, (4 - 1));
855 
856 	sun6i_dsi_start(dsi, DSI_START_LPTX);
857 
858 	return msg->tx_len;
859 }
860 
861 static int sun6i_dsi_dcs_write_long(struct sun6i_dsi *dsi,
862 				    const struct mipi_dsi_msg *msg)
863 {
864 	int ret, len = 0;
865 	u8 *bounce;
866 	u16 crc;
867 
868 	regmap_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(0),
869 		     sun6i_dsi_dcs_build_pkt_hdr(dsi, msg));
870 
871 	bounce = kzalloc(msg->tx_len + sizeof(crc), GFP_KERNEL);
872 	if (!bounce)
873 		return -ENOMEM;
874 
875 	memcpy(bounce, msg->tx_buf, msg->tx_len);
876 	len += msg->tx_len;
877 
878 	crc = sun6i_dsi_crc_compute(bounce, msg->tx_len);
879 	memcpy((u8 *)bounce + msg->tx_len, &crc, sizeof(crc));
880 	len += sizeof(crc);
881 
882 	regmap_bulk_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(1), bounce, len);
883 	regmap_write(dsi->regs, SUN6I_DSI_CMD_CTL_REG, len + 4 - 1);
884 	kfree(bounce);
885 
886 	sun6i_dsi_start(dsi, DSI_START_LPTX);
887 
888 	ret = sun6i_dsi_inst_wait_for_completion(dsi);
889 	if (ret < 0) {
890 		sun6i_dsi_inst_abort(dsi);
891 		return ret;
892 	}
893 
894 	/*
895 	 * TODO: There's some bits (reg 0x200, bits 8/9) that
896 	 * apparently can be used to check whether the data have been
897 	 * sent, but I couldn't get it to work reliably.
898 	 */
899 	return msg->tx_len;
900 }
901 
902 static int sun6i_dsi_dcs_read(struct sun6i_dsi *dsi,
903 			      const struct mipi_dsi_msg *msg)
904 {
905 	u32 val;
906 	int ret;
907 	u8 byte0;
908 
909 	regmap_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(0),
910 		     sun6i_dsi_dcs_build_pkt_hdr(dsi, msg));
911 	regmap_write(dsi->regs, SUN6I_DSI_CMD_CTL_REG,
912 		     (4 - 1));
913 
914 	sun6i_dsi_start(dsi, DSI_START_LPRX);
915 
916 	ret = sun6i_dsi_inst_wait_for_completion(dsi);
917 	if (ret < 0) {
918 		sun6i_dsi_inst_abort(dsi);
919 		return ret;
920 	}
921 
922 	/*
923 	 * TODO: There's some bits (reg 0x200, bits 24/25) that
924 	 * apparently can be used to check whether the data have been
925 	 * received, but I couldn't get it to work reliably.
926 	 */
927 	regmap_read(dsi->regs, SUN6I_DSI_CMD_CTL_REG, &val);
928 	if (val & SUN6I_DSI_CMD_CTL_RX_OVERFLOW)
929 		return -EIO;
930 
931 	regmap_read(dsi->regs, SUN6I_DSI_CMD_RX_REG(0), &val);
932 	byte0 = val & 0xff;
933 	if (byte0 == MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT)
934 		return -EIO;
935 
936 	((u8 *)msg->rx_buf)[0] = (val >> 8);
937 
938 	return 1;
939 }
940 
941 static int sun6i_dsi_attach(struct mipi_dsi_host *host,
942 			    struct mipi_dsi_device *device)
943 {
944 	struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
945 
946 	dsi->device = device;
947 	dsi->panel = of_drm_find_panel(device->dev.of_node);
948 	if (IS_ERR(dsi->panel))
949 		return PTR_ERR(dsi->panel);
950 
951 	dev_info(host->dev, "Attached device %s\n", device->name);
952 
953 	return 0;
954 }
955 
956 static int sun6i_dsi_detach(struct mipi_dsi_host *host,
957 			    struct mipi_dsi_device *device)
958 {
959 	struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
960 
961 	dsi->panel = NULL;
962 	dsi->device = NULL;
963 
964 	return 0;
965 }
966 
967 static ssize_t sun6i_dsi_transfer(struct mipi_dsi_host *host,
968 				  const struct mipi_dsi_msg *msg)
969 {
970 	struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
971 	int ret;
972 
973 	ret = sun6i_dsi_inst_wait_for_completion(dsi);
974 	if (ret < 0)
975 		sun6i_dsi_inst_abort(dsi);
976 
977 	regmap_write(dsi->regs, SUN6I_DSI_CMD_CTL_REG,
978 		     SUN6I_DSI_CMD_CTL_RX_OVERFLOW |
979 		     SUN6I_DSI_CMD_CTL_RX_FLAG |
980 		     SUN6I_DSI_CMD_CTL_TX_FLAG);
981 
982 	switch (msg->type) {
983 	case MIPI_DSI_DCS_SHORT_WRITE:
984 	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
985 	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
986 		ret = sun6i_dsi_dcs_write_short(dsi, msg);
987 		break;
988 
989 	case MIPI_DSI_DCS_LONG_WRITE:
990 		ret = sun6i_dsi_dcs_write_long(dsi, msg);
991 		break;
992 
993 	case MIPI_DSI_DCS_READ:
994 		if (msg->rx_len == 1) {
995 			ret = sun6i_dsi_dcs_read(dsi, msg);
996 			break;
997 		}
998 		/* Else, fall through */
999 
1000 	default:
1001 		ret = -EINVAL;
1002 	}
1003 
1004 	return ret;
1005 }
1006 
1007 static const struct mipi_dsi_host_ops sun6i_dsi_host_ops = {
1008 	.attach		= sun6i_dsi_attach,
1009 	.detach		= sun6i_dsi_detach,
1010 	.transfer	= sun6i_dsi_transfer,
1011 };
1012 
1013 static const struct regmap_config sun6i_dsi_regmap_config = {
1014 	.reg_bits	= 32,
1015 	.val_bits	= 32,
1016 	.reg_stride	= 4,
1017 	.max_register	= SUN6I_DSI_CMD_TX_REG(255),
1018 	.name		= "mipi-dsi",
1019 };
1020 
1021 static int sun6i_dsi_bind(struct device *dev, struct device *master,
1022 			 void *data)
1023 {
1024 	struct drm_device *drm = data;
1025 	struct sun4i_drv *drv = drm->dev_private;
1026 	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
1027 	int ret;
1028 
1029 	if (!dsi->panel)
1030 		return -EPROBE_DEFER;
1031 
1032 	dsi->drv = drv;
1033 
1034 	drm_encoder_helper_add(&dsi->encoder,
1035 			       &sun6i_dsi_enc_helper_funcs);
1036 	ret = drm_encoder_init(drm,
1037 			       &dsi->encoder,
1038 			       &sun6i_dsi_enc_funcs,
1039 			       DRM_MODE_ENCODER_DSI,
1040 			       NULL);
1041 	if (ret) {
1042 		dev_err(dsi->dev, "Couldn't initialise the DSI encoder\n");
1043 		return ret;
1044 	}
1045 	dsi->encoder.possible_crtcs = BIT(0);
1046 
1047 	drm_connector_helper_add(&dsi->connector,
1048 				 &sun6i_dsi_connector_helper_funcs);
1049 	ret = drm_connector_init(drm, &dsi->connector,
1050 				 &sun6i_dsi_connector_funcs,
1051 				 DRM_MODE_CONNECTOR_DSI);
1052 	if (ret) {
1053 		dev_err(dsi->dev,
1054 			"Couldn't initialise the DSI connector\n");
1055 		goto err_cleanup_connector;
1056 	}
1057 
1058 	drm_connector_attach_encoder(&dsi->connector, &dsi->encoder);
1059 	drm_panel_attach(dsi->panel, &dsi->connector);
1060 
1061 	return 0;
1062 
1063 err_cleanup_connector:
1064 	drm_encoder_cleanup(&dsi->encoder);
1065 	return ret;
1066 }
1067 
1068 static void sun6i_dsi_unbind(struct device *dev, struct device *master,
1069 			    void *data)
1070 {
1071 	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
1072 
1073 	drm_panel_detach(dsi->panel);
1074 }
1075 
1076 static const struct component_ops sun6i_dsi_ops = {
1077 	.bind	= sun6i_dsi_bind,
1078 	.unbind	= sun6i_dsi_unbind,
1079 };
1080 
1081 static int sun6i_dsi_probe(struct platform_device *pdev)
1082 {
1083 	struct device *dev = &pdev->dev;
1084 	struct sun6i_dsi *dsi;
1085 	struct resource *res;
1086 	void __iomem *base;
1087 	int ret;
1088 
1089 	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
1090 	if (!dsi)
1091 		return -ENOMEM;
1092 	dev_set_drvdata(dev, dsi);
1093 	dsi->dev = dev;
1094 	dsi->host.ops = &sun6i_dsi_host_ops;
1095 	dsi->host.dev = dev;
1096 
1097 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1098 	base = devm_ioremap_resource(dev, res);
1099 	if (IS_ERR(base)) {
1100 		dev_err(dev, "Couldn't map the DSI encoder registers\n");
1101 		return PTR_ERR(base);
1102 	}
1103 
1104 	dsi->regulator = devm_regulator_get(dev, "vcc-dsi");
1105 	if (IS_ERR(dsi->regulator)) {
1106 		dev_err(dev, "Couldn't get VCC-DSI supply\n");
1107 		return PTR_ERR(dsi->regulator);
1108 	}
1109 
1110 	dsi->regs = devm_regmap_init_mmio_clk(dev, "bus", base,
1111 					      &sun6i_dsi_regmap_config);
1112 	if (IS_ERR(dsi->regs)) {
1113 		dev_err(dev, "Couldn't create the DSI encoder regmap\n");
1114 		return PTR_ERR(dsi->regs);
1115 	}
1116 
1117 	dsi->reset = devm_reset_control_get_shared(dev, NULL);
1118 	if (IS_ERR(dsi->reset)) {
1119 		dev_err(dev, "Couldn't get our reset line\n");
1120 		return PTR_ERR(dsi->reset);
1121 	}
1122 
1123 	dsi->mod_clk = devm_clk_get(dev, "mod");
1124 	if (IS_ERR(dsi->mod_clk)) {
1125 		dev_err(dev, "Couldn't get the DSI mod clock\n");
1126 		return PTR_ERR(dsi->mod_clk);
1127 	}
1128 
1129 	/*
1130 	 * In order to operate properly, that clock seems to be always
1131 	 * set to 297MHz.
1132 	 */
1133 	clk_set_rate_exclusive(dsi->mod_clk, 297000000);
1134 
1135 	dsi->dphy = devm_phy_get(dev, "dphy");
1136 	if (IS_ERR(dsi->dphy)) {
1137 		dev_err(dev, "Couldn't get the MIPI D-PHY\n");
1138 		ret = PTR_ERR(dsi->dphy);
1139 		goto err_unprotect_clk;
1140 	}
1141 
1142 	pm_runtime_enable(dev);
1143 
1144 	ret = mipi_dsi_host_register(&dsi->host);
1145 	if (ret) {
1146 		dev_err(dev, "Couldn't register MIPI-DSI host\n");
1147 		goto err_pm_disable;
1148 	}
1149 
1150 	ret = component_add(&pdev->dev, &sun6i_dsi_ops);
1151 	if (ret) {
1152 		dev_err(dev, "Couldn't register our component\n");
1153 		goto err_remove_dsi_host;
1154 	}
1155 
1156 	return 0;
1157 
1158 err_remove_dsi_host:
1159 	mipi_dsi_host_unregister(&dsi->host);
1160 err_pm_disable:
1161 	pm_runtime_disable(dev);
1162 err_unprotect_clk:
1163 	clk_rate_exclusive_put(dsi->mod_clk);
1164 	return ret;
1165 }
1166 
1167 static int sun6i_dsi_remove(struct platform_device *pdev)
1168 {
1169 	struct device *dev = &pdev->dev;
1170 	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
1171 
1172 	component_del(&pdev->dev, &sun6i_dsi_ops);
1173 	mipi_dsi_host_unregister(&dsi->host);
1174 	pm_runtime_disable(dev);
1175 	clk_rate_exclusive_put(dsi->mod_clk);
1176 
1177 	return 0;
1178 }
1179 
1180 static int __maybe_unused sun6i_dsi_runtime_resume(struct device *dev)
1181 {
1182 	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
1183 	int err;
1184 
1185 	err = regulator_enable(dsi->regulator);
1186 	if (err) {
1187 		dev_err(dsi->dev, "failed to enable VCC-DSI supply: %d\n", err);
1188 		return err;
1189 	}
1190 
1191 	reset_control_deassert(dsi->reset);
1192 	clk_prepare_enable(dsi->mod_clk);
1193 
1194 	/*
1195 	 * Enable the DSI block.
1196 	 *
1197 	 * Some part of it can only be done once we get a number of
1198 	 * lanes, see sun6i_dsi_inst_init
1199 	 */
1200 	regmap_write(dsi->regs, SUN6I_DSI_CTL_REG, SUN6I_DSI_CTL_EN);
1201 
1202 	regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL0_REG,
1203 		     SUN6I_DSI_BASIC_CTL0_ECC_EN | SUN6I_DSI_BASIC_CTL0_CRC_EN);
1204 
1205 	regmap_write(dsi->regs, SUN6I_DSI_TRANS_START_REG, 10);
1206 	regmap_write(dsi->regs, SUN6I_DSI_TRANS_ZERO_REG, 0);
1207 
1208 	if (dsi->device)
1209 		sun6i_dsi_inst_init(dsi, dsi->device);
1210 
1211 	regmap_write(dsi->regs, SUN6I_DSI_DEBUG_DATA_REG, 0xff);
1212 
1213 	return 0;
1214 }
1215 
1216 static int __maybe_unused sun6i_dsi_runtime_suspend(struct device *dev)
1217 {
1218 	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
1219 
1220 	clk_disable_unprepare(dsi->mod_clk);
1221 	reset_control_assert(dsi->reset);
1222 	regulator_disable(dsi->regulator);
1223 
1224 	return 0;
1225 }
1226 
1227 static const struct dev_pm_ops sun6i_dsi_pm_ops = {
1228 	SET_RUNTIME_PM_OPS(sun6i_dsi_runtime_suspend,
1229 			   sun6i_dsi_runtime_resume,
1230 			   NULL)
1231 };
1232 
1233 static const struct of_device_id sun6i_dsi_of_table[] = {
1234 	{ .compatible = "allwinner,sun6i-a31-mipi-dsi" },
1235 	{ }
1236 };
1237 MODULE_DEVICE_TABLE(of, sun6i_dsi_of_table);
1238 
1239 static struct platform_driver sun6i_dsi_platform_driver = {
1240 	.probe		= sun6i_dsi_probe,
1241 	.remove		= sun6i_dsi_remove,
1242 	.driver		= {
1243 		.name		= "sun6i-mipi-dsi",
1244 		.of_match_table	= sun6i_dsi_of_table,
1245 		.pm		= &sun6i_dsi_pm_ops,
1246 	},
1247 };
1248 module_platform_driver(sun6i_dsi_platform_driver);
1249 
1250 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1251 MODULE_DESCRIPTION("Allwinner A31 DSI Driver");
1252 MODULE_LICENSE("GPL");
1253