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