1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2009 Nokia Corporation
4 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 * Some code and ideas taken from drivers/video/omap/ driver
10 #define DSS_SUBSYS_NAME "DSS"
12 #include <linux/debugfs.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
17 #include <linux/export.h>
18 #include <linux/err.h>
19 #include <linux/delay.h>
20 #include <linux/seq_file.h>
21 #include <linux/clk.h>
22 #include <linux/pinctrl/consumer.h>
23 #include <linux/platform_device.h>
24 #include <linux/pm_runtime.h>
25 #include <linux/gfp.h>
26 #include <linux/sizes.h>
27 #include <linux/mfd/syscon.h>
28 #include <linux/regmap.h>
30 #include <linux/of_device.h>
31 #include <linux/of_graph.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/suspend.h>
34 #include <linux/component.h>
35 #include <linux/sys_soc.h>
44 #define DSS_REG(idx) ((const struct dss_reg) { idx })
46 #define DSS_REVISION DSS_REG(0x0000)
47 #define DSS_SYSCONFIG DSS_REG(0x0010)
48 #define DSS_SYSSTATUS DSS_REG(0x0014)
49 #define DSS_CONTROL DSS_REG(0x0040)
50 #define DSS_SDI_CONTROL DSS_REG(0x0044)
51 #define DSS_PLL_CONTROL DSS_REG(0x0048)
52 #define DSS_SDI_STATUS DSS_REG(0x005C)
54 #define REG_GET(dss, idx, start, end) \
55 FLD_GET(dss_read_reg(dss, idx), start, end)
57 #define REG_FLD_MOD(dss, idx, val, start, end) \
58 dss_write_reg(dss, idx, \
59 FLD_MOD(dss_read_reg(dss, idx), val, start, end))
62 int (*dpi_select_source
)(struct dss_device
*dss
, int port
,
63 enum omap_channel channel
);
64 int (*select_lcd_source
)(struct dss_device
*dss
,
65 enum omap_channel channel
,
66 enum dss_clk_source clk_src
);
72 unsigned int fck_freq_max
;
73 u8 dss_fck_multiplier
;
74 const char *parent_clk_name
;
75 const enum omap_display_type
*ports
;
77 const enum omap_dss_output_id
*outputs
;
78 const struct dss_ops
*ops
;
79 struct dss_reg_field dispc_clk_switch
;
83 static const char * const dss_generic_clk_source_names
[] = {
84 [DSS_CLK_SRC_FCK
] = "FCK",
85 [DSS_CLK_SRC_PLL1_1
] = "PLL1:1",
86 [DSS_CLK_SRC_PLL1_2
] = "PLL1:2",
87 [DSS_CLK_SRC_PLL1_3
] = "PLL1:3",
88 [DSS_CLK_SRC_PLL2_1
] = "PLL2:1",
89 [DSS_CLK_SRC_PLL2_2
] = "PLL2:2",
90 [DSS_CLK_SRC_PLL2_3
] = "PLL2:3",
91 [DSS_CLK_SRC_HDMI_PLL
] = "HDMI PLL",
94 static inline void dss_write_reg(struct dss_device
*dss
,
95 const struct dss_reg idx
, u32 val
)
97 __raw_writel(val
, dss
->base
+ idx
.idx
);
100 static inline u32
dss_read_reg(struct dss_device
*dss
, const struct dss_reg idx
)
102 return __raw_readl(dss
->base
+ idx
.idx
);
105 #define SR(dss, reg) \
106 dss->ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(dss, DSS_##reg)
107 #define RR(dss, reg) \
108 dss_write_reg(dss, DSS_##reg, dss->ctx[(DSS_##reg).idx / sizeof(u32)])
110 static void dss_save_context(struct dss_device
*dss
)
112 DSSDBG("dss_save_context\n");
116 if (dss
->feat
->outputs
[OMAP_DSS_CHANNEL_LCD
] & OMAP_DSS_OUTPUT_SDI
) {
117 SR(dss
, SDI_CONTROL
);
118 SR(dss
, PLL_CONTROL
);
121 dss
->ctx_valid
= true;
123 DSSDBG("context saved\n");
126 static void dss_restore_context(struct dss_device
*dss
)
128 DSSDBG("dss_restore_context\n");
135 if (dss
->feat
->outputs
[OMAP_DSS_CHANNEL_LCD
] & OMAP_DSS_OUTPUT_SDI
) {
136 RR(dss
, SDI_CONTROL
);
137 RR(dss
, PLL_CONTROL
);
140 DSSDBG("context restored\n");
146 void dss_ctrl_pll_enable(struct dss_pll
*pll
, bool enable
)
151 if (!pll
->dss
->syscon_pll_ctrl
)
167 DSSERR("illegal DSS PLL ID %d\n", pll
->id
);
171 regmap_update_bits(pll
->dss
->syscon_pll_ctrl
,
172 pll
->dss
->syscon_pll_ctrl_offset
,
173 1 << shift
, val
<< shift
);
176 static int dss_ctrl_pll_set_control_mux(struct dss_device
*dss
,
177 enum dss_clk_source clk_src
,
178 enum omap_channel channel
)
180 unsigned int shift
, val
;
182 if (!dss
->syscon_pll_ctrl
)
186 case OMAP_DSS_CHANNEL_LCD
:
190 case DSS_CLK_SRC_PLL1_1
:
192 case DSS_CLK_SRC_HDMI_PLL
:
195 DSSERR("error in PLL mux config for LCD\n");
200 case OMAP_DSS_CHANNEL_LCD2
:
204 case DSS_CLK_SRC_PLL1_3
:
206 case DSS_CLK_SRC_PLL2_3
:
208 case DSS_CLK_SRC_HDMI_PLL
:
211 DSSERR("error in PLL mux config for LCD2\n");
216 case OMAP_DSS_CHANNEL_LCD3
:
220 case DSS_CLK_SRC_PLL2_1
:
222 case DSS_CLK_SRC_PLL1_3
:
224 case DSS_CLK_SRC_HDMI_PLL
:
227 DSSERR("error in PLL mux config for LCD3\n");
233 DSSERR("error in PLL mux config\n");
237 regmap_update_bits(dss
->syscon_pll_ctrl
, dss
->syscon_pll_ctrl_offset
,
238 0x3 << shift
, val
<< shift
);
243 void dss_sdi_init(struct dss_device
*dss
, int datapairs
)
247 BUG_ON(datapairs
> 3 || datapairs
< 1);
249 l
= dss_read_reg(dss
, DSS_SDI_CONTROL
);
250 l
= FLD_MOD(l
, 0xf, 19, 15); /* SDI_PDIV */
251 l
= FLD_MOD(l
, datapairs
-1, 3, 2); /* SDI_PRSEL */
252 l
= FLD_MOD(l
, 2, 1, 0); /* SDI_BWSEL */
253 dss_write_reg(dss
, DSS_SDI_CONTROL
, l
);
255 l
= dss_read_reg(dss
, DSS_PLL_CONTROL
);
256 l
= FLD_MOD(l
, 0x7, 25, 22); /* SDI_PLL_FREQSEL */
257 l
= FLD_MOD(l
, 0xb, 16, 11); /* SDI_PLL_REGN */
258 l
= FLD_MOD(l
, 0xb4, 10, 1); /* SDI_PLL_REGM */
259 dss_write_reg(dss
, DSS_PLL_CONTROL
, l
);
262 int dss_sdi_enable(struct dss_device
*dss
)
264 unsigned long timeout
;
266 dispc_pck_free_enable(dss
->dispc
, 1);
269 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 1, 18, 18); /* SDI_PLL_SYSRESET */
270 udelay(1); /* wait 2x PCLK */
273 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 1, 28, 28); /* SDI_PLL_GOBIT */
275 /* Waiting for PLL lock request to complete */
276 timeout
= jiffies
+ msecs_to_jiffies(500);
277 while (dss_read_reg(dss
, DSS_SDI_STATUS
) & (1 << 6)) {
278 if (time_after_eq(jiffies
, timeout
)) {
279 DSSERR("PLL lock request timed out\n");
284 /* Clearing PLL_GO bit */
285 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 0, 28, 28);
287 /* Waiting for PLL to lock */
288 timeout
= jiffies
+ msecs_to_jiffies(500);
289 while (!(dss_read_reg(dss
, DSS_SDI_STATUS
) & (1 << 5))) {
290 if (time_after_eq(jiffies
, timeout
)) {
291 DSSERR("PLL lock timed out\n");
296 dispc_lcd_enable_signal(dss
->dispc
, 1);
298 /* Waiting for SDI reset to complete */
299 timeout
= jiffies
+ msecs_to_jiffies(500);
300 while (!(dss_read_reg(dss
, DSS_SDI_STATUS
) & (1 << 2))) {
301 if (time_after_eq(jiffies
, timeout
)) {
302 DSSERR("SDI reset timed out\n");
310 dispc_lcd_enable_signal(dss
->dispc
, 0);
313 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 0, 18, 18); /* SDI_PLL_SYSRESET */
315 dispc_pck_free_enable(dss
->dispc
, 0);
320 void dss_sdi_disable(struct dss_device
*dss
)
322 dispc_lcd_enable_signal(dss
->dispc
, 0);
324 dispc_pck_free_enable(dss
->dispc
, 0);
327 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 0, 18, 18); /* SDI_PLL_SYSRESET */
330 const char *dss_get_clk_source_name(enum dss_clk_source clk_src
)
332 return dss_generic_clk_source_names
[clk_src
];
335 static void dss_dump_clocks(struct dss_device
*dss
, struct seq_file
*s
)
337 const char *fclk_name
;
338 unsigned long fclk_rate
;
340 if (dss_runtime_get(dss
))
343 seq_printf(s
, "- DSS -\n");
345 fclk_name
= dss_get_clk_source_name(DSS_CLK_SRC_FCK
);
346 fclk_rate
= clk_get_rate(dss
->dss_clk
);
348 seq_printf(s
, "%s = %lu\n",
352 dss_runtime_put(dss
);
355 static int dss_dump_regs(struct seq_file
*s
, void *p
)
357 struct dss_device
*dss
= s
->private;
359 #define DUMPREG(dss, r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(dss, r))
361 if (dss_runtime_get(dss
))
364 DUMPREG(dss
, DSS_REVISION
);
365 DUMPREG(dss
, DSS_SYSCONFIG
);
366 DUMPREG(dss
, DSS_SYSSTATUS
);
367 DUMPREG(dss
, DSS_CONTROL
);
369 if (dss
->feat
->outputs
[OMAP_DSS_CHANNEL_LCD
] & OMAP_DSS_OUTPUT_SDI
) {
370 DUMPREG(dss
, DSS_SDI_CONTROL
);
371 DUMPREG(dss
, DSS_PLL_CONTROL
);
372 DUMPREG(dss
, DSS_SDI_STATUS
);
375 dss_runtime_put(dss
);
380 static int dss_debug_dump_clocks(struct seq_file
*s
, void *p
)
382 struct dss_device
*dss
= s
->private;
384 dss_dump_clocks(dss
, s
);
385 dispc_dump_clocks(dss
->dispc
, s
);
389 static int dss_get_channel_index(enum omap_channel channel
)
392 case OMAP_DSS_CHANNEL_LCD
:
394 case OMAP_DSS_CHANNEL_LCD2
:
396 case OMAP_DSS_CHANNEL_LCD3
:
404 static void dss_select_dispc_clk_source(struct dss_device
*dss
,
405 enum dss_clk_source clk_src
)
410 * We always use PRCM clock as the DISPC func clock, except on DSS3,
411 * where we don't have separate DISPC and LCD clock sources.
413 if (WARN_ON(dss
->feat
->has_lcd_clk_src
&& clk_src
!= DSS_CLK_SRC_FCK
))
417 case DSS_CLK_SRC_FCK
:
420 case DSS_CLK_SRC_PLL1_1
:
423 case DSS_CLK_SRC_PLL2_1
:
431 REG_FLD_MOD(dss
, DSS_CONTROL
, b
, /* DISPC_CLK_SWITCH */
432 dss
->feat
->dispc_clk_switch
.start
,
433 dss
->feat
->dispc_clk_switch
.end
);
435 dss
->dispc_clk_source
= clk_src
;
438 void dss_select_dsi_clk_source(struct dss_device
*dss
, int dsi_module
,
439 enum dss_clk_source clk_src
)
444 case DSS_CLK_SRC_FCK
:
447 case DSS_CLK_SRC_PLL1_2
:
448 BUG_ON(dsi_module
!= 0);
451 case DSS_CLK_SRC_PLL2_2
:
452 BUG_ON(dsi_module
!= 1);
460 pos
= dsi_module
== 0 ? 1 : 10;
461 REG_FLD_MOD(dss
, DSS_CONTROL
, b
, pos
, pos
); /* DSIx_CLK_SWITCH */
463 dss
->dsi_clk_source
[dsi_module
] = clk_src
;
466 static int dss_lcd_clk_mux_dra7(struct dss_device
*dss
,
467 enum omap_channel channel
,
468 enum dss_clk_source clk_src
)
470 const u8 ctrl_bits
[] = {
471 [OMAP_DSS_CHANNEL_LCD
] = 0,
472 [OMAP_DSS_CHANNEL_LCD2
] = 12,
473 [OMAP_DSS_CHANNEL_LCD3
] = 19,
476 u8 ctrl_bit
= ctrl_bits
[channel
];
479 if (clk_src
== DSS_CLK_SRC_FCK
) {
480 /* LCDx_CLK_SWITCH */
481 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, ctrl_bit
, ctrl_bit
);
485 r
= dss_ctrl_pll_set_control_mux(dss
, clk_src
, channel
);
489 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, ctrl_bit
, ctrl_bit
);
494 static int dss_lcd_clk_mux_omap5(struct dss_device
*dss
,
495 enum omap_channel channel
,
496 enum dss_clk_source clk_src
)
498 const u8 ctrl_bits
[] = {
499 [OMAP_DSS_CHANNEL_LCD
] = 0,
500 [OMAP_DSS_CHANNEL_LCD2
] = 12,
501 [OMAP_DSS_CHANNEL_LCD3
] = 19,
503 const enum dss_clk_source allowed_plls
[] = {
504 [OMAP_DSS_CHANNEL_LCD
] = DSS_CLK_SRC_PLL1_1
,
505 [OMAP_DSS_CHANNEL_LCD2
] = DSS_CLK_SRC_FCK
,
506 [OMAP_DSS_CHANNEL_LCD3
] = DSS_CLK_SRC_PLL2_1
,
509 u8 ctrl_bit
= ctrl_bits
[channel
];
511 if (clk_src
== DSS_CLK_SRC_FCK
) {
512 /* LCDx_CLK_SWITCH */
513 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, ctrl_bit
, ctrl_bit
);
517 if (WARN_ON(allowed_plls
[channel
] != clk_src
))
520 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, ctrl_bit
, ctrl_bit
);
525 static int dss_lcd_clk_mux_omap4(struct dss_device
*dss
,
526 enum omap_channel channel
,
527 enum dss_clk_source clk_src
)
529 const u8 ctrl_bits
[] = {
530 [OMAP_DSS_CHANNEL_LCD
] = 0,
531 [OMAP_DSS_CHANNEL_LCD2
] = 12,
533 const enum dss_clk_source allowed_plls
[] = {
534 [OMAP_DSS_CHANNEL_LCD
] = DSS_CLK_SRC_PLL1_1
,
535 [OMAP_DSS_CHANNEL_LCD2
] = DSS_CLK_SRC_PLL2_1
,
538 u8 ctrl_bit
= ctrl_bits
[channel
];
540 if (clk_src
== DSS_CLK_SRC_FCK
) {
541 /* LCDx_CLK_SWITCH */
542 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, ctrl_bit
, ctrl_bit
);
546 if (WARN_ON(allowed_plls
[channel
] != clk_src
))
549 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, ctrl_bit
, ctrl_bit
);
554 void dss_select_lcd_clk_source(struct dss_device
*dss
,
555 enum omap_channel channel
,
556 enum dss_clk_source clk_src
)
558 int idx
= dss_get_channel_index(channel
);
561 if (!dss
->feat
->has_lcd_clk_src
) {
562 dss_select_dispc_clk_source(dss
, clk_src
);
563 dss
->lcd_clk_source
[idx
] = clk_src
;
567 r
= dss
->feat
->ops
->select_lcd_source(dss
, channel
, clk_src
);
571 dss
->lcd_clk_source
[idx
] = clk_src
;
574 enum dss_clk_source
dss_get_dispc_clk_source(struct dss_device
*dss
)
576 return dss
->dispc_clk_source
;
579 enum dss_clk_source
dss_get_dsi_clk_source(struct dss_device
*dss
,
582 return dss
->dsi_clk_source
[dsi_module
];
585 enum dss_clk_source
dss_get_lcd_clk_source(struct dss_device
*dss
,
586 enum omap_channel channel
)
588 if (dss
->feat
->has_lcd_clk_src
) {
589 int idx
= dss_get_channel_index(channel
);
590 return dss
->lcd_clk_source
[idx
];
592 /* LCD_CLK source is the same as DISPC_FCLK source for
594 return dss
->dispc_clk_source
;
598 bool dss_div_calc(struct dss_device
*dss
, unsigned long pck
,
599 unsigned long fck_min
, dss_div_calc_func func
, void *data
)
601 int fckd
, fckd_start
, fckd_stop
;
603 unsigned long fck_hw_max
;
604 unsigned long fckd_hw_max
;
608 fck_hw_max
= dss
->feat
->fck_freq_max
;
610 if (dss
->parent_clk
== NULL
) {
613 pckd
= fck_hw_max
/ pck
;
617 fck
= clk_round_rate(dss
->dss_clk
, fck
);
619 return func(fck
, data
);
622 fckd_hw_max
= dss
->feat
->fck_div_max
;
624 m
= dss
->feat
->dss_fck_multiplier
;
625 prate
= clk_get_rate(dss
->parent_clk
);
627 fck_min
= fck_min
? fck_min
: 1;
629 fckd_start
= min(prate
* m
/ fck_min
, fckd_hw_max
);
630 fckd_stop
= max(DIV_ROUND_UP(prate
* m
, fck_hw_max
), 1ul);
632 for (fckd
= fckd_start
; fckd
>= fckd_stop
; --fckd
) {
633 fck
= DIV_ROUND_UP(prate
, fckd
) * m
;
642 int dss_set_fck_rate(struct dss_device
*dss
, unsigned long rate
)
646 DSSDBG("set fck to %lu\n", rate
);
648 r
= clk_set_rate(dss
->dss_clk
, rate
);
652 dss
->dss_clk_rate
= clk_get_rate(dss
->dss_clk
);
654 WARN_ONCE(dss
->dss_clk_rate
!= rate
, "clk rate mismatch: %lu != %lu",
655 dss
->dss_clk_rate
, rate
);
660 unsigned long dss_get_dispc_clk_rate(struct dss_device
*dss
)
662 return dss
->dss_clk_rate
;
665 unsigned long dss_get_max_fck_rate(struct dss_device
*dss
)
667 return dss
->feat
->fck_freq_max
;
670 static int dss_setup_default_clock(struct dss_device
*dss
)
672 unsigned long max_dss_fck
, prate
;
674 unsigned int fck_div
;
677 max_dss_fck
= dss
->feat
->fck_freq_max
;
679 if (dss
->parent_clk
== NULL
) {
680 fck
= clk_round_rate(dss
->dss_clk
, max_dss_fck
);
682 prate
= clk_get_rate(dss
->parent_clk
);
684 fck_div
= DIV_ROUND_UP(prate
* dss
->feat
->dss_fck_multiplier
,
686 fck
= DIV_ROUND_UP(prate
, fck_div
)
687 * dss
->feat
->dss_fck_multiplier
;
690 r
= dss_set_fck_rate(dss
, fck
);
697 void dss_set_venc_output(struct dss_device
*dss
, enum omap_dss_venc_type type
)
701 if (type
== OMAP_DSS_VENC_TYPE_COMPOSITE
)
703 else if (type
== OMAP_DSS_VENC_TYPE_SVIDEO
)
708 /* venc out selection. 0 = comp, 1 = svideo */
709 REG_FLD_MOD(dss
, DSS_CONTROL
, l
, 6, 6);
712 void dss_set_dac_pwrdn_bgz(struct dss_device
*dss
, bool enable
)
714 /* DAC Power-Down Control */
715 REG_FLD_MOD(dss
, DSS_CONTROL
, enable
, 5, 5);
718 void dss_select_hdmi_venc_clk_source(struct dss_device
*dss
,
719 enum dss_hdmi_venc_clk_source_select src
)
721 enum omap_dss_output_id outputs
;
723 outputs
= dss
->feat
->outputs
[OMAP_DSS_CHANNEL_DIGIT
];
725 /* Complain about invalid selections */
726 WARN_ON((src
== DSS_VENC_TV_CLK
) && !(outputs
& OMAP_DSS_OUTPUT_VENC
));
727 WARN_ON((src
== DSS_HDMI_M_PCLK
) && !(outputs
& OMAP_DSS_OUTPUT_HDMI
));
729 /* Select only if we have options */
730 if ((outputs
& OMAP_DSS_OUTPUT_VENC
) &&
731 (outputs
& OMAP_DSS_OUTPUT_HDMI
))
732 /* VENC_HDMI_SWITCH */
733 REG_FLD_MOD(dss
, DSS_CONTROL
, src
, 15, 15);
736 static int dss_dpi_select_source_omap2_omap3(struct dss_device
*dss
, int port
,
737 enum omap_channel channel
)
739 if (channel
!= OMAP_DSS_CHANNEL_LCD
)
745 static int dss_dpi_select_source_omap4(struct dss_device
*dss
, int port
,
746 enum omap_channel channel
)
751 case OMAP_DSS_CHANNEL_LCD2
:
754 case OMAP_DSS_CHANNEL_DIGIT
:
761 REG_FLD_MOD(dss
, DSS_CONTROL
, val
, 17, 17);
766 static int dss_dpi_select_source_omap5(struct dss_device
*dss
, int port
,
767 enum omap_channel channel
)
772 case OMAP_DSS_CHANNEL_LCD
:
775 case OMAP_DSS_CHANNEL_LCD2
:
778 case OMAP_DSS_CHANNEL_LCD3
:
781 case OMAP_DSS_CHANNEL_DIGIT
:
788 REG_FLD_MOD(dss
, DSS_CONTROL
, val
, 17, 16);
793 static int dss_dpi_select_source_dra7xx(struct dss_device
*dss
, int port
,
794 enum omap_channel channel
)
798 return dss_dpi_select_source_omap5(dss
, port
, channel
);
800 if (channel
!= OMAP_DSS_CHANNEL_LCD2
)
804 if (channel
!= OMAP_DSS_CHANNEL_LCD3
)
814 int dss_dpi_select_source(struct dss_device
*dss
, int port
,
815 enum omap_channel channel
)
817 return dss
->feat
->ops
->dpi_select_source(dss
, port
, channel
);
820 static int dss_get_clocks(struct dss_device
*dss
)
824 clk
= devm_clk_get(&dss
->pdev
->dev
, "fck");
826 DSSERR("can't get clock fck\n");
832 if (dss
->feat
->parent_clk_name
) {
833 clk
= clk_get(NULL
, dss
->feat
->parent_clk_name
);
835 DSSERR("Failed to get %s\n",
836 dss
->feat
->parent_clk_name
);
843 dss
->parent_clk
= clk
;
848 static void dss_put_clocks(struct dss_device
*dss
)
851 clk_put(dss
->parent_clk
);
854 int dss_runtime_get(struct dss_device
*dss
)
858 DSSDBG("dss_runtime_get\n");
860 r
= pm_runtime_get_sync(&dss
->pdev
->dev
);
862 return r
< 0 ? r
: 0;
865 void dss_runtime_put(struct dss_device
*dss
)
869 DSSDBG("dss_runtime_put\n");
871 r
= pm_runtime_put_sync(&dss
->pdev
->dev
);
872 WARN_ON(r
< 0 && r
!= -ENOSYS
&& r
!= -EBUSY
);
875 struct dss_device
*dss_get_device(struct device
*dev
)
877 return dev_get_drvdata(dev
);
881 #if defined(CONFIG_OMAP2_DSS_DEBUGFS)
882 static int dss_initialize_debugfs(struct dss_device
*dss
)
886 dir
= debugfs_create_dir("omapdss", NULL
);
890 dss
->debugfs
.root
= dir
;
895 static void dss_uninitialize_debugfs(struct dss_device
*dss
)
897 debugfs_remove_recursive(dss
->debugfs
.root
);
900 struct dss_debugfs_entry
{
901 struct dentry
*dentry
;
902 int (*show_fn
)(struct seq_file
*s
, void *data
);
906 static int dss_debug_open(struct inode
*inode
, struct file
*file
)
908 struct dss_debugfs_entry
*entry
= inode
->i_private
;
910 return single_open(file
, entry
->show_fn
, entry
->data
);
913 static const struct file_operations dss_debug_fops
= {
914 .open
= dss_debug_open
,
917 .release
= single_release
,
920 struct dss_debugfs_entry
*
921 dss_debugfs_create_file(struct dss_device
*dss
, const char *name
,
922 int (*show_fn
)(struct seq_file
*s
, void *data
),
925 struct dss_debugfs_entry
*entry
;
927 entry
= kzalloc(sizeof(*entry
), GFP_KERNEL
);
929 return ERR_PTR(-ENOMEM
);
931 entry
->show_fn
= show_fn
;
933 entry
->dentry
= debugfs_create_file(name
, 0444, dss
->debugfs
.root
,
934 entry
, &dss_debug_fops
);
939 void dss_debugfs_remove_file(struct dss_debugfs_entry
*entry
)
941 if (IS_ERR_OR_NULL(entry
))
944 debugfs_remove(entry
->dentry
);
948 #else /* CONFIG_OMAP2_DSS_DEBUGFS */
949 static inline int dss_initialize_debugfs(struct dss_device
*dss
)
953 static inline void dss_uninitialize_debugfs(struct dss_device
*dss
)
956 #endif /* CONFIG_OMAP2_DSS_DEBUGFS */
958 static const struct dss_ops dss_ops_omap2_omap3
= {
959 .dpi_select_source
= &dss_dpi_select_source_omap2_omap3
,
962 static const struct dss_ops dss_ops_omap4
= {
963 .dpi_select_source
= &dss_dpi_select_source_omap4
,
964 .select_lcd_source
= &dss_lcd_clk_mux_omap4
,
967 static const struct dss_ops dss_ops_omap5
= {
968 .dpi_select_source
= &dss_dpi_select_source_omap5
,
969 .select_lcd_source
= &dss_lcd_clk_mux_omap5
,
972 static const struct dss_ops dss_ops_dra7
= {
973 .dpi_select_source
= &dss_dpi_select_source_dra7xx
,
974 .select_lcd_source
= &dss_lcd_clk_mux_dra7
,
977 static const enum omap_display_type omap2plus_ports
[] = {
978 OMAP_DISPLAY_TYPE_DPI
,
981 static const enum omap_display_type omap34xx_ports
[] = {
982 OMAP_DISPLAY_TYPE_DPI
,
983 OMAP_DISPLAY_TYPE_SDI
,
986 static const enum omap_display_type dra7xx_ports
[] = {
987 OMAP_DISPLAY_TYPE_DPI
,
988 OMAP_DISPLAY_TYPE_DPI
,
989 OMAP_DISPLAY_TYPE_DPI
,
992 static const enum omap_dss_output_id omap2_dss_supported_outputs
[] = {
993 /* OMAP_DSS_CHANNEL_LCD */
994 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
,
996 /* OMAP_DSS_CHANNEL_DIGIT */
997 OMAP_DSS_OUTPUT_VENC
,
1000 static const enum omap_dss_output_id omap3430_dss_supported_outputs
[] = {
1001 /* OMAP_DSS_CHANNEL_LCD */
1002 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1003 OMAP_DSS_OUTPUT_SDI
| OMAP_DSS_OUTPUT_DSI1
,
1005 /* OMAP_DSS_CHANNEL_DIGIT */
1006 OMAP_DSS_OUTPUT_VENC
,
1009 static const enum omap_dss_output_id omap3630_dss_supported_outputs
[] = {
1010 /* OMAP_DSS_CHANNEL_LCD */
1011 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1012 OMAP_DSS_OUTPUT_DSI1
,
1014 /* OMAP_DSS_CHANNEL_DIGIT */
1015 OMAP_DSS_OUTPUT_VENC
,
1018 static const enum omap_dss_output_id am43xx_dss_supported_outputs
[] = {
1019 /* OMAP_DSS_CHANNEL_LCD */
1020 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
,
1023 static const enum omap_dss_output_id omap4_dss_supported_outputs
[] = {
1024 /* OMAP_DSS_CHANNEL_LCD */
1025 OMAP_DSS_OUTPUT_DBI
| OMAP_DSS_OUTPUT_DSI1
,
1027 /* OMAP_DSS_CHANNEL_DIGIT */
1028 OMAP_DSS_OUTPUT_VENC
| OMAP_DSS_OUTPUT_HDMI
,
1030 /* OMAP_DSS_CHANNEL_LCD2 */
1031 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1032 OMAP_DSS_OUTPUT_DSI2
,
1035 static const enum omap_dss_output_id omap5_dss_supported_outputs
[] = {
1036 /* OMAP_DSS_CHANNEL_LCD */
1037 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1038 OMAP_DSS_OUTPUT_DSI1
| OMAP_DSS_OUTPUT_DSI2
,
1040 /* OMAP_DSS_CHANNEL_DIGIT */
1041 OMAP_DSS_OUTPUT_HDMI
,
1043 /* OMAP_DSS_CHANNEL_LCD2 */
1044 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1045 OMAP_DSS_OUTPUT_DSI1
,
1047 /* OMAP_DSS_CHANNEL_LCD3 */
1048 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1049 OMAP_DSS_OUTPUT_DSI2
,
1052 static const struct dss_features omap24xx_dss_feats
= {
1053 .model
= DSS_MODEL_OMAP2
,
1055 * fck div max is really 16, but the divider range has gaps. The range
1056 * from 1 to 6 has no gaps, so let's use that as a max.
1059 .fck_freq_max
= 133000000,
1060 .dss_fck_multiplier
= 2,
1061 .parent_clk_name
= "core_ck",
1062 .ports
= omap2plus_ports
,
1063 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1064 .outputs
= omap2_dss_supported_outputs
,
1065 .ops
= &dss_ops_omap2_omap3
,
1066 .dispc_clk_switch
= { 0, 0 },
1067 .has_lcd_clk_src
= false,
1070 static const struct dss_features omap34xx_dss_feats
= {
1071 .model
= DSS_MODEL_OMAP3
,
1073 .fck_freq_max
= 173000000,
1074 .dss_fck_multiplier
= 2,
1075 .parent_clk_name
= "dpll4_ck",
1076 .ports
= omap34xx_ports
,
1077 .outputs
= omap3430_dss_supported_outputs
,
1078 .num_ports
= ARRAY_SIZE(omap34xx_ports
),
1079 .ops
= &dss_ops_omap2_omap3
,
1080 .dispc_clk_switch
= { 0, 0 },
1081 .has_lcd_clk_src
= false,
1084 static const struct dss_features omap3630_dss_feats
= {
1085 .model
= DSS_MODEL_OMAP3
,
1087 .fck_freq_max
= 173000000,
1088 .dss_fck_multiplier
= 1,
1089 .parent_clk_name
= "dpll4_ck",
1090 .ports
= omap2plus_ports
,
1091 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1092 .outputs
= omap3630_dss_supported_outputs
,
1093 .ops
= &dss_ops_omap2_omap3
,
1094 .dispc_clk_switch
= { 0, 0 },
1095 .has_lcd_clk_src
= false,
1098 static const struct dss_features omap44xx_dss_feats
= {
1099 .model
= DSS_MODEL_OMAP4
,
1101 .fck_freq_max
= 186000000,
1102 .dss_fck_multiplier
= 1,
1103 .parent_clk_name
= "dpll_per_x2_ck",
1104 .ports
= omap2plus_ports
,
1105 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1106 .outputs
= omap4_dss_supported_outputs
,
1107 .ops
= &dss_ops_omap4
,
1108 .dispc_clk_switch
= { 9, 8 },
1109 .has_lcd_clk_src
= true,
1112 static const struct dss_features omap54xx_dss_feats
= {
1113 .model
= DSS_MODEL_OMAP5
,
1115 .fck_freq_max
= 209250000,
1116 .dss_fck_multiplier
= 1,
1117 .parent_clk_name
= "dpll_per_x2_ck",
1118 .ports
= omap2plus_ports
,
1119 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1120 .outputs
= omap5_dss_supported_outputs
,
1121 .ops
= &dss_ops_omap5
,
1122 .dispc_clk_switch
= { 9, 7 },
1123 .has_lcd_clk_src
= true,
1126 static const struct dss_features am43xx_dss_feats
= {
1127 .model
= DSS_MODEL_OMAP3
,
1129 .fck_freq_max
= 200000000,
1130 .dss_fck_multiplier
= 0,
1131 .parent_clk_name
= NULL
,
1132 .ports
= omap2plus_ports
,
1133 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1134 .outputs
= am43xx_dss_supported_outputs
,
1135 .ops
= &dss_ops_omap2_omap3
,
1136 .dispc_clk_switch
= { 0, 0 },
1137 .has_lcd_clk_src
= true,
1140 static const struct dss_features dra7xx_dss_feats
= {
1141 .model
= DSS_MODEL_DRA7
,
1143 .fck_freq_max
= 209250000,
1144 .dss_fck_multiplier
= 1,
1145 .parent_clk_name
= "dpll_per_x2_ck",
1146 .ports
= dra7xx_ports
,
1147 .num_ports
= ARRAY_SIZE(dra7xx_ports
),
1148 .outputs
= omap5_dss_supported_outputs
,
1149 .ops
= &dss_ops_dra7
,
1150 .dispc_clk_switch
= { 9, 7 },
1151 .has_lcd_clk_src
= true,
1154 static int dss_init_ports(struct dss_device
*dss
)
1156 struct platform_device
*pdev
= dss
->pdev
;
1157 struct device_node
*parent
= pdev
->dev
.of_node
;
1158 struct device_node
*port
;
1162 for (i
= 0; i
< dss
->feat
->num_ports
; i
++) {
1163 port
= of_graph_get_port_by_id(parent
, i
);
1167 switch (dss
->feat
->ports
[i
]) {
1168 case OMAP_DISPLAY_TYPE_DPI
:
1169 r
= dpi_init_port(dss
, pdev
, port
, dss
->feat
->model
);
1174 case OMAP_DISPLAY_TYPE_SDI
:
1175 r
= sdi_init_port(dss
, pdev
, port
);
1188 static void dss_uninit_ports(struct dss_device
*dss
)
1190 struct platform_device
*pdev
= dss
->pdev
;
1191 struct device_node
*parent
= pdev
->dev
.of_node
;
1192 struct device_node
*port
;
1195 for (i
= 0; i
< dss
->feat
->num_ports
; i
++) {
1196 port
= of_graph_get_port_by_id(parent
, i
);
1200 switch (dss
->feat
->ports
[i
]) {
1201 case OMAP_DISPLAY_TYPE_DPI
:
1202 dpi_uninit_port(port
);
1204 case OMAP_DISPLAY_TYPE_SDI
:
1205 sdi_uninit_port(port
);
1213 static int dss_video_pll_probe(struct dss_device
*dss
)
1215 struct platform_device
*pdev
= dss
->pdev
;
1216 struct device_node
*np
= pdev
->dev
.of_node
;
1217 struct regulator
*pll_regulator
;
1223 if (of_property_read_bool(np
, "syscon-pll-ctrl")) {
1224 dss
->syscon_pll_ctrl
= syscon_regmap_lookup_by_phandle(np
,
1226 if (IS_ERR(dss
->syscon_pll_ctrl
)) {
1228 "failed to get syscon-pll-ctrl regmap\n");
1229 return PTR_ERR(dss
->syscon_pll_ctrl
);
1232 if (of_property_read_u32_index(np
, "syscon-pll-ctrl", 1,
1233 &dss
->syscon_pll_ctrl_offset
)) {
1235 "failed to get syscon-pll-ctrl offset\n");
1240 pll_regulator
= devm_regulator_get(&pdev
->dev
, "vdda_video");
1241 if (IS_ERR(pll_regulator
)) {
1242 r
= PTR_ERR(pll_regulator
);
1246 pll_regulator
= NULL
;
1250 return -EPROBE_DEFER
;
1253 DSSERR("can't get DPLL VDDA regulator\n");
1258 if (of_property_match_string(np
, "reg-names", "pll1") >= 0) {
1259 dss
->video1_pll
= dss_video_pll_init(dss
, pdev
, 0,
1261 if (IS_ERR(dss
->video1_pll
))
1262 return PTR_ERR(dss
->video1_pll
);
1265 if (of_property_match_string(np
, "reg-names", "pll2") >= 0) {
1266 dss
->video2_pll
= dss_video_pll_init(dss
, pdev
, 1,
1268 if (IS_ERR(dss
->video2_pll
)) {
1269 dss_video_pll_uninit(dss
->video1_pll
);
1270 return PTR_ERR(dss
->video2_pll
);
1277 /* DSS HW IP initialisation */
1278 static const struct of_device_id dss_of_match
[] = {
1279 { .compatible
= "ti,omap2-dss", .data
= &omap24xx_dss_feats
},
1280 { .compatible
= "ti,omap3-dss", .data
= &omap3630_dss_feats
},
1281 { .compatible
= "ti,omap4-dss", .data
= &omap44xx_dss_feats
},
1282 { .compatible
= "ti,omap5-dss", .data
= &omap54xx_dss_feats
},
1283 { .compatible
= "ti,dra7-dss", .data
= &dra7xx_dss_feats
},
1286 MODULE_DEVICE_TABLE(of
, dss_of_match
);
1288 static const struct soc_device_attribute dss_soc_devices
[] = {
1289 { .machine
= "OMAP3430/3530", .data
= &omap34xx_dss_feats
},
1290 { .machine
= "AM35??", .data
= &omap34xx_dss_feats
},
1291 { .family
= "AM43xx", .data
= &am43xx_dss_feats
},
1295 static int dss_bind(struct device
*dev
)
1297 struct dss_device
*dss
= dev_get_drvdata(dev
);
1298 struct platform_device
*drm_pdev
;
1301 r
= component_bind_all(dev
, NULL
);
1305 pm_set_vt_switch(0);
1307 omapdss_set_dss(dss
);
1309 drm_pdev
= platform_device_register_simple("omapdrm", 0, NULL
, 0);
1310 if (IS_ERR(drm_pdev
)) {
1311 component_unbind_all(dev
, NULL
);
1312 return PTR_ERR(drm_pdev
);
1315 dss
->drm_pdev
= drm_pdev
;
1320 static void dss_unbind(struct device
*dev
)
1322 struct dss_device
*dss
= dev_get_drvdata(dev
);
1324 platform_device_unregister(dss
->drm_pdev
);
1326 omapdss_set_dss(NULL
);
1328 component_unbind_all(dev
, NULL
);
1331 static const struct component_master_ops dss_component_ops
= {
1333 .unbind
= dss_unbind
,
1336 static int dss_component_compare(struct device
*dev
, void *data
)
1338 struct device
*child
= data
;
1339 return dev
== child
;
1342 static int dss_add_child_component(struct device
*dev
, void *data
)
1344 struct component_match
**match
= data
;
1348 * We don't have a working driver for rfbi, so skip it here always.
1349 * Otherwise dss will never get probed successfully, as it will wait
1350 * for rfbi to get probed.
1352 if (strstr(dev_name(dev
), "rfbi"))
1355 component_match_add(dev
->parent
, match
, dss_component_compare
, dev
);
1360 static int dss_probe_hardware(struct dss_device
*dss
)
1365 r
= dss_runtime_get(dss
);
1369 dss
->dss_clk_rate
= clk_get_rate(dss
->dss_clk
);
1372 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, 0, 0);
1374 dss_select_dispc_clk_source(dss
, DSS_CLK_SRC_FCK
);
1376 #ifdef CONFIG_OMAP2_DSS_VENC
1377 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, 4, 4); /* venc dac demen */
1378 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, 3, 3); /* venc clock 4x enable */
1379 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, 2, 2); /* venc clock mode = normal */
1381 dss
->dsi_clk_source
[0] = DSS_CLK_SRC_FCK
;
1382 dss
->dsi_clk_source
[1] = DSS_CLK_SRC_FCK
;
1383 dss
->dispc_clk_source
= DSS_CLK_SRC_FCK
;
1384 dss
->lcd_clk_source
[0] = DSS_CLK_SRC_FCK
;
1385 dss
->lcd_clk_source
[1] = DSS_CLK_SRC_FCK
;
1387 rev
= dss_read_reg(dss
, DSS_REVISION
);
1388 pr_info("OMAP DSS rev %d.%d\n", FLD_GET(rev
, 7, 4), FLD_GET(rev
, 3, 0));
1390 dss_runtime_put(dss
);
1395 static int dss_probe(struct platform_device
*pdev
)
1397 const struct soc_device_attribute
*soc
;
1398 struct component_match
*match
= NULL
;
1399 struct resource
*dss_mem
;
1400 struct dss_device
*dss
;
1403 dss
= kzalloc(sizeof(*dss
), GFP_KERNEL
);
1408 platform_set_drvdata(pdev
, dss
);
1410 r
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
1412 dev_err(&pdev
->dev
, "Failed to set the DMA mask\n");
1417 * The various OMAP3-based SoCs can't be told apart using the compatible
1418 * string, use SoC device matching.
1420 soc
= soc_device_match(dss_soc_devices
);
1422 dss
->feat
= soc
->data
;
1424 dss
->feat
= of_match_device(dss_of_match
, &pdev
->dev
)->data
;
1426 /* Map I/O registers, get and setup clocks. */
1427 dss_mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1428 dss
->base
= devm_ioremap_resource(&pdev
->dev
, dss_mem
);
1429 if (IS_ERR(dss
->base
)) {
1430 r
= PTR_ERR(dss
->base
);
1434 r
= dss_get_clocks(dss
);
1438 r
= dss_setup_default_clock(dss
);
1440 goto err_put_clocks
;
1442 /* Setup the video PLLs and the DPI and SDI ports. */
1443 r
= dss_video_pll_probe(dss
);
1445 goto err_put_clocks
;
1447 r
= dss_init_ports(dss
);
1449 goto err_uninit_plls
;
1451 /* Enable runtime PM and probe the hardware. */
1452 pm_runtime_enable(&pdev
->dev
);
1454 r
= dss_probe_hardware(dss
);
1456 goto err_pm_runtime_disable
;
1458 /* Initialize debugfs. */
1459 r
= dss_initialize_debugfs(dss
);
1461 goto err_pm_runtime_disable
;
1463 dss
->debugfs
.clk
= dss_debugfs_create_file(dss
, "clk",
1464 dss_debug_dump_clocks
, dss
);
1465 dss
->debugfs
.dss
= dss_debugfs_create_file(dss
, "dss", dss_dump_regs
,
1468 /* Add all the child devices as components. */
1469 r
= of_platform_populate(pdev
->dev
.of_node
, NULL
, NULL
, &pdev
->dev
);
1471 goto err_uninit_debugfs
;
1473 omapdss_gather_components(&pdev
->dev
);
1475 device_for_each_child(&pdev
->dev
, &match
, dss_add_child_component
);
1477 r
= component_master_add_with_match(&pdev
->dev
, &dss_component_ops
, match
);
1479 goto err_of_depopulate
;
1484 of_platform_depopulate(&pdev
->dev
);
1487 dss_debugfs_remove_file(dss
->debugfs
.clk
);
1488 dss_debugfs_remove_file(dss
->debugfs
.dss
);
1489 dss_uninitialize_debugfs(dss
);
1491 err_pm_runtime_disable
:
1492 pm_runtime_disable(&pdev
->dev
);
1493 dss_uninit_ports(dss
);
1496 if (dss
->video1_pll
)
1497 dss_video_pll_uninit(dss
->video1_pll
);
1498 if (dss
->video2_pll
)
1499 dss_video_pll_uninit(dss
->video2_pll
);
1502 dss_put_clocks(dss
);
1510 static int dss_remove(struct platform_device
*pdev
)
1512 struct dss_device
*dss
= platform_get_drvdata(pdev
);
1514 of_platform_depopulate(&pdev
->dev
);
1516 component_master_del(&pdev
->dev
, &dss_component_ops
);
1518 dss_debugfs_remove_file(dss
->debugfs
.clk
);
1519 dss_debugfs_remove_file(dss
->debugfs
.dss
);
1520 dss_uninitialize_debugfs(dss
);
1522 pm_runtime_disable(&pdev
->dev
);
1524 dss_uninit_ports(dss
);
1526 if (dss
->video1_pll
)
1527 dss_video_pll_uninit(dss
->video1_pll
);
1529 if (dss
->video2_pll
)
1530 dss_video_pll_uninit(dss
->video2_pll
);
1532 dss_put_clocks(dss
);
1539 static void dss_shutdown(struct platform_device
*pdev
)
1541 struct omap_dss_device
*dssdev
= NULL
;
1543 DSSDBG("shutdown\n");
1545 for_each_dss_output(dssdev
) {
1546 if (dssdev
->state
== OMAP_DSS_DISPLAY_ACTIVE
)
1547 dssdev
->ops
->disable(dssdev
);
1551 static int dss_runtime_suspend(struct device
*dev
)
1553 struct dss_device
*dss
= dev_get_drvdata(dev
);
1555 dss_save_context(dss
);
1556 dss_set_min_bus_tput(dev
, 0);
1558 pinctrl_pm_select_sleep_state(dev
);
1563 static int dss_runtime_resume(struct device
*dev
)
1565 struct dss_device
*dss
= dev_get_drvdata(dev
);
1568 pinctrl_pm_select_default_state(dev
);
1571 * Set an arbitrarily high tput request to ensure OPP100.
1572 * What we should really do is to make a request to stay in OPP100,
1573 * without any tput requirements, but that is not currently possible
1577 r
= dss_set_min_bus_tput(dev
, 1000000000);
1581 dss_restore_context(dss
);
1585 static const struct dev_pm_ops dss_pm_ops
= {
1586 .runtime_suspend
= dss_runtime_suspend
,
1587 .runtime_resume
= dss_runtime_resume
,
1590 struct platform_driver omap_dsshw_driver
= {
1592 .remove
= dss_remove
,
1593 .shutdown
= dss_shutdown
,
1595 .name
= "omapdss_dss",
1597 .of_match_table
= dss_of_match
,
1598 .suppress_bind_attrs
= true,
1603 static struct platform_driver
* const omap_dss_drivers
[] = {
1605 &omap_dispchw_driver
,
1606 #ifdef CONFIG_OMAP2_DSS_DSI
1609 #ifdef CONFIG_OMAP2_DSS_VENC
1610 &omap_venchw_driver
,
1612 #ifdef CONFIG_OMAP4_DSS_HDMI
1613 &omapdss_hdmi4hw_driver
,
1615 #ifdef CONFIG_OMAP5_DSS_HDMI
1616 &omapdss_hdmi5hw_driver
,
1620 static int __init
omap_dss_init(void)
1622 return platform_register_drivers(omap_dss_drivers
,
1623 ARRAY_SIZE(omap_dss_drivers
));
1626 static void __exit
omap_dss_exit(void)
1628 platform_unregister_drivers(omap_dss_drivers
,
1629 ARRAY_SIZE(omap_dss_drivers
));
1632 module_init(omap_dss_init
);
1633 module_exit(omap_dss_exit
);
1635 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
1636 MODULE_DESCRIPTION("OMAP2/3/4/5 Display Subsystem");
1637 MODULE_LICENSE("GPL v2");