xref: /openbmc/linux/drivers/gpu/drm/sun4i/sun4i_tcon.c (revision faa16bc4)
1 /*
2  * Copyright (C) 2015 Free Electrons
3  * Copyright (C) 2015 NextThing Co
4  *
5  * Maxime Ripard <maxime.ripard@free-electrons.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  */
12 
13 #include <drm/drmP.h>
14 #include <drm/drm_atomic_helper.h>
15 #include <drm/drm_crtc.h>
16 #include <drm/drm_crtc_helper.h>
17 #include <drm/drm_encoder.h>
18 #include <drm/drm_modes.h>
19 #include <drm/drm_of.h>
20 #include <drm/drm_panel.h>
21 
22 #include <uapi/drm/drm_mode.h>
23 
24 #include <linux/component.h>
25 #include <linux/ioport.h>
26 #include <linux/of_address.h>
27 #include <linux/of_device.h>
28 #include <linux/of_irq.h>
29 #include <linux/regmap.h>
30 #include <linux/reset.h>
31 
32 #include "sun4i_crtc.h"
33 #include "sun4i_dotclock.h"
34 #include "sun4i_drv.h"
35 #include "sun4i_lvds.h"
36 #include "sun4i_rgb.h"
37 #include "sun4i_tcon.h"
38 #include "sun6i_mipi_dsi.h"
39 #include "sunxi_engine.h"
40 
41 static struct drm_connector *sun4i_tcon_get_connector(const struct drm_encoder *encoder)
42 {
43 	struct drm_connector *connector;
44 	struct drm_connector_list_iter iter;
45 
46 	drm_connector_list_iter_begin(encoder->dev, &iter);
47 	drm_for_each_connector_iter(connector, &iter)
48 		if (connector->encoder == encoder) {
49 			drm_connector_list_iter_end(&iter);
50 			return connector;
51 		}
52 	drm_connector_list_iter_end(&iter);
53 
54 	return NULL;
55 }
56 
57 static int sun4i_tcon_get_pixel_depth(const struct drm_encoder *encoder)
58 {
59 	struct drm_connector *connector;
60 	struct drm_display_info *info;
61 
62 	connector = sun4i_tcon_get_connector(encoder);
63 	if (!connector)
64 		return -EINVAL;
65 
66 	info = &connector->display_info;
67 	if (info->num_bus_formats != 1)
68 		return -EINVAL;
69 
70 	switch (info->bus_formats[0]) {
71 	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
72 		return 18;
73 
74 	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
75 	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
76 		return 24;
77 	}
78 
79 	return -EINVAL;
80 }
81 
82 static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
83 					  bool enabled)
84 {
85 	struct clk *clk;
86 
87 	switch (channel) {
88 	case 0:
89 		WARN_ON(!tcon->quirks->has_channel_0);
90 		regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
91 				   SUN4I_TCON0_CTL_TCON_ENABLE,
92 				   enabled ? SUN4I_TCON0_CTL_TCON_ENABLE : 0);
93 		clk = tcon->dclk;
94 		break;
95 	case 1:
96 		WARN_ON(!tcon->quirks->has_channel_1);
97 		regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
98 				   SUN4I_TCON1_CTL_TCON_ENABLE,
99 				   enabled ? SUN4I_TCON1_CTL_TCON_ENABLE : 0);
100 		clk = tcon->sclk1;
101 		break;
102 	default:
103 		DRM_WARN("Unknown channel... doing nothing\n");
104 		return;
105 	}
106 
107 	if (enabled) {
108 		clk_prepare_enable(clk);
109 		clk_rate_exclusive_get(clk);
110 	} else {
111 		clk_rate_exclusive_put(clk);
112 		clk_disable_unprepare(clk);
113 	}
114 }
115 
116 static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
117 				       const struct drm_encoder *encoder,
118 				       bool enabled)
119 {
120 	if (enabled) {
121 		u8 val;
122 
123 		regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
124 				   SUN4I_TCON0_LVDS_IF_EN,
125 				   SUN4I_TCON0_LVDS_IF_EN);
126 
127 		/*
128 		 * As their name suggest, these values only apply to the A31
129 		 * and later SoCs. We'll have to rework this when merging
130 		 * support for the older SoCs.
131 		 */
132 		regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
133 			     SUN6I_TCON0_LVDS_ANA0_C(2) |
134 			     SUN6I_TCON0_LVDS_ANA0_V(3) |
135 			     SUN6I_TCON0_LVDS_ANA0_PD(2) |
136 			     SUN6I_TCON0_LVDS_ANA0_EN_LDO);
137 		udelay(2);
138 
139 		regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
140 				   SUN6I_TCON0_LVDS_ANA0_EN_MB,
141 				   SUN6I_TCON0_LVDS_ANA0_EN_MB);
142 		udelay(2);
143 
144 		regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
145 				   SUN6I_TCON0_LVDS_ANA0_EN_DRVC,
146 				   SUN6I_TCON0_LVDS_ANA0_EN_DRVC);
147 
148 		if (sun4i_tcon_get_pixel_depth(encoder) == 18)
149 			val = 7;
150 		else
151 			val = 0xf;
152 
153 		regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
154 				  SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
155 				  SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
156 	} else {
157 		regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
158 				   SUN4I_TCON0_LVDS_IF_EN, 0);
159 	}
160 }
161 
162 void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
163 			   const struct drm_encoder *encoder,
164 			   bool enabled)
165 {
166 	bool is_lvds = false;
167 	int channel;
168 
169 	switch (encoder->encoder_type) {
170 	case DRM_MODE_ENCODER_LVDS:
171 		is_lvds = true;
172 		/* Fallthrough */
173 	case DRM_MODE_ENCODER_DSI:
174 	case DRM_MODE_ENCODER_NONE:
175 		channel = 0;
176 		break;
177 	case DRM_MODE_ENCODER_TMDS:
178 	case DRM_MODE_ENCODER_TVDAC:
179 		channel = 1;
180 		break;
181 	default:
182 		DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
183 		return;
184 	}
185 
186 	if (is_lvds && !enabled)
187 		sun4i_tcon_lvds_set_status(tcon, encoder, false);
188 
189 	regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
190 			   SUN4I_TCON_GCTL_TCON_ENABLE,
191 			   enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0);
192 
193 	if (is_lvds && enabled)
194 		sun4i_tcon_lvds_set_status(tcon, encoder, true);
195 
196 	sun4i_tcon_channel_set_status(tcon, channel, enabled);
197 }
198 
199 void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
200 {
201 	u32 mask, val = 0;
202 
203 	DRM_DEBUG_DRIVER("%sabling VBLANK interrupt\n", enable ? "En" : "Dis");
204 
205 	mask = SUN4I_TCON_GINT0_VBLANK_ENABLE(0) |
206 		SUN4I_TCON_GINT0_VBLANK_ENABLE(1) |
207 		SUN4I_TCON_GINT0_TCON0_TRI_FINISH_ENABLE;
208 
209 	if (enable)
210 		val = mask;
211 
212 	regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG, mask, val);
213 }
214 EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
215 
216 /*
217  * This function is a helper for TCON output muxing. The TCON output
218  * muxing control register in earlier SoCs (without the TCON TOP block)
219  * are located in TCON0. This helper returns a pointer to TCON0's
220  * sun4i_tcon structure, or NULL if not found.
221  */
222 static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm)
223 {
224 	struct sun4i_drv *drv = drm->dev_private;
225 	struct sun4i_tcon *tcon;
226 
227 	list_for_each_entry(tcon, &drv->tcon_list, list)
228 		if (tcon->id == 0)
229 			return tcon;
230 
231 	dev_warn(drm->dev,
232 		 "TCON0 not found, display output muxing may not work\n");
233 
234 	return NULL;
235 }
236 
237 void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
238 			const struct drm_encoder *encoder)
239 {
240 	int ret = -ENOTSUPP;
241 
242 	if (tcon->quirks->set_mux)
243 		ret = tcon->quirks->set_mux(tcon, encoder);
244 
245 	DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s: %d\n",
246 			 encoder->name, encoder->crtc->name, ret);
247 }
248 
249 static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode,
250 				    int channel)
251 {
252 	int delay = mode->vtotal - mode->vdisplay;
253 
254 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
255 		delay /= 2;
256 
257 	if (channel == 1)
258 		delay -= 2;
259 
260 	delay = min(delay, 30);
261 
262 	DRM_DEBUG_DRIVER("TCON %d clock delay %u\n", channel, delay);
263 
264 	return delay;
265 }
266 
267 static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
268 					const struct drm_display_mode *mode)
269 {
270 	/* Configure the dot clock */
271 	clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
272 
273 	/* Set the resolution */
274 	regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
275 		     SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
276 		     SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
277 }
278 
279 static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon,
280 				     struct mipi_dsi_device *device,
281 				     const struct drm_display_mode *mode)
282 {
283 	u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
284 	u8 lanes = device->lanes;
285 	u32 block_space, start_delay;
286 	u32 tcon_div;
287 
288 	tcon->dclk_min_div = 4;
289 	tcon->dclk_max_div = 127;
290 
291 	sun4i_tcon0_mode_set_common(tcon, mode);
292 
293 	regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
294 			   SUN4I_TCON0_CTL_IF_MASK,
295 			   SUN4I_TCON0_CTL_IF_8080);
296 
297 	regmap_write(tcon->regs, SUN4I_TCON_ECC_FIFO_REG,
298 		     SUN4I_TCON_ECC_FIFO_EN);
299 
300 	regmap_write(tcon->regs, SUN4I_TCON0_CPU_IF_REG,
301 		     SUN4I_TCON0_CPU_IF_MODE_DSI |
302 		     SUN4I_TCON0_CPU_IF_TRI_FIFO_FLUSH |
303 		     SUN4I_TCON0_CPU_IF_TRI_FIFO_EN |
304 		     SUN4I_TCON0_CPU_IF_TRI_EN);
305 
306 	/*
307 	 * This looks suspicious, but it works...
308 	 *
309 	 * The datasheet says that this should be set higher than 20 *
310 	 * pixel cycle, but it's not clear what a pixel cycle is.
311 	 */
312 	regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
313 	tcon_div &= GENMASK(6, 0);
314 	block_space = mode->htotal * bpp / (tcon_div * lanes);
315 	block_space -= mode->hdisplay + 40;
316 
317 	regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
318 		     SUN4I_TCON0_CPU_TRI0_BLOCK_SPACE(block_space) |
319 		     SUN4I_TCON0_CPU_TRI0_BLOCK_SIZE(mode->hdisplay));
320 
321 	regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI1_REG,
322 		     SUN4I_TCON0_CPU_TRI1_BLOCK_NUM(mode->vdisplay));
323 
324 	start_delay = (mode->crtc_vtotal - mode->crtc_vdisplay - 10 - 1);
325 	start_delay = start_delay * mode->crtc_htotal * 149;
326 	start_delay = start_delay / (mode->crtc_clock / 1000) / 8;
327 	regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI2_REG,
328 		     SUN4I_TCON0_CPU_TRI2_TRANS_START_SET(10) |
329 		     SUN4I_TCON0_CPU_TRI2_START_DELAY(start_delay));
330 
331 	/*
332 	 * The Allwinner BSP has a comment that the period should be
333 	 * the display clock * 15, but uses an hardcoded 3000...
334 	 */
335 	regmap_write(tcon->regs, SUN4I_TCON_SAFE_PERIOD_REG,
336 		     SUN4I_TCON_SAFE_PERIOD_NUM(3000) |
337 		     SUN4I_TCON_SAFE_PERIOD_MODE(3));
338 
339 	/* Enable the output on the pins */
340 	regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG,
341 		     0xe0000000);
342 }
343 
344 static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
345 				      const struct drm_encoder *encoder,
346 				      const struct drm_display_mode *mode)
347 {
348 	unsigned int bp;
349 	u8 clk_delay;
350 	u32 reg, val = 0;
351 
352 	WARN_ON(!tcon->quirks->has_channel_0);
353 
354 	tcon->dclk_min_div = 7;
355 	tcon->dclk_max_div = 7;
356 	sun4i_tcon0_mode_set_common(tcon, mode);
357 
358 	/* Adjust clock delay */
359 	clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
360 	regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
361 			   SUN4I_TCON0_CTL_CLK_DELAY_MASK,
362 			   SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
363 
364 	/*
365 	 * This is called a backporch in the register documentation,
366 	 * but it really is the back porch + hsync
367 	 */
368 	bp = mode->crtc_htotal - mode->crtc_hsync_start;
369 	DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
370 			 mode->crtc_htotal, bp);
371 
372 	/* Set horizontal display timings */
373 	regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
374 		     SUN4I_TCON0_BASIC1_H_TOTAL(mode->htotal) |
375 		     SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
376 
377 	/*
378 	 * This is called a backporch in the register documentation,
379 	 * but it really is the back porch + hsync
380 	 */
381 	bp = mode->crtc_vtotal - mode->crtc_vsync_start;
382 	DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
383 			 mode->crtc_vtotal, bp);
384 
385 	/* Set vertical display timings */
386 	regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
387 		     SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
388 		     SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
389 
390 	reg = SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0 |
391 		SUN4I_TCON0_LVDS_IF_DATA_POL_NORMAL |
392 		SUN4I_TCON0_LVDS_IF_CLK_POL_NORMAL;
393 	if (sun4i_tcon_get_pixel_depth(encoder) == 24)
394 		reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS;
395 	else
396 		reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS;
397 
398 	regmap_write(tcon->regs, SUN4I_TCON0_LVDS_IF_REG, reg);
399 
400 	/* Setup the polarity of the various signals */
401 	if (!(mode->flags & DRM_MODE_FLAG_PHSYNC))
402 		val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
403 
404 	if (!(mode->flags & DRM_MODE_FLAG_PVSYNC))
405 		val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
406 
407 	regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val);
408 
409 	/* Map output pins to channel 0 */
410 	regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
411 			   SUN4I_TCON_GCTL_IOMAP_MASK,
412 			   SUN4I_TCON_GCTL_IOMAP_TCON0);
413 
414 	/* Enable the output on the pins */
415 	regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);
416 }
417 
418 static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
419 				     const struct drm_display_mode *mode)
420 {
421 	struct drm_panel *panel = tcon->panel;
422 	struct drm_connector *connector = panel->connector;
423 	struct drm_display_info display_info = connector->display_info;
424 	unsigned int bp, hsync, vsync;
425 	u8 clk_delay;
426 	u32 val = 0;
427 
428 	WARN_ON(!tcon->quirks->has_channel_0);
429 
430 	tcon->dclk_min_div = 6;
431 	tcon->dclk_max_div = 127;
432 	sun4i_tcon0_mode_set_common(tcon, mode);
433 
434 	/* Adjust clock delay */
435 	clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
436 	regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
437 			   SUN4I_TCON0_CTL_CLK_DELAY_MASK,
438 			   SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
439 
440 	/*
441 	 * This is called a backporch in the register documentation,
442 	 * but it really is the back porch + hsync
443 	 */
444 	bp = mode->crtc_htotal - mode->crtc_hsync_start;
445 	DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
446 			 mode->crtc_htotal, bp);
447 
448 	/* Set horizontal display timings */
449 	regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
450 		     SUN4I_TCON0_BASIC1_H_TOTAL(mode->crtc_htotal) |
451 		     SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
452 
453 	/*
454 	 * This is called a backporch in the register documentation,
455 	 * but it really is the back porch + hsync
456 	 */
457 	bp = mode->crtc_vtotal - mode->crtc_vsync_start;
458 	DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
459 			 mode->crtc_vtotal, bp);
460 
461 	/* Set vertical display timings */
462 	regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
463 		     SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
464 		     SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
465 
466 	/* Set Hsync and Vsync length */
467 	hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
468 	vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
469 	DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync, vsync);
470 	regmap_write(tcon->regs, SUN4I_TCON0_BASIC3_REG,
471 		     SUN4I_TCON0_BASIC3_V_SYNC(vsync) |
472 		     SUN4I_TCON0_BASIC3_H_SYNC(hsync));
473 
474 	/* Setup the polarity of the various signals */
475 	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
476 		val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
477 
478 	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
479 		val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
480 
481 	/*
482 	 * On A20 and similar SoCs, the only way to achieve Positive Edge
483 	 * (Rising Edge), is setting dclk clock phase to 2/3(240°).
484 	 * By default TCON works in Negative Edge(Falling Edge),
485 	 * this is why phase is set to 0 in that case.
486 	 * Unfortunately there's no way to logically invert dclk through
487 	 * IO_POL register.
488 	 * The only acceptable way to work, triple checked with scope,
489 	 * is using clock phase set to 0° for Negative Edge and set to 240°
490 	 * for Positive Edge.
491 	 * On A33 and similar SoCs there would be a 90° phase option,
492 	 * but it divides also dclk by 2.
493 	 * Following code is a way to avoid quirks all around TCON
494 	 * and DOTCLOCK drivers.
495 	 */
496 	if (display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
497 		clk_set_phase(tcon->dclk, 240);
498 
499 	if (display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
500 		clk_set_phase(tcon->dclk, 0);
501 
502 	regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG,
503 			   SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE,
504 			   val);
505 
506 	/* Map output pins to channel 0 */
507 	regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
508 			   SUN4I_TCON_GCTL_IOMAP_MASK,
509 			   SUN4I_TCON_GCTL_IOMAP_TCON0);
510 
511 	/* Enable the output on the pins */
512 	regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0);
513 }
514 
515 static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
516 				 const struct drm_display_mode *mode)
517 {
518 	unsigned int bp, hsync, vsync, vtotal;
519 	u8 clk_delay;
520 	u32 val;
521 
522 	WARN_ON(!tcon->quirks->has_channel_1);
523 
524 	/* Configure the dot clock */
525 	clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000);
526 
527 	/* Adjust clock delay */
528 	clk_delay = sun4i_tcon_get_clk_delay(mode, 1);
529 	regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
530 			   SUN4I_TCON1_CTL_CLK_DELAY_MASK,
531 			   SUN4I_TCON1_CTL_CLK_DELAY(clk_delay));
532 
533 	/* Set interlaced mode */
534 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
535 		val = SUN4I_TCON1_CTL_INTERLACE_ENABLE;
536 	else
537 		val = 0;
538 	regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
539 			   SUN4I_TCON1_CTL_INTERLACE_ENABLE,
540 			   val);
541 
542 	/* Set the input resolution */
543 	regmap_write(tcon->regs, SUN4I_TCON1_BASIC0_REG,
544 		     SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay) |
545 		     SUN4I_TCON1_BASIC0_Y(mode->crtc_vdisplay));
546 
547 	/* Set the upscaling resolution */
548 	regmap_write(tcon->regs, SUN4I_TCON1_BASIC1_REG,
549 		     SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay) |
550 		     SUN4I_TCON1_BASIC1_Y(mode->crtc_vdisplay));
551 
552 	/* Set the output resolution */
553 	regmap_write(tcon->regs, SUN4I_TCON1_BASIC2_REG,
554 		     SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay) |
555 		     SUN4I_TCON1_BASIC2_Y(mode->crtc_vdisplay));
556 
557 	/* Set horizontal display timings */
558 	bp = mode->crtc_htotal - mode->crtc_hsync_start;
559 	DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
560 			 mode->htotal, bp);
561 	regmap_write(tcon->regs, SUN4I_TCON1_BASIC3_REG,
562 		     SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal) |
563 		     SUN4I_TCON1_BASIC3_H_BACKPORCH(bp));
564 
565 	bp = mode->crtc_vtotal - mode->crtc_vsync_start;
566 	DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
567 			 mode->crtc_vtotal, bp);
568 
569 	/*
570 	 * The vertical resolution needs to be doubled in all
571 	 * cases. We could use crtc_vtotal and always multiply by two,
572 	 * but that leads to a rounding error in interlace when vtotal
573 	 * is odd.
574 	 *
575 	 * This happens with TV's PAL for example, where vtotal will
576 	 * be 625, crtc_vtotal 312, and thus crtc_vtotal * 2 will be
577 	 * 624, which apparently confuses the hardware.
578 	 *
579 	 * To work around this, we will always use vtotal, and
580 	 * multiply by two only if we're not in interlace.
581 	 */
582 	vtotal = mode->vtotal;
583 	if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
584 		vtotal = vtotal * 2;
585 
586 	/* Set vertical display timings */
587 	regmap_write(tcon->regs, SUN4I_TCON1_BASIC4_REG,
588 		     SUN4I_TCON1_BASIC4_V_TOTAL(vtotal) |
589 		     SUN4I_TCON1_BASIC4_V_BACKPORCH(bp));
590 
591 	/* Set Hsync and Vsync length */
592 	hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
593 	vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
594 	DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync, vsync);
595 	regmap_write(tcon->regs, SUN4I_TCON1_BASIC5_REG,
596 		     SUN4I_TCON1_BASIC5_V_SYNC(vsync) |
597 		     SUN4I_TCON1_BASIC5_H_SYNC(hsync));
598 
599 	/* Map output pins to channel 1 */
600 	regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
601 			   SUN4I_TCON_GCTL_IOMAP_MASK,
602 			   SUN4I_TCON_GCTL_IOMAP_TCON1);
603 }
604 
605 void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
606 			 const struct drm_encoder *encoder,
607 			 const struct drm_display_mode *mode)
608 {
609 	struct sun6i_dsi *dsi;
610 
611 	switch (encoder->encoder_type) {
612 	case DRM_MODE_ENCODER_DSI:
613 		/*
614 		 * This is not really elegant, but it's the "cleaner"
615 		 * way I could think of...
616 		 */
617 		dsi = encoder_to_sun6i_dsi(encoder);
618 		sun4i_tcon0_mode_set_cpu(tcon, dsi->device, mode);
619 		break;
620 	case DRM_MODE_ENCODER_LVDS:
621 		sun4i_tcon0_mode_set_lvds(tcon, encoder, mode);
622 		break;
623 	case DRM_MODE_ENCODER_NONE:
624 		sun4i_tcon0_mode_set_rgb(tcon, mode);
625 		sun4i_tcon_set_mux(tcon, 0, encoder);
626 		break;
627 	case DRM_MODE_ENCODER_TVDAC:
628 	case DRM_MODE_ENCODER_TMDS:
629 		sun4i_tcon1_mode_set(tcon, mode);
630 		sun4i_tcon_set_mux(tcon, 1, encoder);
631 		break;
632 	default:
633 		DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
634 	}
635 }
636 EXPORT_SYMBOL(sun4i_tcon_mode_set);
637 
638 static void sun4i_tcon_finish_page_flip(struct drm_device *dev,
639 					struct sun4i_crtc *scrtc)
640 {
641 	unsigned long flags;
642 
643 	spin_lock_irqsave(&dev->event_lock, flags);
644 	if (scrtc->event) {
645 		drm_crtc_send_vblank_event(&scrtc->crtc, scrtc->event);
646 		drm_crtc_vblank_put(&scrtc->crtc);
647 		scrtc->event = NULL;
648 	}
649 	spin_unlock_irqrestore(&dev->event_lock, flags);
650 }
651 
652 static irqreturn_t sun4i_tcon_handler(int irq, void *private)
653 {
654 	struct sun4i_tcon *tcon = private;
655 	struct drm_device *drm = tcon->drm;
656 	struct sun4i_crtc *scrtc = tcon->crtc;
657 	struct sunxi_engine *engine = scrtc->engine;
658 	unsigned int status;
659 
660 	regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status);
661 
662 	if (!(status & (SUN4I_TCON_GINT0_VBLANK_INT(0) |
663 			SUN4I_TCON_GINT0_VBLANK_INT(1) |
664 			SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT)))
665 		return IRQ_NONE;
666 
667 	drm_crtc_handle_vblank(&scrtc->crtc);
668 	sun4i_tcon_finish_page_flip(drm, scrtc);
669 
670 	/* Acknowledge the interrupt */
671 	regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG,
672 			   SUN4I_TCON_GINT0_VBLANK_INT(0) |
673 			   SUN4I_TCON_GINT0_VBLANK_INT(1) |
674 			   SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT,
675 			   0);
676 
677 	if (engine->ops->vblank_quirk)
678 		engine->ops->vblank_quirk(engine);
679 
680 	return IRQ_HANDLED;
681 }
682 
683 static int sun4i_tcon_init_clocks(struct device *dev,
684 				  struct sun4i_tcon *tcon)
685 {
686 	tcon->clk = devm_clk_get(dev, "ahb");
687 	if (IS_ERR(tcon->clk)) {
688 		dev_err(dev, "Couldn't get the TCON bus clock\n");
689 		return PTR_ERR(tcon->clk);
690 	}
691 	clk_prepare_enable(tcon->clk);
692 
693 	if (tcon->quirks->has_channel_0) {
694 		tcon->sclk0 = devm_clk_get(dev, "tcon-ch0");
695 		if (IS_ERR(tcon->sclk0)) {
696 			dev_err(dev, "Couldn't get the TCON channel 0 clock\n");
697 			return PTR_ERR(tcon->sclk0);
698 		}
699 	}
700 
701 	if (tcon->quirks->has_channel_1) {
702 		tcon->sclk1 = devm_clk_get(dev, "tcon-ch1");
703 		if (IS_ERR(tcon->sclk1)) {
704 			dev_err(dev, "Couldn't get the TCON channel 1 clock\n");
705 			return PTR_ERR(tcon->sclk1);
706 		}
707 	}
708 
709 	return 0;
710 }
711 
712 static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon)
713 {
714 	clk_disable_unprepare(tcon->clk);
715 }
716 
717 static int sun4i_tcon_init_irq(struct device *dev,
718 			       struct sun4i_tcon *tcon)
719 {
720 	struct platform_device *pdev = to_platform_device(dev);
721 	int irq, ret;
722 
723 	irq = platform_get_irq(pdev, 0);
724 	if (irq < 0) {
725 		dev_err(dev, "Couldn't retrieve the TCON interrupt\n");
726 		return irq;
727 	}
728 
729 	ret = devm_request_irq(dev, irq, sun4i_tcon_handler, 0,
730 			       dev_name(dev), tcon);
731 	if (ret) {
732 		dev_err(dev, "Couldn't request the IRQ\n");
733 		return ret;
734 	}
735 
736 	return 0;
737 }
738 
739 static struct regmap_config sun4i_tcon_regmap_config = {
740 	.reg_bits	= 32,
741 	.val_bits	= 32,
742 	.reg_stride	= 4,
743 	.max_register	= 0x800,
744 };
745 
746 static int sun4i_tcon_init_regmap(struct device *dev,
747 				  struct sun4i_tcon *tcon)
748 {
749 	struct platform_device *pdev = to_platform_device(dev);
750 	struct resource *res;
751 	void __iomem *regs;
752 
753 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
754 	regs = devm_ioremap_resource(dev, res);
755 	if (IS_ERR(regs))
756 		return PTR_ERR(regs);
757 
758 	tcon->regs = devm_regmap_init_mmio(dev, regs,
759 					   &sun4i_tcon_regmap_config);
760 	if (IS_ERR(tcon->regs)) {
761 		dev_err(dev, "Couldn't create the TCON regmap\n");
762 		return PTR_ERR(tcon->regs);
763 	}
764 
765 	/* Make sure the TCON is disabled and all IRQs are off */
766 	regmap_write(tcon->regs, SUN4I_TCON_GCTL_REG, 0);
767 	regmap_write(tcon->regs, SUN4I_TCON_GINT0_REG, 0);
768 	regmap_write(tcon->regs, SUN4I_TCON_GINT1_REG, 0);
769 
770 	/* Disable IO lines and set them to tristate */
771 	regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, ~0);
772 	regmap_write(tcon->regs, SUN4I_TCON1_IO_TRI_REG, ~0);
773 
774 	return 0;
775 }
776 
777 /*
778  * On SoCs with the old display pipeline design (Display Engine 1.0),
779  * the TCON is always tied to just one backend. Hence we can traverse
780  * the of_graph upwards to find the backend our tcon is connected to,
781  * and take its ID as our own.
782  *
783  * We can either identify backends from their compatible strings, which
784  * means maintaining a large list of them. Or, since the backend is
785  * registered and binded before the TCON, we can just go through the
786  * list of registered backends and compare the device node.
787  *
788  * As the structures now store engines instead of backends, here this
789  * function in fact searches the corresponding engine, and the ID is
790  * requested via the get_id function of the engine.
791  */
792 static struct sunxi_engine *
793 sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
794 				struct device_node *node)
795 {
796 	struct device_node *port, *ep, *remote;
797 	struct sunxi_engine *engine = ERR_PTR(-EINVAL);
798 
799 	port = of_graph_get_port_by_id(node, 0);
800 	if (!port)
801 		return ERR_PTR(-EINVAL);
802 
803 	/*
804 	 * This only works if there is only one path from the TCON
805 	 * to any display engine. Otherwise the probe order of the
806 	 * TCONs and display engines is not guaranteed. They may
807 	 * either bind to the wrong one, or worse, bind to the same
808 	 * one if additional checks are not done.
809 	 *
810 	 * Bail out if there are multiple input connections.
811 	 */
812 	if (of_get_available_child_count(port) != 1)
813 		goto out_put_port;
814 
815 	/* Get the first connection without specifying an ID */
816 	ep = of_get_next_available_child(port, NULL);
817 	if (!ep)
818 		goto out_put_port;
819 
820 	remote = of_graph_get_remote_port_parent(ep);
821 	if (!remote)
822 		goto out_put_ep;
823 
824 	/* does this node match any registered engines? */
825 	list_for_each_entry(engine, &drv->engine_list, list)
826 		if (remote == engine->node)
827 			goto out_put_remote;
828 
829 	/* keep looking through upstream ports */
830 	engine = sun4i_tcon_find_engine_traverse(drv, remote);
831 
832 out_put_remote:
833 	of_node_put(remote);
834 out_put_ep:
835 	of_node_put(ep);
836 out_put_port:
837 	of_node_put(port);
838 
839 	return engine;
840 }
841 
842 /*
843  * The device tree binding says that the remote endpoint ID of any
844  * connection between components, up to and including the TCON, of
845  * the display pipeline should be equal to the actual ID of the local
846  * component. Thus we can look at any one of the input connections of
847  * the TCONs, and use that connection's remote endpoint ID as our own.
848  *
849  * Since the user of this function already finds the input port,
850  * the port is passed in directly without further checks.
851  */
852 static int sun4i_tcon_of_get_id_from_port(struct device_node *port)
853 {
854 	struct device_node *ep;
855 	int ret = -EINVAL;
856 
857 	/* try finding an upstream endpoint */
858 	for_each_available_child_of_node(port, ep) {
859 		struct device_node *remote;
860 		u32 reg;
861 
862 		remote = of_graph_get_remote_endpoint(ep);
863 		if (!remote)
864 			continue;
865 
866 		ret = of_property_read_u32(remote, "reg", &reg);
867 		if (ret)
868 			continue;
869 
870 		ret = reg;
871 	}
872 
873 	return ret;
874 }
875 
876 /*
877  * Once we know the TCON's id, we can look through the list of
878  * engines to find a matching one. We assume all engines have
879  * been probed and added to the list.
880  */
881 static struct sunxi_engine *sun4i_tcon_get_engine_by_id(struct sun4i_drv *drv,
882 							int id)
883 {
884 	struct sunxi_engine *engine;
885 
886 	list_for_each_entry(engine, &drv->engine_list, list)
887 		if (engine->id == id)
888 			return engine;
889 
890 	return ERR_PTR(-EINVAL);
891 }
892 
893 /*
894  * On SoCs with the old display pipeline design (Display Engine 1.0),
895  * we assumed the TCON was always tied to just one backend. However
896  * this proved not to be the case. On the A31, the TCON can select
897  * either backend as its source. On the A20 (and likely on the A10),
898  * the backend can choose which TCON to output to.
899  *
900  * The device tree binding says that the remote endpoint ID of any
901  * connection between components, up to and including the TCON, of
902  * the display pipeline should be equal to the actual ID of the local
903  * component. Thus we should be able to look at any one of the input
904  * connections of the TCONs, and use that connection's remote endpoint
905  * ID as our own.
906  *
907  * However  the connections between the backend and TCON were assumed
908  * to be always singular, and their endpoit IDs were all incorrectly
909  * set to 0. This means for these old device trees, we cannot just look
910  * up the remote endpoint ID of a TCON input endpoint. TCON1 would be
911  * incorrectly identified as TCON0.
912  *
913  * This function first checks if the TCON node has 2 input endpoints.
914  * If so, then the device tree is a corrected version, and it will use
915  * sun4i_tcon_of_get_id() and sun4i_tcon_get_engine_by_id() from above
916  * to fetch the ID and engine directly. If not, then it is likely an
917  * old device trees, where the endpoint IDs were incorrect, but did not
918  * have endpoint connections between the backend and TCON across
919  * different display pipelines. It will fall back to the old method of
920  * traversing the  of_graph to try and find a matching engine by device
921  * node.
922  *
923  * In the case of single display pipeline device trees, either method
924  * works.
925  */
926 static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv,
927 						   struct device_node *node)
928 {
929 	struct device_node *port;
930 	struct sunxi_engine *engine;
931 
932 	port = of_graph_get_port_by_id(node, 0);
933 	if (!port)
934 		return ERR_PTR(-EINVAL);
935 
936 	/*
937 	 * Is this a corrected device tree with cross pipeline
938 	 * connections between the backend and TCON?
939 	 */
940 	if (of_get_child_count(port) > 1) {
941 		/* Get our ID directly from an upstream endpoint */
942 		int id = sun4i_tcon_of_get_id_from_port(port);
943 
944 		/* Get our engine by matching our ID */
945 		engine = sun4i_tcon_get_engine_by_id(drv, id);
946 
947 		of_node_put(port);
948 		return engine;
949 	}
950 
951 	/* Fallback to old method by traversing input endpoints */
952 	of_node_put(port);
953 	return sun4i_tcon_find_engine_traverse(drv, node);
954 }
955 
956 static int sun4i_tcon_bind(struct device *dev, struct device *master,
957 			   void *data)
958 {
959 	struct drm_device *drm = data;
960 	struct sun4i_drv *drv = drm->dev_private;
961 	struct sunxi_engine *engine;
962 	struct device_node *remote;
963 	struct sun4i_tcon *tcon;
964 	struct reset_control *edp_rstc;
965 	bool has_lvds_rst, has_lvds_alt, can_lvds;
966 	int ret;
967 
968 	engine = sun4i_tcon_find_engine(drv, dev->of_node);
969 	if (IS_ERR(engine)) {
970 		dev_err(dev, "Couldn't find matching engine\n");
971 		return -EPROBE_DEFER;
972 	}
973 
974 	tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL);
975 	if (!tcon)
976 		return -ENOMEM;
977 	dev_set_drvdata(dev, tcon);
978 	tcon->drm = drm;
979 	tcon->dev = dev;
980 	tcon->id = engine->id;
981 	tcon->quirks = of_device_get_match_data(dev);
982 
983 	tcon->lcd_rst = devm_reset_control_get(dev, "lcd");
984 	if (IS_ERR(tcon->lcd_rst)) {
985 		dev_err(dev, "Couldn't get our reset line\n");
986 		return PTR_ERR(tcon->lcd_rst);
987 	}
988 
989 	if (tcon->quirks->needs_edp_reset) {
990 		edp_rstc = devm_reset_control_get_shared(dev, "edp");
991 		if (IS_ERR(edp_rstc)) {
992 			dev_err(dev, "Couldn't get edp reset line\n");
993 			return PTR_ERR(edp_rstc);
994 		}
995 
996 		ret = reset_control_deassert(edp_rstc);
997 		if (ret) {
998 			dev_err(dev, "Couldn't deassert edp reset line\n");
999 			return ret;
1000 		}
1001 	}
1002 
1003 	/* Make sure our TCON is reset */
1004 	ret = reset_control_reset(tcon->lcd_rst);
1005 	if (ret) {
1006 		dev_err(dev, "Couldn't deassert our reset line\n");
1007 		return ret;
1008 	}
1009 
1010 	if (tcon->quirks->supports_lvds) {
1011 		/*
1012 		 * This can only be made optional since we've had DT
1013 		 * nodes without the LVDS reset properties.
1014 		 *
1015 		 * If the property is missing, just disable LVDS, and
1016 		 * print a warning.
1017 		 */
1018 		tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
1019 		if (IS_ERR(tcon->lvds_rst)) {
1020 			dev_err(dev, "Couldn't get our reset line\n");
1021 			return PTR_ERR(tcon->lvds_rst);
1022 		} else if (tcon->lvds_rst) {
1023 			has_lvds_rst = true;
1024 			reset_control_reset(tcon->lvds_rst);
1025 		} else {
1026 			has_lvds_rst = false;
1027 		}
1028 
1029 		/*
1030 		 * This can only be made optional since we've had DT
1031 		 * nodes without the LVDS reset properties.
1032 		 *
1033 		 * If the property is missing, just disable LVDS, and
1034 		 * print a warning.
1035 		 */
1036 		if (tcon->quirks->has_lvds_alt) {
1037 			tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
1038 			if (IS_ERR(tcon->lvds_pll)) {
1039 				if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
1040 					has_lvds_alt = false;
1041 				} else {
1042 					dev_err(dev, "Couldn't get the LVDS PLL\n");
1043 					return PTR_ERR(tcon->lvds_pll);
1044 				}
1045 			} else {
1046 				has_lvds_alt = true;
1047 			}
1048 		}
1049 
1050 		if (!has_lvds_rst ||
1051 		    (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
1052 			dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
1053 			dev_warn(dev, "LVDS output disabled\n");
1054 			can_lvds = false;
1055 		} else {
1056 			can_lvds = true;
1057 		}
1058 	} else {
1059 		can_lvds = false;
1060 	}
1061 
1062 	ret = sun4i_tcon_init_clocks(dev, tcon);
1063 	if (ret) {
1064 		dev_err(dev, "Couldn't init our TCON clocks\n");
1065 		goto err_assert_reset;
1066 	}
1067 
1068 	ret = sun4i_tcon_init_regmap(dev, tcon);
1069 	if (ret) {
1070 		dev_err(dev, "Couldn't init our TCON regmap\n");
1071 		goto err_free_clocks;
1072 	}
1073 
1074 	if (tcon->quirks->has_channel_0) {
1075 		ret = sun4i_dclk_create(dev, tcon);
1076 		if (ret) {
1077 			dev_err(dev, "Couldn't create our TCON dot clock\n");
1078 			goto err_free_clocks;
1079 		}
1080 	}
1081 
1082 	ret = sun4i_tcon_init_irq(dev, tcon);
1083 	if (ret) {
1084 		dev_err(dev, "Couldn't init our TCON interrupts\n");
1085 		goto err_free_dotclock;
1086 	}
1087 
1088 	tcon->crtc = sun4i_crtc_init(drm, engine, tcon);
1089 	if (IS_ERR(tcon->crtc)) {
1090 		dev_err(dev, "Couldn't create our CRTC\n");
1091 		ret = PTR_ERR(tcon->crtc);
1092 		goto err_free_dotclock;
1093 	}
1094 
1095 	/*
1096 	 * If we have an LVDS panel connected to the TCON, we should
1097 	 * just probe the LVDS connector. Otherwise, just probe RGB as
1098 	 * we used to.
1099 	 */
1100 	remote = of_graph_get_remote_node(dev->of_node, 1, 0);
1101 	if (of_device_is_compatible(remote, "panel-lvds"))
1102 		if (can_lvds)
1103 			ret = sun4i_lvds_init(drm, tcon);
1104 		else
1105 			ret = -EINVAL;
1106 	else
1107 		ret = sun4i_rgb_init(drm, tcon);
1108 	of_node_put(remote);
1109 
1110 	if (ret < 0)
1111 		goto err_free_dotclock;
1112 
1113 	if (tcon->quirks->needs_de_be_mux) {
1114 		/*
1115 		 * We assume there is no dynamic muxing of backends
1116 		 * and TCONs, so we select the backend with same ID.
1117 		 *
1118 		 * While dynamic selection might be interesting, since
1119 		 * the CRTC is tied to the TCON, while the layers are
1120 		 * tied to the backends, this means, we will need to
1121 		 * switch between groups of layers. There might not be
1122 		 * a way to represent this constraint in DRM.
1123 		 */
1124 		regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
1125 				   SUN4I_TCON0_CTL_SRC_SEL_MASK,
1126 				   tcon->id);
1127 		regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
1128 				   SUN4I_TCON1_CTL_SRC_SEL_MASK,
1129 				   tcon->id);
1130 	}
1131 
1132 	list_add_tail(&tcon->list, &drv->tcon_list);
1133 
1134 	return 0;
1135 
1136 err_free_dotclock:
1137 	if (tcon->quirks->has_channel_0)
1138 		sun4i_dclk_free(tcon);
1139 err_free_clocks:
1140 	sun4i_tcon_free_clocks(tcon);
1141 err_assert_reset:
1142 	reset_control_assert(tcon->lcd_rst);
1143 	return ret;
1144 }
1145 
1146 static void sun4i_tcon_unbind(struct device *dev, struct device *master,
1147 			      void *data)
1148 {
1149 	struct sun4i_tcon *tcon = dev_get_drvdata(dev);
1150 
1151 	list_del(&tcon->list);
1152 	if (tcon->quirks->has_channel_0)
1153 		sun4i_dclk_free(tcon);
1154 	sun4i_tcon_free_clocks(tcon);
1155 }
1156 
1157 static const struct component_ops sun4i_tcon_ops = {
1158 	.bind	= sun4i_tcon_bind,
1159 	.unbind	= sun4i_tcon_unbind,
1160 };
1161 
1162 static int sun4i_tcon_probe(struct platform_device *pdev)
1163 {
1164 	struct device_node *node = pdev->dev.of_node;
1165 	struct drm_bridge *bridge;
1166 	struct drm_panel *panel;
1167 	int ret;
1168 
1169 	ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge);
1170 	if (ret == -EPROBE_DEFER)
1171 		return ret;
1172 
1173 	return component_add(&pdev->dev, &sun4i_tcon_ops);
1174 }
1175 
1176 static int sun4i_tcon_remove(struct platform_device *pdev)
1177 {
1178 	component_del(&pdev->dev, &sun4i_tcon_ops);
1179 
1180 	return 0;
1181 }
1182 
1183 /* platform specific TCON muxing callbacks */
1184 static int sun4i_a10_tcon_set_mux(struct sun4i_tcon *tcon,
1185 				  const struct drm_encoder *encoder)
1186 {
1187 	struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
1188 	u32 shift;
1189 
1190 	if (!tcon0)
1191 		return -EINVAL;
1192 
1193 	switch (encoder->encoder_type) {
1194 	case DRM_MODE_ENCODER_TMDS:
1195 		/* HDMI */
1196 		shift = 8;
1197 		break;
1198 	default:
1199 		return -EINVAL;
1200 	}
1201 
1202 	regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG,
1203 			   0x3 << shift, tcon->id << shift);
1204 
1205 	return 0;
1206 }
1207 
1208 static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon,
1209 				  const struct drm_encoder *encoder)
1210 {
1211 	u32 val;
1212 
1213 	if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
1214 		val = 1;
1215 	else
1216 		val = 0;
1217 
1218 	/*
1219 	 * FIXME: Undocumented bits
1220 	 */
1221 	return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val);
1222 }
1223 
1224 static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon,
1225 			      const struct drm_encoder *encoder)
1226 {
1227 	struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
1228 	u32 shift;
1229 
1230 	if (!tcon0)
1231 		return -EINVAL;
1232 
1233 	switch (encoder->encoder_type) {
1234 	case DRM_MODE_ENCODER_TMDS:
1235 		/* HDMI */
1236 		shift = 8;
1237 		break;
1238 	default:
1239 		/* TODO A31 has MIPI DSI but A31s does not */
1240 		return -EINVAL;
1241 	}
1242 
1243 	regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG,
1244 			   0x3 << shift, tcon->id << shift);
1245 
1246 	return 0;
1247 }
1248 
1249 static const struct sun4i_tcon_quirks sun4i_a10_quirks = {
1250 	.has_channel_0		= true,
1251 	.has_channel_1		= true,
1252 	.set_mux		= sun4i_a10_tcon_set_mux,
1253 };
1254 
1255 static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
1256 	.has_channel_0		= true,
1257 	.has_channel_1		= true,
1258 	.set_mux		= sun5i_a13_tcon_set_mux,
1259 };
1260 
1261 static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
1262 	.has_channel_0		= true,
1263 	.has_channel_1		= true,
1264 	.has_lvds_alt		= true,
1265 	.needs_de_be_mux	= true,
1266 	.set_mux		= sun6i_tcon_set_mux,
1267 };
1268 
1269 static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
1270 	.has_channel_0		= true,
1271 	.has_channel_1		= true,
1272 	.needs_de_be_mux	= true,
1273 };
1274 
1275 static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
1276 	.has_channel_0		= true,
1277 	.has_channel_1		= true,
1278 	/* Same display pipeline structure as A10 */
1279 	.set_mux		= sun4i_a10_tcon_set_mux,
1280 };
1281 
1282 static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
1283 	.has_channel_0		= true,
1284 	.has_lvds_alt		= true,
1285 };
1286 
1287 static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
1288 	.supports_lvds		= true,
1289 	.has_channel_0		= true,
1290 };
1291 
1292 static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = {
1293 	.has_channel_1		= true,
1294 };
1295 
1296 static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
1297 	.has_channel_0		= true,
1298 };
1299 
1300 static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = {
1301 	.has_channel_0	= true,
1302 	.needs_edp_reset = true,
1303 };
1304 
1305 static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = {
1306 	.has_channel_1	= true,
1307 	.needs_edp_reset = true,
1308 };
1309 
1310 /* sun4i_drv uses this list to check if a device node is a TCON */
1311 const struct of_device_id sun4i_tcon_of_table[] = {
1312 	{ .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
1313 	{ .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks },
1314 	{ .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks },
1315 	{ .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
1316 	{ .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks },
1317 	{ .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
1318 	{ .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks },
1319 	{ .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks },
1320 	{ .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
1321 	{ .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks },
1322 	{ .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i_a80_tcon_tv_quirks },
1323 	{ }
1324 };
1325 MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
1326 EXPORT_SYMBOL(sun4i_tcon_of_table);
1327 
1328 static struct platform_driver sun4i_tcon_platform_driver = {
1329 	.probe		= sun4i_tcon_probe,
1330 	.remove		= sun4i_tcon_remove,
1331 	.driver		= {
1332 		.name		= "sun4i-tcon",
1333 		.of_match_table	= sun4i_tcon_of_table,
1334 	},
1335 };
1336 module_platform_driver(sun4i_tcon_platform_driver);
1337 
1338 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1339 MODULE_DESCRIPTION("Allwinner A10 Timing Controller Driver");
1340 MODULE_LICENSE("GPL");
1341