1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2015 Free Electrons
4 * Copyright (C) 2015 NextThing Co
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
9 #include <linux/component.h>
10 #include <linux/ioport.h>
11 #include <linux/media-bus-format.h>
12 #include <linux/module.h>
14 #include <linux/of_platform.h>
15 #include <linux/platform_device.h>
16 #include <linux/regmap.h>
17 #include <linux/reset.h>
19 #include <drm/drm_atomic_helper.h>
20 #include <drm/drm_bridge.h>
21 #include <drm/drm_connector.h>
22 #include <drm/drm_crtc.h>
23 #include <drm/drm_encoder.h>
24 #include <drm/drm_modes.h>
25 #include <drm/drm_of.h>
26 #include <drm/drm_panel.h>
27 #include <drm/drm_print.h>
28 #include <drm/drm_probe_helper.h>
29 #include <drm/drm_vblank.h>
31 #include <uapi/drm/drm_mode.h>
33 #include "sun4i_crtc.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 "sun4i_tcon_dclk.h"
40 #include "sun8i_tcon_top.h"
41 #include "sunxi_engine.h"
43 static struct drm_connector
*sun4i_tcon_get_connector(const struct drm_encoder
*encoder
)
45 struct drm_connector
*connector
;
46 struct drm_connector_list_iter iter
;
48 drm_connector_list_iter_begin(encoder
->dev
, &iter
);
49 drm_for_each_connector_iter(connector
, &iter
)
50 if (connector
->encoder
== encoder
) {
51 drm_connector_list_iter_end(&iter
);
54 drm_connector_list_iter_end(&iter
);
59 static int sun4i_tcon_get_pixel_depth(const struct drm_encoder
*encoder
)
61 struct drm_connector
*connector
;
62 struct drm_display_info
*info
;
64 connector
= sun4i_tcon_get_connector(encoder
);
68 info
= &connector
->display_info
;
69 if (info
->num_bus_formats
!= 1)
72 switch (info
->bus_formats
[0]) {
73 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG
:
76 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA
:
77 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG
:
84 static void sun4i_tcon_channel_set_status(struct sun4i_tcon
*tcon
, int channel
,
91 WARN_ON(!tcon
->quirks
->has_channel_0
);
92 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_CTL_REG
,
93 SUN4I_TCON0_CTL_TCON_ENABLE
,
94 enabled
? SUN4I_TCON0_CTL_TCON_ENABLE
: 0);
98 WARN_ON(!tcon
->quirks
->has_channel_1
);
99 regmap_update_bits(tcon
->regs
, SUN4I_TCON1_CTL_REG
,
100 SUN4I_TCON1_CTL_TCON_ENABLE
,
101 enabled
? SUN4I_TCON1_CTL_TCON_ENABLE
: 0);
105 DRM_WARN("Unknown channel... doing nothing\n");
110 clk_prepare_enable(clk
);
111 clk_rate_exclusive_get(clk
);
113 clk_rate_exclusive_put(clk
);
114 clk_disable_unprepare(clk
);
118 static void sun4i_tcon_setup_lvds_phy(struct sun4i_tcon
*tcon
,
119 const struct drm_encoder
*encoder
)
121 regmap_write(tcon
->regs
, SUN4I_TCON0_LVDS_ANA0_REG
,
122 SUN4I_TCON0_LVDS_ANA0_CK_EN
|
123 SUN4I_TCON0_LVDS_ANA0_REG_V
|
124 SUN4I_TCON0_LVDS_ANA0_REG_C
|
125 SUN4I_TCON0_LVDS_ANA0_EN_MB
|
126 SUN4I_TCON0_LVDS_ANA0_PD
|
127 SUN4I_TCON0_LVDS_ANA0_DCHS
);
129 udelay(2); /* delay at least 1200 ns */
130 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_LVDS_ANA1_REG
,
131 SUN4I_TCON0_LVDS_ANA1_INIT
,
132 SUN4I_TCON0_LVDS_ANA1_INIT
);
133 udelay(1); /* delay at least 120 ns */
134 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_LVDS_ANA1_REG
,
135 SUN4I_TCON0_LVDS_ANA1_UPDATE
,
136 SUN4I_TCON0_LVDS_ANA1_UPDATE
);
137 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_LVDS_ANA0_REG
,
138 SUN4I_TCON0_LVDS_ANA0_EN_MB
,
139 SUN4I_TCON0_LVDS_ANA0_EN_MB
);
142 static void sun6i_tcon_setup_lvds_phy(struct sun4i_tcon
*tcon
,
143 const struct drm_encoder
*encoder
)
147 regmap_write(tcon
->regs
, SUN4I_TCON0_LVDS_ANA0_REG
,
148 SUN6I_TCON0_LVDS_ANA0_C(2) |
149 SUN6I_TCON0_LVDS_ANA0_V(3) |
150 SUN6I_TCON0_LVDS_ANA0_PD(2) |
151 SUN6I_TCON0_LVDS_ANA0_EN_LDO
);
154 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_LVDS_ANA0_REG
,
155 SUN6I_TCON0_LVDS_ANA0_EN_MB
,
156 SUN6I_TCON0_LVDS_ANA0_EN_MB
);
159 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_LVDS_ANA0_REG
,
160 SUN6I_TCON0_LVDS_ANA0_EN_DRVC
,
161 SUN6I_TCON0_LVDS_ANA0_EN_DRVC
);
163 if (sun4i_tcon_get_pixel_depth(encoder
) == 18)
168 regmap_write_bits(tcon
->regs
, SUN4I_TCON0_LVDS_ANA0_REG
,
169 SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
170 SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val
));
173 static void sun4i_tcon_lvds_set_status(struct sun4i_tcon
*tcon
,
174 const struct drm_encoder
*encoder
,
178 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_LVDS_IF_REG
,
179 SUN4I_TCON0_LVDS_IF_EN
,
180 SUN4I_TCON0_LVDS_IF_EN
);
181 if (tcon
->quirks
->setup_lvds_phy
)
182 tcon
->quirks
->setup_lvds_phy(tcon
, encoder
);
184 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_LVDS_IF_REG
,
185 SUN4I_TCON0_LVDS_IF_EN
, 0);
189 void sun4i_tcon_set_status(struct sun4i_tcon
*tcon
,
190 const struct drm_encoder
*encoder
,
193 bool is_lvds
= false;
196 switch (encoder
->encoder_type
) {
197 case DRM_MODE_ENCODER_LVDS
:
200 case DRM_MODE_ENCODER_DSI
:
201 case DRM_MODE_ENCODER_NONE
:
204 case DRM_MODE_ENCODER_TMDS
:
205 case DRM_MODE_ENCODER_TVDAC
:
209 DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
213 if (is_lvds
&& !enabled
)
214 sun4i_tcon_lvds_set_status(tcon
, encoder
, false);
216 regmap_update_bits(tcon
->regs
, SUN4I_TCON_GCTL_REG
,
217 SUN4I_TCON_GCTL_TCON_ENABLE
,
218 enabled
? SUN4I_TCON_GCTL_TCON_ENABLE
: 0);
220 if (is_lvds
&& enabled
)
221 sun4i_tcon_lvds_set_status(tcon
, encoder
, true);
223 sun4i_tcon_channel_set_status(tcon
, channel
, enabled
);
226 void sun4i_tcon_enable_vblank(struct sun4i_tcon
*tcon
, bool enable
)
230 DRM_DEBUG_DRIVER("%sabling VBLANK interrupt\n", enable
? "En" : "Dis");
232 mask
= SUN4I_TCON_GINT0_VBLANK_ENABLE(0) |
233 SUN4I_TCON_GINT0_VBLANK_ENABLE(1) |
234 SUN4I_TCON_GINT0_TCON0_TRI_FINISH_ENABLE
;
239 regmap_update_bits(tcon
->regs
, SUN4I_TCON_GINT0_REG
, mask
, val
);
241 EXPORT_SYMBOL(sun4i_tcon_enable_vblank
);
244 * This function is a helper for TCON output muxing. The TCON output
245 * muxing control register in earlier SoCs (without the TCON TOP block)
246 * are located in TCON0. This helper returns a pointer to TCON0's
247 * sun4i_tcon structure, or NULL if not found.
249 static struct sun4i_tcon
*sun4i_get_tcon0(struct drm_device
*drm
)
251 struct sun4i_drv
*drv
= drm
->dev_private
;
252 struct sun4i_tcon
*tcon
;
254 list_for_each_entry(tcon
, &drv
->tcon_list
, list
)
259 "TCON0 not found, display output muxing may not work\n");
264 static void sun4i_tcon_set_mux(struct sun4i_tcon
*tcon
, int channel
,
265 const struct drm_encoder
*encoder
)
269 if (tcon
->quirks
->set_mux
)
270 ret
= tcon
->quirks
->set_mux(tcon
, encoder
);
272 DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s: %d\n",
273 encoder
->name
, encoder
->crtc
->name
, ret
);
276 static int sun4i_tcon_get_clk_delay(const struct drm_display_mode
*mode
,
279 int delay
= mode
->vtotal
- mode
->vdisplay
;
281 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
287 delay
= min(delay
, 30);
289 DRM_DEBUG_DRIVER("TCON %d clock delay %u\n", channel
, delay
);
294 static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon
*tcon
,
295 const struct drm_connector
*connector
)
300 /* XXX Would this ever happen? */
305 * FIXME: Undocumented bits
307 * The whole dithering process and these parameters are not
308 * explained in the vendor documents or BSP kernel code.
310 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_SEED_PR_REG
, 0x11111111);
311 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_SEED_PG_REG
, 0x11111111);
312 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_SEED_PB_REG
, 0x11111111);
313 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_SEED_LR_REG
, 0x11111111);
314 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_SEED_LG_REG
, 0x11111111);
315 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_SEED_LB_REG
, 0x11111111);
316 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_TBL0_REG
, 0x01010000);
317 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_TBL1_REG
, 0x15151111);
318 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_TBL2_REG
, 0x57575555);
319 regmap_write(tcon
->regs
, SUN4I_TCON0_FRM_TBL3_REG
, 0x7f7f7777);
321 /* Do dithering if panel only supports 6 bits per color */
322 if (connector
->display_info
.bpc
== 6)
323 val
|= SUN4I_TCON0_FRM_CTL_EN
;
325 if (connector
->display_info
.num_bus_formats
== 1)
326 bus_format
= connector
->display_info
.bus_formats
[0];
328 /* Check the connection format */
329 switch (bus_format
) {
330 case MEDIA_BUS_FMT_RGB565_1X16
:
331 /* R and B components are only 5 bits deep */
332 val
|= SUN4I_TCON0_FRM_CTL_MODE_R
;
333 val
|= SUN4I_TCON0_FRM_CTL_MODE_B
;
335 case MEDIA_BUS_FMT_RGB666_1X18
:
336 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG
:
337 /* Fall through: enable dithering */
338 val
|= SUN4I_TCON0_FRM_CTL_EN
;
342 /* Write dithering settings */
343 regmap_write(tcon
->regs
, SUN4I_TCON_FRM_CTL_REG
, val
);
346 static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon
*tcon
,
347 const struct drm_encoder
*encoder
,
348 const struct drm_display_mode
*mode
)
350 /* TODO support normal CPU interface modes */
351 struct sun6i_dsi
*dsi
= encoder_to_sun6i_dsi(encoder
);
352 struct mipi_dsi_device
*device
= dsi
->device
;
353 u8 bpp
= mipi_dsi_pixel_format_to_bpp(device
->format
);
354 u8 lanes
= device
->lanes
;
355 u32 block_space
, start_delay
;
359 * dclk is required to run at 1/4 the DSI per-lane bit rate.
361 tcon
->dclk_min_div
= SUN6I_DSI_TCON_DIV
;
362 tcon
->dclk_max_div
= SUN6I_DSI_TCON_DIV
;
363 clk_set_rate(tcon
->dclk
, mode
->crtc_clock
* 1000 * (bpp
/ lanes
)
364 / SUN6I_DSI_TCON_DIV
);
366 /* Set the resolution */
367 regmap_write(tcon
->regs
, SUN4I_TCON0_BASIC0_REG
,
368 SUN4I_TCON0_BASIC0_X(mode
->crtc_hdisplay
) |
369 SUN4I_TCON0_BASIC0_Y(mode
->crtc_vdisplay
));
371 /* Set dithering if needed */
372 sun4i_tcon0_mode_set_dithering(tcon
, sun4i_tcon_get_connector(encoder
));
374 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_CTL_REG
,
375 SUN4I_TCON0_CTL_IF_MASK
,
376 SUN4I_TCON0_CTL_IF_8080
);
378 regmap_write(tcon
->regs
, SUN4I_TCON_ECC_FIFO_REG
,
379 SUN4I_TCON_ECC_FIFO_EN
);
381 regmap_write(tcon
->regs
, SUN4I_TCON0_CPU_IF_REG
,
382 SUN4I_TCON0_CPU_IF_MODE_DSI
|
383 SUN4I_TCON0_CPU_IF_TRI_FIFO_FLUSH
|
384 SUN4I_TCON0_CPU_IF_TRI_FIFO_EN
|
385 SUN4I_TCON0_CPU_IF_TRI_EN
);
388 * This looks suspicious, but it works...
390 * The datasheet says that this should be set higher than 20 *
391 * pixel cycle, but it's not clear what a pixel cycle is.
393 regmap_read(tcon
->regs
, SUN4I_TCON0_DCLK_REG
, &tcon_div
);
394 tcon_div
&= GENMASK(6, 0);
395 block_space
= mode
->htotal
* bpp
/ (tcon_div
* lanes
);
396 block_space
-= mode
->hdisplay
+ 40;
398 regmap_write(tcon
->regs
, SUN4I_TCON0_CPU_TRI0_REG
,
399 SUN4I_TCON0_CPU_TRI0_BLOCK_SPACE(block_space
) |
400 SUN4I_TCON0_CPU_TRI0_BLOCK_SIZE(mode
->hdisplay
));
402 regmap_write(tcon
->regs
, SUN4I_TCON0_CPU_TRI1_REG
,
403 SUN4I_TCON0_CPU_TRI1_BLOCK_NUM(mode
->vdisplay
));
405 start_delay
= (mode
->crtc_vtotal
- mode
->crtc_vdisplay
- 10 - 1);
406 start_delay
= start_delay
* mode
->crtc_htotal
* 149;
407 start_delay
= start_delay
/ (mode
->crtc_clock
/ 1000) / 8;
408 regmap_write(tcon
->regs
, SUN4I_TCON0_CPU_TRI2_REG
,
409 SUN4I_TCON0_CPU_TRI2_TRANS_START_SET(10) |
410 SUN4I_TCON0_CPU_TRI2_START_DELAY(start_delay
));
413 * The Allwinner BSP has a comment that the period should be
414 * the display clock * 15, but uses an hardcoded 3000...
416 regmap_write(tcon
->regs
, SUN4I_TCON_SAFE_PERIOD_REG
,
417 SUN4I_TCON_SAFE_PERIOD_NUM(3000) |
418 SUN4I_TCON_SAFE_PERIOD_MODE(3));
420 /* Enable the output on the pins */
421 regmap_write(tcon
->regs
, SUN4I_TCON0_IO_TRI_REG
,
425 static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon
*tcon
,
426 const struct drm_encoder
*encoder
,
427 const struct drm_display_mode
*mode
)
433 WARN_ON(!tcon
->quirks
->has_channel_0
);
435 tcon
->dclk_min_div
= 7;
436 tcon
->dclk_max_div
= 7;
437 clk_set_rate(tcon
->dclk
, mode
->crtc_clock
* 1000);
439 /* Set the resolution */
440 regmap_write(tcon
->regs
, SUN4I_TCON0_BASIC0_REG
,
441 SUN4I_TCON0_BASIC0_X(mode
->crtc_hdisplay
) |
442 SUN4I_TCON0_BASIC0_Y(mode
->crtc_vdisplay
));
444 /* Set dithering if needed */
445 sun4i_tcon0_mode_set_dithering(tcon
, sun4i_tcon_get_connector(encoder
));
447 /* Adjust clock delay */
448 clk_delay
= sun4i_tcon_get_clk_delay(mode
, 0);
449 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_CTL_REG
,
450 SUN4I_TCON0_CTL_CLK_DELAY_MASK
,
451 SUN4I_TCON0_CTL_CLK_DELAY(clk_delay
));
454 * This is called a backporch in the register documentation,
455 * but it really is the back porch + hsync
457 bp
= mode
->crtc_htotal
- mode
->crtc_hsync_start
;
458 DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
459 mode
->crtc_htotal
, bp
);
461 /* Set horizontal display timings */
462 regmap_write(tcon
->regs
, SUN4I_TCON0_BASIC1_REG
,
463 SUN4I_TCON0_BASIC1_H_TOTAL(mode
->htotal
) |
464 SUN4I_TCON0_BASIC1_H_BACKPORCH(bp
));
467 * This is called a backporch in the register documentation,
468 * but it really is the back porch + hsync
470 bp
= mode
->crtc_vtotal
- mode
->crtc_vsync_start
;
471 DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
472 mode
->crtc_vtotal
, bp
);
474 /* Set vertical display timings */
475 regmap_write(tcon
->regs
, SUN4I_TCON0_BASIC2_REG
,
476 SUN4I_TCON0_BASIC2_V_TOTAL(mode
->crtc_vtotal
* 2) |
477 SUN4I_TCON0_BASIC2_V_BACKPORCH(bp
));
479 reg
= SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0
;
480 if (sun4i_tcon_get_pixel_depth(encoder
) == 24)
481 reg
|= SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS
;
483 reg
|= SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS
;
485 regmap_write(tcon
->regs
, SUN4I_TCON0_LVDS_IF_REG
, reg
);
487 /* Setup the polarity of the various signals */
488 if (!(mode
->flags
& DRM_MODE_FLAG_PHSYNC
))
489 val
|= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE
;
491 if (!(mode
->flags
& DRM_MODE_FLAG_PVSYNC
))
492 val
|= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE
;
494 regmap_write(tcon
->regs
, SUN4I_TCON0_IO_POL_REG
, val
);
496 /* Map output pins to channel 0 */
497 regmap_update_bits(tcon
->regs
, SUN4I_TCON_GCTL_REG
,
498 SUN4I_TCON_GCTL_IOMAP_MASK
,
499 SUN4I_TCON_GCTL_IOMAP_TCON0
);
501 /* Enable the output on the pins */
502 regmap_write(tcon
->regs
, SUN4I_TCON0_IO_TRI_REG
, 0xe0000000);
505 static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon
*tcon
,
506 const struct drm_encoder
*encoder
,
507 const struct drm_display_mode
*mode
)
509 struct drm_connector
*connector
= sun4i_tcon_get_connector(encoder
);
510 const struct drm_display_info
*info
= &connector
->display_info
;
511 unsigned int bp
, hsync
, vsync
;
515 WARN_ON(!tcon
->quirks
->has_channel_0
);
517 tcon
->dclk_min_div
= tcon
->quirks
->dclk_min_div
;
518 tcon
->dclk_max_div
= 127;
519 clk_set_rate(tcon
->dclk
, mode
->crtc_clock
* 1000);
521 /* Set the resolution */
522 regmap_write(tcon
->regs
, SUN4I_TCON0_BASIC0_REG
,
523 SUN4I_TCON0_BASIC0_X(mode
->crtc_hdisplay
) |
524 SUN4I_TCON0_BASIC0_Y(mode
->crtc_vdisplay
));
526 /* Set dithering if needed */
527 sun4i_tcon0_mode_set_dithering(tcon
, connector
);
529 /* Adjust clock delay */
530 clk_delay
= sun4i_tcon_get_clk_delay(mode
, 0);
531 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_CTL_REG
,
532 SUN4I_TCON0_CTL_CLK_DELAY_MASK
,
533 SUN4I_TCON0_CTL_CLK_DELAY(clk_delay
));
536 * This is called a backporch in the register documentation,
537 * but it really is the back porch + hsync
539 bp
= mode
->crtc_htotal
- mode
->crtc_hsync_start
;
540 DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
541 mode
->crtc_htotal
, bp
);
543 /* Set horizontal display timings */
544 regmap_write(tcon
->regs
, SUN4I_TCON0_BASIC1_REG
,
545 SUN4I_TCON0_BASIC1_H_TOTAL(mode
->crtc_htotal
) |
546 SUN4I_TCON0_BASIC1_H_BACKPORCH(bp
));
549 * This is called a backporch in the register documentation,
550 * but it really is the back porch + hsync
552 bp
= mode
->crtc_vtotal
- mode
->crtc_vsync_start
;
553 DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
554 mode
->crtc_vtotal
, bp
);
556 /* Set vertical display timings */
557 regmap_write(tcon
->regs
, SUN4I_TCON0_BASIC2_REG
,
558 SUN4I_TCON0_BASIC2_V_TOTAL(mode
->crtc_vtotal
* 2) |
559 SUN4I_TCON0_BASIC2_V_BACKPORCH(bp
));
561 /* Set Hsync and Vsync length */
562 hsync
= mode
->crtc_hsync_end
- mode
->crtc_hsync_start
;
563 vsync
= mode
->crtc_vsync_end
- mode
->crtc_vsync_start
;
564 DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync
, vsync
);
565 regmap_write(tcon
->regs
, SUN4I_TCON0_BASIC3_REG
,
566 SUN4I_TCON0_BASIC3_V_SYNC(vsync
) |
567 SUN4I_TCON0_BASIC3_H_SYNC(hsync
));
569 /* Setup the polarity of the various signals */
570 if (mode
->flags
& DRM_MODE_FLAG_PHSYNC
)
571 val
|= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE
;
573 if (mode
->flags
& DRM_MODE_FLAG_PVSYNC
)
574 val
|= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE
;
576 if (info
->bus_flags
& DRM_BUS_FLAG_DE_LOW
)
577 val
|= SUN4I_TCON0_IO_POL_DE_NEGATIVE
;
579 if (info
->bus_flags
& DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE
)
580 val
|= SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE
;
582 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_IO_POL_REG
,
583 SUN4I_TCON0_IO_POL_HSYNC_POSITIVE
|
584 SUN4I_TCON0_IO_POL_VSYNC_POSITIVE
|
585 SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE
|
586 SUN4I_TCON0_IO_POL_DE_NEGATIVE
,
589 /* Map output pins to channel 0 */
590 regmap_update_bits(tcon
->regs
, SUN4I_TCON_GCTL_REG
,
591 SUN4I_TCON_GCTL_IOMAP_MASK
,
592 SUN4I_TCON_GCTL_IOMAP_TCON0
);
594 /* Enable the output on the pins */
595 regmap_write(tcon
->regs
, SUN4I_TCON0_IO_TRI_REG
, 0);
598 static void sun4i_tcon1_mode_set(struct sun4i_tcon
*tcon
,
599 const struct drm_display_mode
*mode
)
601 unsigned int bp
, hsync
, vsync
, vtotal
;
605 WARN_ON(!tcon
->quirks
->has_channel_1
);
607 /* Configure the dot clock */
608 clk_set_rate(tcon
->sclk1
, mode
->crtc_clock
* 1000);
610 /* Adjust clock delay */
611 clk_delay
= sun4i_tcon_get_clk_delay(mode
, 1);
612 regmap_update_bits(tcon
->regs
, SUN4I_TCON1_CTL_REG
,
613 SUN4I_TCON1_CTL_CLK_DELAY_MASK
,
614 SUN4I_TCON1_CTL_CLK_DELAY(clk_delay
));
616 /* Set interlaced mode */
617 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
618 val
= SUN4I_TCON1_CTL_INTERLACE_ENABLE
;
621 regmap_update_bits(tcon
->regs
, SUN4I_TCON1_CTL_REG
,
622 SUN4I_TCON1_CTL_INTERLACE_ENABLE
,
625 /* Set the input resolution */
626 regmap_write(tcon
->regs
, SUN4I_TCON1_BASIC0_REG
,
627 SUN4I_TCON1_BASIC0_X(mode
->crtc_hdisplay
) |
628 SUN4I_TCON1_BASIC0_Y(mode
->crtc_vdisplay
));
630 /* Set the upscaling resolution */
631 regmap_write(tcon
->regs
, SUN4I_TCON1_BASIC1_REG
,
632 SUN4I_TCON1_BASIC1_X(mode
->crtc_hdisplay
) |
633 SUN4I_TCON1_BASIC1_Y(mode
->crtc_vdisplay
));
635 /* Set the output resolution */
636 regmap_write(tcon
->regs
, SUN4I_TCON1_BASIC2_REG
,
637 SUN4I_TCON1_BASIC2_X(mode
->crtc_hdisplay
) |
638 SUN4I_TCON1_BASIC2_Y(mode
->crtc_vdisplay
));
640 /* Set horizontal display timings */
641 bp
= mode
->crtc_htotal
- mode
->crtc_hsync_start
;
642 DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
644 regmap_write(tcon
->regs
, SUN4I_TCON1_BASIC3_REG
,
645 SUN4I_TCON1_BASIC3_H_TOTAL(mode
->crtc_htotal
) |
646 SUN4I_TCON1_BASIC3_H_BACKPORCH(bp
));
648 bp
= mode
->crtc_vtotal
- mode
->crtc_vsync_start
;
649 DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
650 mode
->crtc_vtotal
, bp
);
653 * The vertical resolution needs to be doubled in all
654 * cases. We could use crtc_vtotal and always multiply by two,
655 * but that leads to a rounding error in interlace when vtotal
658 * This happens with TV's PAL for example, where vtotal will
659 * be 625, crtc_vtotal 312, and thus crtc_vtotal * 2 will be
660 * 624, which apparently confuses the hardware.
662 * To work around this, we will always use vtotal, and
663 * multiply by two only if we're not in interlace.
665 vtotal
= mode
->vtotal
;
666 if (!(mode
->flags
& DRM_MODE_FLAG_INTERLACE
))
669 /* Set vertical display timings */
670 regmap_write(tcon
->regs
, SUN4I_TCON1_BASIC4_REG
,
671 SUN4I_TCON1_BASIC4_V_TOTAL(vtotal
) |
672 SUN4I_TCON1_BASIC4_V_BACKPORCH(bp
));
674 /* Set Hsync and Vsync length */
675 hsync
= mode
->crtc_hsync_end
- mode
->crtc_hsync_start
;
676 vsync
= mode
->crtc_vsync_end
- mode
->crtc_vsync_start
;
677 DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync
, vsync
);
678 regmap_write(tcon
->regs
, SUN4I_TCON1_BASIC5_REG
,
679 SUN4I_TCON1_BASIC5_V_SYNC(vsync
) |
680 SUN4I_TCON1_BASIC5_H_SYNC(hsync
));
682 /* Setup the polarity of multiple signals */
683 if (tcon
->quirks
->polarity_in_ch0
) {
686 if (mode
->flags
& DRM_MODE_FLAG_PHSYNC
)
687 val
|= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE
;
689 if (mode
->flags
& DRM_MODE_FLAG_PVSYNC
)
690 val
|= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE
;
692 regmap_write(tcon
->regs
, SUN4I_TCON0_IO_POL_REG
, val
);
694 /* according to vendor driver, this bit must be always set */
695 val
= SUN4I_TCON1_IO_POL_UNKNOWN
;
697 if (mode
->flags
& DRM_MODE_FLAG_PHSYNC
)
698 val
|= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE
;
700 if (mode
->flags
& DRM_MODE_FLAG_PVSYNC
)
701 val
|= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE
;
703 regmap_write(tcon
->regs
, SUN4I_TCON1_IO_POL_REG
, val
);
706 /* Map output pins to channel 1 */
707 regmap_update_bits(tcon
->regs
, SUN4I_TCON_GCTL_REG
,
708 SUN4I_TCON_GCTL_IOMAP_MASK
,
709 SUN4I_TCON_GCTL_IOMAP_TCON1
);
712 void sun4i_tcon_mode_set(struct sun4i_tcon
*tcon
,
713 const struct drm_encoder
*encoder
,
714 const struct drm_display_mode
*mode
)
716 switch (encoder
->encoder_type
) {
717 case DRM_MODE_ENCODER_DSI
:
718 /* DSI is tied to special case of CPU interface */
719 sun4i_tcon0_mode_set_cpu(tcon
, encoder
, mode
);
721 case DRM_MODE_ENCODER_LVDS
:
722 sun4i_tcon0_mode_set_lvds(tcon
, encoder
, mode
);
724 case DRM_MODE_ENCODER_NONE
:
725 sun4i_tcon0_mode_set_rgb(tcon
, encoder
, mode
);
726 sun4i_tcon_set_mux(tcon
, 0, encoder
);
728 case DRM_MODE_ENCODER_TVDAC
:
729 case DRM_MODE_ENCODER_TMDS
:
730 sun4i_tcon1_mode_set(tcon
, mode
);
731 sun4i_tcon_set_mux(tcon
, 1, encoder
);
734 DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
737 EXPORT_SYMBOL(sun4i_tcon_mode_set
);
739 static void sun4i_tcon_finish_page_flip(struct drm_device
*dev
,
740 struct sun4i_crtc
*scrtc
)
744 spin_lock_irqsave(&dev
->event_lock
, flags
);
746 drm_crtc_send_vblank_event(&scrtc
->crtc
, scrtc
->event
);
747 drm_crtc_vblank_put(&scrtc
->crtc
);
750 spin_unlock_irqrestore(&dev
->event_lock
, flags
);
753 static irqreturn_t
sun4i_tcon_handler(int irq
, void *private)
755 struct sun4i_tcon
*tcon
= private;
756 struct drm_device
*drm
= tcon
->drm
;
757 struct sun4i_crtc
*scrtc
= tcon
->crtc
;
758 struct sunxi_engine
*engine
= scrtc
->engine
;
761 regmap_read(tcon
->regs
, SUN4I_TCON_GINT0_REG
, &status
);
763 if (!(status
& (SUN4I_TCON_GINT0_VBLANK_INT(0) |
764 SUN4I_TCON_GINT0_VBLANK_INT(1) |
765 SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT
)))
768 drm_crtc_handle_vblank(&scrtc
->crtc
);
769 sun4i_tcon_finish_page_flip(drm
, scrtc
);
771 /* Acknowledge the interrupt */
772 regmap_update_bits(tcon
->regs
, SUN4I_TCON_GINT0_REG
,
773 SUN4I_TCON_GINT0_VBLANK_INT(0) |
774 SUN4I_TCON_GINT0_VBLANK_INT(1) |
775 SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT
,
778 if (engine
->ops
->vblank_quirk
)
779 engine
->ops
->vblank_quirk(engine
);
784 static int sun4i_tcon_init_clocks(struct device
*dev
,
785 struct sun4i_tcon
*tcon
)
787 tcon
->clk
= devm_clk_get_enabled(dev
, "ahb");
788 if (IS_ERR(tcon
->clk
)) {
789 dev_err(dev
, "Couldn't get the TCON bus clock\n");
790 return PTR_ERR(tcon
->clk
);
793 if (tcon
->quirks
->has_channel_0
) {
794 tcon
->sclk0
= devm_clk_get_enabled(dev
, "tcon-ch0");
795 if (IS_ERR(tcon
->sclk0
)) {
796 dev_err(dev
, "Couldn't get the TCON channel 0 clock\n");
797 return PTR_ERR(tcon
->sclk0
);
801 if (tcon
->quirks
->has_channel_1
) {
802 tcon
->sclk1
= devm_clk_get(dev
, "tcon-ch1");
803 if (IS_ERR(tcon
->sclk1
)) {
804 dev_err(dev
, "Couldn't get the TCON channel 1 clock\n");
805 return PTR_ERR(tcon
->sclk1
);
812 static int sun4i_tcon_init_irq(struct device
*dev
,
813 struct sun4i_tcon
*tcon
)
815 struct platform_device
*pdev
= to_platform_device(dev
);
818 irq
= platform_get_irq(pdev
, 0);
822 ret
= devm_request_irq(dev
, irq
, sun4i_tcon_handler
, 0,
823 dev_name(dev
), tcon
);
825 dev_err(dev
, "Couldn't request the IRQ\n");
832 static const struct regmap_config sun4i_tcon_regmap_config
= {
836 .max_register
= 0x800,
839 static int sun4i_tcon_init_regmap(struct device
*dev
,
840 struct sun4i_tcon
*tcon
)
842 struct platform_device
*pdev
= to_platform_device(dev
);
845 regs
= devm_platform_ioremap_resource(pdev
, 0);
847 return PTR_ERR(regs
);
849 tcon
->regs
= devm_regmap_init_mmio(dev
, regs
,
850 &sun4i_tcon_regmap_config
);
851 if (IS_ERR(tcon
->regs
)) {
852 dev_err(dev
, "Couldn't create the TCON regmap\n");
853 return PTR_ERR(tcon
->regs
);
856 /* Make sure the TCON is disabled and all IRQs are off */
857 regmap_write(tcon
->regs
, SUN4I_TCON_GCTL_REG
, 0);
858 regmap_write(tcon
->regs
, SUN4I_TCON_GINT0_REG
, 0);
859 regmap_write(tcon
->regs
, SUN4I_TCON_GINT1_REG
, 0);
861 /* Disable IO lines and set them to tristate */
862 regmap_write(tcon
->regs
, SUN4I_TCON0_IO_TRI_REG
, ~0);
863 regmap_write(tcon
->regs
, SUN4I_TCON1_IO_TRI_REG
, ~0);
869 * On SoCs with the old display pipeline design (Display Engine 1.0),
870 * the TCON is always tied to just one backend. Hence we can traverse
871 * the of_graph upwards to find the backend our tcon is connected to,
872 * and take its ID as our own.
874 * We can either identify backends from their compatible strings, which
875 * means maintaining a large list of them. Or, since the backend is
876 * registered and binded before the TCON, we can just go through the
877 * list of registered backends and compare the device node.
879 * As the structures now store engines instead of backends, here this
880 * function in fact searches the corresponding engine, and the ID is
881 * requested via the get_id function of the engine.
883 static struct sunxi_engine
*
884 sun4i_tcon_find_engine_traverse(struct sun4i_drv
*drv
,
885 struct device_node
*node
,
888 struct device_node
*port
, *ep
, *remote
;
889 struct sunxi_engine
*engine
= ERR_PTR(-EINVAL
);
892 port
= of_graph_get_port_by_id(node
, port_id
);
894 return ERR_PTR(-EINVAL
);
897 * This only works if there is only one path from the TCON
898 * to any display engine. Otherwise the probe order of the
899 * TCONs and display engines is not guaranteed. They may
900 * either bind to the wrong one, or worse, bind to the same
901 * one if additional checks are not done.
903 * Bail out if there are multiple input connections.
905 if (of_get_available_child_count(port
) != 1)
908 /* Get the first connection without specifying an ID */
909 ep
= of_get_next_available_child(port
, NULL
);
913 remote
= of_graph_get_remote_port_parent(ep
);
917 /* does this node match any registered engines? */
918 list_for_each_entry(engine
, &drv
->engine_list
, list
)
919 if (remote
== engine
->node
)
923 * According to device tree binding input ports have even id
924 * number and output ports have odd id. Since component with
925 * more than one input and one output (TCON TOP) exits, correct
926 * remote input id has to be calculated by subtracting 1 from
927 * remote output id. If this for some reason can't be done, 0
928 * is used as input port id.
931 port
= of_graph_get_remote_port(ep
);
932 if (!of_property_read_u32(port
, "reg", ®
) && reg
> 0)
935 /* keep looking through upstream ports */
936 engine
= sun4i_tcon_find_engine_traverse(drv
, remote
, reg
);
949 * The device tree binding says that the remote endpoint ID of any
950 * connection between components, up to and including the TCON, of
951 * the display pipeline should be equal to the actual ID of the local
952 * component. Thus we can look at any one of the input connections of
953 * the TCONs, and use that connection's remote endpoint ID as our own.
955 * Since the user of this function already finds the input port,
956 * the port is passed in directly without further checks.
958 static int sun4i_tcon_of_get_id_from_port(struct device_node
*port
)
960 struct device_node
*ep
;
963 /* try finding an upstream endpoint */
964 for_each_available_child_of_node(port
, ep
) {
965 struct device_node
*remote
;
968 remote
= of_graph_get_remote_endpoint(ep
);
972 ret
= of_property_read_u32(remote
, "reg", ®
);
983 * Once we know the TCON's id, we can look through the list of
984 * engines to find a matching one. We assume all engines have
985 * been probed and added to the list.
987 static struct sunxi_engine
*sun4i_tcon_get_engine_by_id(struct sun4i_drv
*drv
,
990 struct sunxi_engine
*engine
;
992 list_for_each_entry(engine
, &drv
->engine_list
, list
)
993 if (engine
->id
== id
)
996 return ERR_PTR(-EINVAL
);
999 static bool sun4i_tcon_connected_to_tcon_top(struct device_node
*node
)
1001 struct device_node
*remote
;
1004 remote
= of_graph_get_remote_node(node
, 0, -1);
1006 ret
= !!(IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP
) &&
1007 of_match_node(sun8i_tcon_top_of_table
, remote
));
1008 of_node_put(remote
);
1014 static int sun4i_tcon_get_index(struct sun4i_drv
*drv
)
1016 struct list_head
*pos
;
1020 * Because TCON is added to the list at the end of the probe
1021 * (after this function is called), index of the current TCON
1022 * will be same as current TCON list size.
1024 list_for_each(pos
, &drv
->tcon_list
)
1031 * On SoCs with the old display pipeline design (Display Engine 1.0),
1032 * we assumed the TCON was always tied to just one backend. However
1033 * this proved not to be the case. On the A31, the TCON can select
1034 * either backend as its source. On the A20 (and likely on the A10),
1035 * the backend can choose which TCON to output to.
1037 * The device tree binding says that the remote endpoint ID of any
1038 * connection between components, up to and including the TCON, of
1039 * the display pipeline should be equal to the actual ID of the local
1040 * component. Thus we should be able to look at any one of the input
1041 * connections of the TCONs, and use that connection's remote endpoint
1044 * However the connections between the backend and TCON were assumed
1045 * to be always singular, and their endpoit IDs were all incorrectly
1046 * set to 0. This means for these old device trees, we cannot just look
1047 * up the remote endpoint ID of a TCON input endpoint. TCON1 would be
1048 * incorrectly identified as TCON0.
1050 * This function first checks if the TCON node has 2 input endpoints.
1051 * If so, then the device tree is a corrected version, and it will use
1052 * sun4i_tcon_of_get_id() and sun4i_tcon_get_engine_by_id() from above
1053 * to fetch the ID and engine directly. If not, then it is likely an
1054 * old device trees, where the endpoint IDs were incorrect, but did not
1055 * have endpoint connections between the backend and TCON across
1056 * different display pipelines. It will fall back to the old method of
1057 * traversing the of_graph to try and find a matching engine by device
1060 * In the case of single display pipeline device trees, either method
1063 static struct sunxi_engine
*sun4i_tcon_find_engine(struct sun4i_drv
*drv
,
1064 struct device_node
*node
)
1066 struct device_node
*port
;
1067 struct sunxi_engine
*engine
;
1069 port
= of_graph_get_port_by_id(node
, 0);
1071 return ERR_PTR(-EINVAL
);
1074 * Is this a corrected device tree with cross pipeline
1075 * connections between the backend and TCON?
1077 if (of_get_child_count(port
) > 1) {
1081 * When pipeline has the same number of TCONs and engines which
1082 * are represented by frontends/backends (DE1) or mixers (DE2),
1083 * we match them by their respective IDs. However, if pipeline
1084 * contains TCON TOP, chances are that there are either more
1085 * TCONs than engines (R40) or TCONs with non-consecutive ids.
1086 * (H6). In that case it's easier just use TCON index in list
1087 * as an id. That means that on R40, any 2 TCONs can be enabled
1088 * in DT out of 4 (there are 2 mixers). Due to the design of
1089 * TCON TOP, remaining 2 TCONs can't be connected to anything
1092 if (sun4i_tcon_connected_to_tcon_top(node
))
1093 id
= sun4i_tcon_get_index(drv
);
1095 id
= sun4i_tcon_of_get_id_from_port(port
);
1097 /* Get our engine by matching our ID */
1098 engine
= sun4i_tcon_get_engine_by_id(drv
, id
);
1104 /* Fallback to old method by traversing input endpoints */
1106 return sun4i_tcon_find_engine_traverse(drv
, node
, 0);
1109 static int sun4i_tcon_bind(struct device
*dev
, struct device
*master
,
1112 struct drm_device
*drm
= data
;
1113 struct sun4i_drv
*drv
= drm
->dev_private
;
1114 struct sunxi_engine
*engine
;
1115 struct device_node
*remote
;
1116 struct sun4i_tcon
*tcon
;
1117 struct reset_control
*edp_rstc
;
1118 bool has_lvds_rst
, has_lvds_alt
, can_lvds
;
1121 engine
= sun4i_tcon_find_engine(drv
, dev
->of_node
);
1122 if (IS_ERR(engine
)) {
1123 dev_err(dev
, "Couldn't find matching engine\n");
1124 return -EPROBE_DEFER
;
1127 tcon
= devm_kzalloc(dev
, sizeof(*tcon
), GFP_KERNEL
);
1130 dev_set_drvdata(dev
, tcon
);
1133 tcon
->id
= engine
->id
;
1134 tcon
->quirks
= of_device_get_match_data(dev
);
1136 tcon
->lcd_rst
= devm_reset_control_get(dev
, "lcd");
1137 if (IS_ERR(tcon
->lcd_rst
)) {
1138 dev_err(dev
, "Couldn't get our reset line\n");
1139 return PTR_ERR(tcon
->lcd_rst
);
1142 if (tcon
->quirks
->needs_edp_reset
) {
1143 edp_rstc
= devm_reset_control_get_shared(dev
, "edp");
1144 if (IS_ERR(edp_rstc
)) {
1145 dev_err(dev
, "Couldn't get edp reset line\n");
1146 return PTR_ERR(edp_rstc
);
1149 ret
= reset_control_deassert(edp_rstc
);
1151 dev_err(dev
, "Couldn't deassert edp reset line\n");
1156 /* Make sure our TCON is reset */
1157 ret
= reset_control_reset(tcon
->lcd_rst
);
1159 dev_err(dev
, "Couldn't deassert our reset line\n");
1163 if (tcon
->quirks
->supports_lvds
) {
1165 * This can only be made optional since we've had DT
1166 * nodes without the LVDS reset properties.
1168 * If the property is missing, just disable LVDS, and
1171 tcon
->lvds_rst
= devm_reset_control_get_optional(dev
, "lvds");
1172 if (IS_ERR(tcon
->lvds_rst
)) {
1173 dev_err(dev
, "Couldn't get our reset line\n");
1174 return PTR_ERR(tcon
->lvds_rst
);
1175 } else if (tcon
->lvds_rst
) {
1176 has_lvds_rst
= true;
1177 reset_control_reset(tcon
->lvds_rst
);
1179 has_lvds_rst
= false;
1183 * This can only be made optional since we've had DT
1184 * nodes without the LVDS reset properties.
1186 * If the property is missing, just disable LVDS, and
1189 if (tcon
->quirks
->has_lvds_alt
) {
1190 tcon
->lvds_pll
= devm_clk_get(dev
, "lvds-alt");
1191 if (IS_ERR(tcon
->lvds_pll
)) {
1192 if (PTR_ERR(tcon
->lvds_pll
) == -ENOENT
) {
1193 has_lvds_alt
= false;
1195 dev_err(dev
, "Couldn't get the LVDS PLL\n");
1196 return PTR_ERR(tcon
->lvds_pll
);
1199 has_lvds_alt
= true;
1203 if (!has_lvds_rst
||
1204 (tcon
->quirks
->has_lvds_alt
&& !has_lvds_alt
)) {
1205 dev_warn(dev
, "Missing LVDS properties, Please upgrade your DT\n");
1206 dev_warn(dev
, "LVDS output disabled\n");
1215 ret
= sun4i_tcon_init_clocks(dev
, tcon
);
1217 dev_err(dev
, "Couldn't init our TCON clocks\n");
1218 goto err_assert_reset
;
1221 ret
= sun4i_tcon_init_regmap(dev
, tcon
);
1223 dev_err(dev
, "Couldn't init our TCON regmap\n");
1224 goto err_assert_reset
;
1227 if (tcon
->quirks
->has_channel_0
) {
1228 ret
= sun4i_dclk_create(dev
, tcon
);
1230 dev_err(dev
, "Couldn't create our TCON dot clock\n");
1231 goto err_assert_reset
;
1235 ret
= sun4i_tcon_init_irq(dev
, tcon
);
1237 dev_err(dev
, "Couldn't init our TCON interrupts\n");
1241 tcon
->crtc
= sun4i_crtc_init(drm
, engine
, tcon
);
1242 if (IS_ERR(tcon
->crtc
)) {
1243 dev_err(dev
, "Couldn't create our CRTC\n");
1244 ret
= PTR_ERR(tcon
->crtc
);
1248 if (tcon
->quirks
->has_channel_0
) {
1250 * If we have an LVDS panel connected to the TCON, we should
1251 * just probe the LVDS connector. Otherwise, just probe RGB as
1254 remote
= of_graph_get_remote_node(dev
->of_node
, 1, 0);
1255 if (of_device_is_compatible(remote
, "panel-lvds"))
1257 ret
= sun4i_lvds_init(drm
, tcon
);
1261 ret
= sun4i_rgb_init(drm
, tcon
);
1262 of_node_put(remote
);
1268 if (tcon
->quirks
->needs_de_be_mux
) {
1270 * We assume there is no dynamic muxing of backends
1271 * and TCONs, so we select the backend with same ID.
1273 * While dynamic selection might be interesting, since
1274 * the CRTC is tied to the TCON, while the layers are
1275 * tied to the backends, this means, we will need to
1276 * switch between groups of layers. There might not be
1277 * a way to represent this constraint in DRM.
1279 regmap_update_bits(tcon
->regs
, SUN4I_TCON0_CTL_REG
,
1280 SUN4I_TCON0_CTL_SRC_SEL_MASK
,
1282 regmap_update_bits(tcon
->regs
, SUN4I_TCON1_CTL_REG
,
1283 SUN4I_TCON1_CTL_SRC_SEL_MASK
,
1287 list_add_tail(&tcon
->list
, &drv
->tcon_list
);
1292 if (tcon
->quirks
->has_channel_0
)
1293 sun4i_dclk_free(tcon
);
1295 reset_control_assert(tcon
->lcd_rst
);
1299 static void sun4i_tcon_unbind(struct device
*dev
, struct device
*master
,
1302 struct sun4i_tcon
*tcon
= dev_get_drvdata(dev
);
1304 list_del(&tcon
->list
);
1305 if (tcon
->quirks
->has_channel_0
)
1306 sun4i_dclk_free(tcon
);
1309 static const struct component_ops sun4i_tcon_ops
= {
1310 .bind
= sun4i_tcon_bind
,
1311 .unbind
= sun4i_tcon_unbind
,
1314 static int sun4i_tcon_probe(struct platform_device
*pdev
)
1316 struct device_node
*node
= pdev
->dev
.of_node
;
1317 const struct sun4i_tcon_quirks
*quirks
;
1318 struct drm_bridge
*bridge
;
1319 struct drm_panel
*panel
;
1322 quirks
= of_device_get_match_data(&pdev
->dev
);
1324 /* panels and bridges are present only on TCONs with channel 0 */
1325 if (quirks
->has_channel_0
) {
1326 ret
= drm_of_find_panel_or_bridge(node
, 1, 0, &panel
, &bridge
);
1327 if (ret
== -EPROBE_DEFER
)
1331 return component_add(&pdev
->dev
, &sun4i_tcon_ops
);
1334 static void sun4i_tcon_remove(struct platform_device
*pdev
)
1336 component_del(&pdev
->dev
, &sun4i_tcon_ops
);
1339 /* platform specific TCON muxing callbacks */
1340 static int sun4i_a10_tcon_set_mux(struct sun4i_tcon
*tcon
,
1341 const struct drm_encoder
*encoder
)
1343 struct sun4i_tcon
*tcon0
= sun4i_get_tcon0(encoder
->dev
);
1349 switch (encoder
->encoder_type
) {
1350 case DRM_MODE_ENCODER_TMDS
:
1358 regmap_update_bits(tcon0
->regs
, SUN4I_TCON_MUX_CTRL_REG
,
1359 0x3 << shift
, tcon
->id
<< shift
);
1364 static int sun5i_a13_tcon_set_mux(struct sun4i_tcon
*tcon
,
1365 const struct drm_encoder
*encoder
)
1369 if (encoder
->encoder_type
== DRM_MODE_ENCODER_TVDAC
)
1375 * FIXME: Undocumented bits
1377 return regmap_write(tcon
->regs
, SUN4I_TCON_MUX_CTRL_REG
, val
);
1380 static int sun6i_tcon_set_mux(struct sun4i_tcon
*tcon
,
1381 const struct drm_encoder
*encoder
)
1383 struct sun4i_tcon
*tcon0
= sun4i_get_tcon0(encoder
->dev
);
1389 switch (encoder
->encoder_type
) {
1390 case DRM_MODE_ENCODER_TMDS
:
1395 /* TODO A31 has MIPI DSI but A31s does not */
1399 regmap_update_bits(tcon0
->regs
, SUN4I_TCON_MUX_CTRL_REG
,
1400 0x3 << shift
, tcon
->id
<< shift
);
1405 static int sun8i_r40_tcon_tv_set_mux(struct sun4i_tcon
*tcon
,
1406 const struct drm_encoder
*encoder
)
1408 struct device_node
*port
, *remote
;
1409 struct platform_device
*pdev
;
1412 /* find TCON TOP platform device and TCON id */
1414 port
= of_graph_get_port_by_id(tcon
->dev
->of_node
, 0);
1418 id
= sun4i_tcon_of_get_id_from_port(port
);
1421 remote
= of_graph_get_remote_node(tcon
->dev
->of_node
, 0, -1);
1425 pdev
= of_find_device_by_node(remote
);
1426 of_node_put(remote
);
1430 if (IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP
) &&
1431 encoder
->encoder_type
== DRM_MODE_ENCODER_TMDS
) {
1432 ret
= sun8i_tcon_top_set_hdmi_src(&pdev
->dev
, id
);
1434 put_device(&pdev
->dev
);
1439 if (IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP
)) {
1440 ret
= sun8i_tcon_top_de_config(&pdev
->dev
, tcon
->id
, id
);
1442 put_device(&pdev
->dev
);
1450 static const struct sun4i_tcon_quirks sun4i_a10_quirks
= {
1451 .has_channel_0
= true,
1452 .has_channel_1
= true,
1454 .set_mux
= sun4i_a10_tcon_set_mux
,
1457 static const struct sun4i_tcon_quirks sun5i_a13_quirks
= {
1458 .has_channel_0
= true,
1459 .has_channel_1
= true,
1461 .set_mux
= sun5i_a13_tcon_set_mux
,
1464 static const struct sun4i_tcon_quirks sun6i_a31_quirks
= {
1465 .has_channel_0
= true,
1466 .has_channel_1
= true,
1467 .has_lvds_alt
= true,
1468 .needs_de_be_mux
= true,
1470 .set_mux
= sun6i_tcon_set_mux
,
1473 static const struct sun4i_tcon_quirks sun6i_a31s_quirks
= {
1474 .has_channel_0
= true,
1475 .has_channel_1
= true,
1476 .needs_de_be_mux
= true,
1480 static const struct sun4i_tcon_quirks sun7i_a20_tcon0_quirks
= {
1481 .supports_lvds
= true,
1482 .has_channel_0
= true,
1483 .has_channel_1
= true,
1485 /* Same display pipeline structure as A10 */
1486 .set_mux
= sun4i_a10_tcon_set_mux
,
1487 .setup_lvds_phy
= sun4i_tcon_setup_lvds_phy
,
1490 static const struct sun4i_tcon_quirks sun7i_a20_quirks
= {
1491 .has_channel_0
= true,
1492 .has_channel_1
= true,
1494 /* Same display pipeline structure as A10 */
1495 .set_mux
= sun4i_a10_tcon_set_mux
,
1498 static const struct sun4i_tcon_quirks sun8i_a33_quirks
= {
1499 .has_channel_0
= true,
1500 .has_lvds_alt
= true,
1502 .setup_lvds_phy
= sun6i_tcon_setup_lvds_phy
,
1503 .supports_lvds
= true,
1506 static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks
= {
1507 .supports_lvds
= true,
1508 .has_channel_0
= true,
1510 .setup_lvds_phy
= sun6i_tcon_setup_lvds_phy
,
1513 static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks
= {
1514 .has_channel_1
= true,
1517 static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks
= {
1518 .has_channel_1
= true,
1519 .polarity_in_ch0
= true,
1520 .set_mux
= sun8i_r40_tcon_tv_set_mux
,
1523 static const struct sun4i_tcon_quirks sun8i_v3s_quirks
= {
1524 .has_channel_0
= true,
1528 static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks
= {
1529 .has_channel_0
= true,
1530 .needs_edp_reset
= true,
1534 static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks
= {
1535 .has_channel_1
= true,
1536 .needs_edp_reset
= true,
1539 static const struct sun4i_tcon_quirks sun20i_d1_lcd_quirks
= {
1540 .has_channel_0
= true,
1542 .set_mux
= sun8i_r40_tcon_tv_set_mux
,
1545 /* sun4i_drv uses this list to check if a device node is a TCON */
1546 const struct of_device_id sun4i_tcon_of_table
[] = {
1547 { .compatible
= "allwinner,sun4i-a10-tcon", .data
= &sun4i_a10_quirks
},
1548 { .compatible
= "allwinner,sun5i-a13-tcon", .data
= &sun5i_a13_quirks
},
1549 { .compatible
= "allwinner,sun6i-a31-tcon", .data
= &sun6i_a31_quirks
},
1550 { .compatible
= "allwinner,sun6i-a31s-tcon", .data
= &sun6i_a31s_quirks
},
1551 { .compatible
= "allwinner,sun7i-a20-tcon", .data
= &sun7i_a20_quirks
},
1552 { .compatible
= "allwinner,sun7i-a20-tcon0", .data
= &sun7i_a20_tcon0_quirks
},
1553 { .compatible
= "allwinner,sun7i-a20-tcon1", .data
= &sun7i_a20_quirks
},
1554 { .compatible
= "allwinner,sun8i-a23-tcon", .data
= &sun8i_a33_quirks
},
1555 { .compatible
= "allwinner,sun8i-a33-tcon", .data
= &sun8i_a33_quirks
},
1556 { .compatible
= "allwinner,sun8i-a83t-tcon-lcd", .data
= &sun8i_a83t_lcd_quirks
},
1557 { .compatible
= "allwinner,sun8i-a83t-tcon-tv", .data
= &sun8i_a83t_tv_quirks
},
1558 { .compatible
= "allwinner,sun8i-r40-tcon-tv", .data
= &sun8i_r40_tv_quirks
},
1559 { .compatible
= "allwinner,sun8i-v3s-tcon", .data
= &sun8i_v3s_quirks
},
1560 { .compatible
= "allwinner,sun9i-a80-tcon-lcd", .data
= &sun9i_a80_tcon_lcd_quirks
},
1561 { .compatible
= "allwinner,sun9i-a80-tcon-tv", .data
= &sun9i_a80_tcon_tv_quirks
},
1562 { .compatible
= "allwinner,sun20i-d1-tcon-lcd", .data
= &sun20i_d1_lcd_quirks
},
1563 { .compatible
= "allwinner,sun20i-d1-tcon-tv", .data
= &sun8i_r40_tv_quirks
},
1566 MODULE_DEVICE_TABLE(of
, sun4i_tcon_of_table
);
1567 EXPORT_SYMBOL(sun4i_tcon_of_table
);
1569 static struct platform_driver sun4i_tcon_platform_driver
= {
1570 .probe
= sun4i_tcon_probe
,
1571 .remove
= sun4i_tcon_remove
,
1573 .name
= "sun4i-tcon",
1574 .of_match_table
= sun4i_tcon_of_table
,
1577 module_platform_driver(sun4i_tcon_platform_driver
);
1579 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1580 MODULE_DESCRIPTION("Allwinner A10 Timing Controller Driver");
1581 MODULE_LICENSE("GPL");