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