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/property.h>
26 #include <linux/gfp.h>
27 #include <linux/sizes.h>
28 #include <linux/mfd/syscon.h>
29 #include <linux/regmap.h>
31 #include <linux/of_platform.h>
32 #include <linux/of_graph.h>
33 #include <linux/regulator/consumer.h>
34 #include <linux/suspend.h>
35 #include <linux/component.h>
36 #include <linux/sys_soc.h>
45 #define DSS_REG(idx) ((const struct dss_reg) { idx })
47 #define DSS_REVISION DSS_REG(0x0000)
48 #define DSS_SYSCONFIG DSS_REG(0x0010)
49 #define DSS_SYSSTATUS DSS_REG(0x0014)
50 #define DSS_CONTROL DSS_REG(0x0040)
51 #define DSS_SDI_CONTROL DSS_REG(0x0044)
52 #define DSS_PLL_CONTROL DSS_REG(0x0048)
53 #define DSS_SDI_STATUS DSS_REG(0x005C)
55 #define REG_GET(dss, idx, start, end) \
56 FLD_GET(dss_read_reg(dss, idx), start, end)
58 #define REG_FLD_MOD(dss, idx, val, start, end) \
59 dss_write_reg(dss, idx, \
60 FLD_MOD(dss_read_reg(dss, idx), val, start, end))
63 int (*dpi_select_source
)(struct dss_device
*dss
, int port
,
64 enum omap_channel channel
);
65 int (*select_lcd_source
)(struct dss_device
*dss
,
66 enum omap_channel channel
,
67 enum dss_clk_source clk_src
);
73 unsigned int fck_freq_max
;
74 u8 dss_fck_multiplier
;
75 const char *parent_clk_name
;
76 const enum omap_display_type
*ports
;
78 const enum omap_dss_output_id
*outputs
;
79 const struct dss_ops
*ops
;
80 struct dss_reg_field dispc_clk_switch
;
84 static const char * const dss_generic_clk_source_names
[] = {
85 [DSS_CLK_SRC_FCK
] = "FCK",
86 [DSS_CLK_SRC_PLL1_1
] = "PLL1:1",
87 [DSS_CLK_SRC_PLL1_2
] = "PLL1:2",
88 [DSS_CLK_SRC_PLL1_3
] = "PLL1:3",
89 [DSS_CLK_SRC_PLL2_1
] = "PLL2:1",
90 [DSS_CLK_SRC_PLL2_2
] = "PLL2:2",
91 [DSS_CLK_SRC_PLL2_3
] = "PLL2:3",
92 [DSS_CLK_SRC_HDMI_PLL
] = "HDMI PLL",
95 static inline void dss_write_reg(struct dss_device
*dss
,
96 const struct dss_reg idx
, u32 val
)
98 __raw_writel(val
, dss
->base
+ idx
.idx
);
101 static inline u32
dss_read_reg(struct dss_device
*dss
, const struct dss_reg idx
)
103 return __raw_readl(dss
->base
+ idx
.idx
);
106 #define SR(dss, reg) \
107 dss->ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(dss, DSS_##reg)
108 #define RR(dss, reg) \
109 dss_write_reg(dss, DSS_##reg, dss->ctx[(DSS_##reg).idx / sizeof(u32)])
111 static void dss_save_context(struct dss_device
*dss
)
113 DSSDBG("dss_save_context\n");
117 if (dss
->feat
->outputs
[OMAP_DSS_CHANNEL_LCD
] & OMAP_DSS_OUTPUT_SDI
) {
118 SR(dss
, SDI_CONTROL
);
119 SR(dss
, PLL_CONTROL
);
122 dss
->ctx_valid
= true;
124 DSSDBG("context saved\n");
127 static void dss_restore_context(struct dss_device
*dss
)
129 DSSDBG("dss_restore_context\n");
136 if (dss
->feat
->outputs
[OMAP_DSS_CHANNEL_LCD
] & OMAP_DSS_OUTPUT_SDI
) {
137 RR(dss
, SDI_CONTROL
);
138 RR(dss
, PLL_CONTROL
);
141 DSSDBG("context restored\n");
147 void dss_ctrl_pll_enable(struct dss_pll
*pll
, bool enable
)
152 if (!pll
->dss
->syscon_pll_ctrl
)
168 DSSERR("illegal DSS PLL ID %d\n", pll
->id
);
172 regmap_update_bits(pll
->dss
->syscon_pll_ctrl
,
173 pll
->dss
->syscon_pll_ctrl_offset
,
174 1 << shift
, val
<< shift
);
177 static int dss_ctrl_pll_set_control_mux(struct dss_device
*dss
,
178 enum dss_clk_source clk_src
,
179 enum omap_channel channel
)
181 unsigned int shift
, val
;
183 if (!dss
->syscon_pll_ctrl
)
187 case OMAP_DSS_CHANNEL_LCD
:
191 case DSS_CLK_SRC_PLL1_1
:
193 case DSS_CLK_SRC_HDMI_PLL
:
196 DSSERR("error in PLL mux config for LCD\n");
201 case OMAP_DSS_CHANNEL_LCD2
:
205 case DSS_CLK_SRC_PLL1_3
:
207 case DSS_CLK_SRC_PLL2_3
:
209 case DSS_CLK_SRC_HDMI_PLL
:
212 DSSERR("error in PLL mux config for LCD2\n");
217 case OMAP_DSS_CHANNEL_LCD3
:
221 case DSS_CLK_SRC_PLL2_1
:
223 case DSS_CLK_SRC_PLL1_3
:
225 case DSS_CLK_SRC_HDMI_PLL
:
228 DSSERR("error in PLL mux config for LCD3\n");
234 DSSERR("error in PLL mux config\n");
238 regmap_update_bits(dss
->syscon_pll_ctrl
, dss
->syscon_pll_ctrl_offset
,
239 0x3 << shift
, val
<< shift
);
244 void dss_sdi_init(struct dss_device
*dss
, int datapairs
)
248 BUG_ON(datapairs
> 3 || datapairs
< 1);
250 l
= dss_read_reg(dss
, DSS_SDI_CONTROL
);
251 l
= FLD_MOD(l
, 0xf, 19, 15); /* SDI_PDIV */
252 l
= FLD_MOD(l
, datapairs
-1, 3, 2); /* SDI_PRSEL */
253 l
= FLD_MOD(l
, 2, 1, 0); /* SDI_BWSEL */
254 dss_write_reg(dss
, DSS_SDI_CONTROL
, l
);
256 l
= dss_read_reg(dss
, DSS_PLL_CONTROL
);
257 l
= FLD_MOD(l
, 0x7, 25, 22); /* SDI_PLL_FREQSEL */
258 l
= FLD_MOD(l
, 0xb, 16, 11); /* SDI_PLL_REGN */
259 l
= FLD_MOD(l
, 0xb4, 10, 1); /* SDI_PLL_REGM */
260 dss_write_reg(dss
, DSS_PLL_CONTROL
, l
);
263 int dss_sdi_enable(struct dss_device
*dss
)
265 unsigned long timeout
;
267 dispc_pck_free_enable(dss
->dispc
, 1);
270 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 1, 18, 18); /* SDI_PLL_SYSRESET */
271 udelay(1); /* wait 2x PCLK */
274 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 1, 28, 28); /* SDI_PLL_GOBIT */
276 /* Waiting for PLL lock request to complete */
277 timeout
= jiffies
+ msecs_to_jiffies(500);
278 while (dss_read_reg(dss
, DSS_SDI_STATUS
) & (1 << 6)) {
279 if (time_after_eq(jiffies
, timeout
)) {
280 DSSERR("PLL lock request timed out\n");
285 /* Clearing PLL_GO bit */
286 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 0, 28, 28);
288 /* Waiting for PLL to lock */
289 timeout
= jiffies
+ msecs_to_jiffies(500);
290 while (!(dss_read_reg(dss
, DSS_SDI_STATUS
) & (1 << 5))) {
291 if (time_after_eq(jiffies
, timeout
)) {
292 DSSERR("PLL lock timed out\n");
297 dispc_lcd_enable_signal(dss
->dispc
, 1);
299 /* Waiting for SDI reset to complete */
300 timeout
= jiffies
+ msecs_to_jiffies(500);
301 while (!(dss_read_reg(dss
, DSS_SDI_STATUS
) & (1 << 2))) {
302 if (time_after_eq(jiffies
, timeout
)) {
303 DSSERR("SDI reset timed out\n");
311 dispc_lcd_enable_signal(dss
->dispc
, 0);
314 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 0, 18, 18); /* SDI_PLL_SYSRESET */
316 dispc_pck_free_enable(dss
->dispc
, 0);
321 void dss_sdi_disable(struct dss_device
*dss
)
323 dispc_lcd_enable_signal(dss
->dispc
, 0);
325 dispc_pck_free_enable(dss
->dispc
, 0);
328 REG_FLD_MOD(dss
, DSS_PLL_CONTROL
, 0, 18, 18); /* SDI_PLL_SYSRESET */
331 const char *dss_get_clk_source_name(enum dss_clk_source clk_src
)
333 return dss_generic_clk_source_names
[clk_src
];
336 static void dss_dump_clocks(struct dss_device
*dss
, struct seq_file
*s
)
338 const char *fclk_name
;
339 unsigned long fclk_rate
;
341 if (dss_runtime_get(dss
))
344 seq_printf(s
, "- DSS -\n");
346 fclk_name
= dss_get_clk_source_name(DSS_CLK_SRC_FCK
);
347 fclk_rate
= clk_get_rate(dss
->dss_clk
);
349 seq_printf(s
, "%s = %lu\n",
353 dss_runtime_put(dss
);
356 static int dss_dump_regs(struct seq_file
*s
, void *p
)
358 struct dss_device
*dss
= s
->private;
360 #define DUMPREG(dss, r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(dss, r))
362 if (dss_runtime_get(dss
))
365 DUMPREG(dss
, DSS_REVISION
);
366 DUMPREG(dss
, DSS_SYSCONFIG
);
367 DUMPREG(dss
, DSS_SYSSTATUS
);
368 DUMPREG(dss
, DSS_CONTROL
);
370 if (dss
->feat
->outputs
[OMAP_DSS_CHANNEL_LCD
] & OMAP_DSS_OUTPUT_SDI
) {
371 DUMPREG(dss
, DSS_SDI_CONTROL
);
372 DUMPREG(dss
, DSS_PLL_CONTROL
);
373 DUMPREG(dss
, DSS_SDI_STATUS
);
376 dss_runtime_put(dss
);
381 static int dss_debug_dump_clocks(struct seq_file
*s
, void *p
)
383 struct dss_device
*dss
= s
->private;
385 dss_dump_clocks(dss
, s
);
386 dispc_dump_clocks(dss
->dispc
, s
);
390 static int dss_get_channel_index(enum omap_channel channel
)
393 case OMAP_DSS_CHANNEL_LCD
:
395 case OMAP_DSS_CHANNEL_LCD2
:
397 case OMAP_DSS_CHANNEL_LCD3
:
405 static void dss_select_dispc_clk_source(struct dss_device
*dss
,
406 enum dss_clk_source clk_src
)
411 * We always use PRCM clock as the DISPC func clock, except on DSS3,
412 * where we don't have separate DISPC and LCD clock sources.
414 if (WARN_ON(dss
->feat
->has_lcd_clk_src
&& clk_src
!= DSS_CLK_SRC_FCK
))
418 case DSS_CLK_SRC_FCK
:
421 case DSS_CLK_SRC_PLL1_1
:
424 case DSS_CLK_SRC_PLL2_1
:
432 REG_FLD_MOD(dss
, DSS_CONTROL
, b
, /* DISPC_CLK_SWITCH */
433 dss
->feat
->dispc_clk_switch
.start
,
434 dss
->feat
->dispc_clk_switch
.end
);
436 dss
->dispc_clk_source
= clk_src
;
439 void dss_select_dsi_clk_source(struct dss_device
*dss
, int dsi_module
,
440 enum dss_clk_source clk_src
)
445 case DSS_CLK_SRC_FCK
:
448 case DSS_CLK_SRC_PLL1_2
:
449 BUG_ON(dsi_module
!= 0);
452 case DSS_CLK_SRC_PLL2_2
:
453 BUG_ON(dsi_module
!= 1);
461 pos
= dsi_module
== 0 ? 1 : 10;
462 REG_FLD_MOD(dss
, DSS_CONTROL
, b
, pos
, pos
); /* DSIx_CLK_SWITCH */
464 dss
->dsi_clk_source
[dsi_module
] = clk_src
;
467 static int dss_lcd_clk_mux_dra7(struct dss_device
*dss
,
468 enum omap_channel channel
,
469 enum dss_clk_source clk_src
)
471 const u8 ctrl_bits
[] = {
472 [OMAP_DSS_CHANNEL_LCD
] = 0,
473 [OMAP_DSS_CHANNEL_LCD2
] = 12,
474 [OMAP_DSS_CHANNEL_LCD3
] = 19,
477 u8 ctrl_bit
= ctrl_bits
[channel
];
480 if (clk_src
== DSS_CLK_SRC_FCK
) {
481 /* LCDx_CLK_SWITCH */
482 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, ctrl_bit
, ctrl_bit
);
486 r
= dss_ctrl_pll_set_control_mux(dss
, clk_src
, channel
);
490 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, ctrl_bit
, ctrl_bit
);
495 static int dss_lcd_clk_mux_omap5(struct dss_device
*dss
,
496 enum omap_channel channel
,
497 enum dss_clk_source clk_src
)
499 const u8 ctrl_bits
[] = {
500 [OMAP_DSS_CHANNEL_LCD
] = 0,
501 [OMAP_DSS_CHANNEL_LCD2
] = 12,
502 [OMAP_DSS_CHANNEL_LCD3
] = 19,
504 const enum dss_clk_source allowed_plls
[] = {
505 [OMAP_DSS_CHANNEL_LCD
] = DSS_CLK_SRC_PLL1_1
,
506 [OMAP_DSS_CHANNEL_LCD2
] = DSS_CLK_SRC_FCK
,
507 [OMAP_DSS_CHANNEL_LCD3
] = DSS_CLK_SRC_PLL2_1
,
510 u8 ctrl_bit
= ctrl_bits
[channel
];
512 if (clk_src
== DSS_CLK_SRC_FCK
) {
513 /* LCDx_CLK_SWITCH */
514 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, ctrl_bit
, ctrl_bit
);
518 if (WARN_ON(allowed_plls
[channel
] != clk_src
))
521 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, ctrl_bit
, ctrl_bit
);
526 static int dss_lcd_clk_mux_omap4(struct dss_device
*dss
,
527 enum omap_channel channel
,
528 enum dss_clk_source clk_src
)
530 const u8 ctrl_bits
[] = {
531 [OMAP_DSS_CHANNEL_LCD
] = 0,
532 [OMAP_DSS_CHANNEL_LCD2
] = 12,
534 const enum dss_clk_source allowed_plls
[] = {
535 [OMAP_DSS_CHANNEL_LCD
] = DSS_CLK_SRC_PLL1_1
,
536 [OMAP_DSS_CHANNEL_LCD2
] = DSS_CLK_SRC_PLL2_1
,
539 u8 ctrl_bit
= ctrl_bits
[channel
];
541 if (clk_src
== DSS_CLK_SRC_FCK
) {
542 /* LCDx_CLK_SWITCH */
543 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, ctrl_bit
, ctrl_bit
);
547 if (WARN_ON(allowed_plls
[channel
] != clk_src
))
550 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, ctrl_bit
, ctrl_bit
);
555 void dss_select_lcd_clk_source(struct dss_device
*dss
,
556 enum omap_channel channel
,
557 enum dss_clk_source clk_src
)
559 int idx
= dss_get_channel_index(channel
);
562 if (!dss
->feat
->has_lcd_clk_src
) {
563 dss_select_dispc_clk_source(dss
, clk_src
);
564 dss
->lcd_clk_source
[idx
] = clk_src
;
568 r
= dss
->feat
->ops
->select_lcd_source(dss
, channel
, clk_src
);
572 dss
->lcd_clk_source
[idx
] = clk_src
;
575 enum dss_clk_source
dss_get_dispc_clk_source(struct dss_device
*dss
)
577 return dss
->dispc_clk_source
;
580 enum dss_clk_source
dss_get_dsi_clk_source(struct dss_device
*dss
,
583 return dss
->dsi_clk_source
[dsi_module
];
586 enum dss_clk_source
dss_get_lcd_clk_source(struct dss_device
*dss
,
587 enum omap_channel channel
)
589 if (dss
->feat
->has_lcd_clk_src
) {
590 int idx
= dss_get_channel_index(channel
);
591 return dss
->lcd_clk_source
[idx
];
593 /* LCD_CLK source is the same as DISPC_FCLK source for
595 return dss
->dispc_clk_source
;
599 bool dss_div_calc(struct dss_device
*dss
, unsigned long pck
,
600 unsigned long fck_min
, dss_div_calc_func func
, void *data
)
602 int fckd
, fckd_start
, fckd_stop
;
604 unsigned long fck_hw_max
;
605 unsigned long fckd_hw_max
;
609 fck_hw_max
= dss
->feat
->fck_freq_max
;
611 if (dss
->parent_clk
== NULL
) {
614 pckd
= fck_hw_max
/ pck
;
618 fck
= clk_round_rate(dss
->dss_clk
, fck
);
620 return func(fck
, data
);
623 fckd_hw_max
= dss
->feat
->fck_div_max
;
625 m
= dss
->feat
->dss_fck_multiplier
;
626 prate
= clk_get_rate(dss
->parent_clk
);
628 fck_min
= fck_min
? fck_min
: 1;
630 fckd_start
= min(prate
* m
/ fck_min
, fckd_hw_max
);
631 fckd_stop
= max(DIV_ROUND_UP(prate
* m
, fck_hw_max
), 1ul);
633 for (fckd
= fckd_start
; fckd
>= fckd_stop
; --fckd
) {
634 fck
= DIV_ROUND_UP(prate
, fckd
) * m
;
643 int dss_set_fck_rate(struct dss_device
*dss
, unsigned long rate
)
647 DSSDBG("set fck to %lu\n", rate
);
649 r
= clk_set_rate(dss
->dss_clk
, rate
);
653 dss
->dss_clk_rate
= clk_get_rate(dss
->dss_clk
);
655 WARN_ONCE(dss
->dss_clk_rate
!= rate
, "clk rate mismatch: %lu != %lu",
656 dss
->dss_clk_rate
, rate
);
661 unsigned long dss_get_dispc_clk_rate(struct dss_device
*dss
)
663 return dss
->dss_clk_rate
;
666 unsigned long dss_get_max_fck_rate(struct dss_device
*dss
)
668 return dss
->feat
->fck_freq_max
;
671 static int dss_setup_default_clock(struct dss_device
*dss
)
673 unsigned long max_dss_fck
, prate
;
675 unsigned int fck_div
;
678 max_dss_fck
= dss
->feat
->fck_freq_max
;
680 if (dss
->parent_clk
== NULL
) {
681 fck
= clk_round_rate(dss
->dss_clk
, max_dss_fck
);
683 prate
= clk_get_rate(dss
->parent_clk
);
685 fck_div
= DIV_ROUND_UP(prate
* dss
->feat
->dss_fck_multiplier
,
687 fck
= DIV_ROUND_UP(prate
, fck_div
)
688 * dss
->feat
->dss_fck_multiplier
;
691 r
= dss_set_fck_rate(dss
, fck
);
698 void dss_set_venc_output(struct dss_device
*dss
, enum omap_dss_venc_type type
)
702 if (type
== OMAP_DSS_VENC_TYPE_COMPOSITE
)
704 else if (type
== OMAP_DSS_VENC_TYPE_SVIDEO
)
709 /* venc out selection. 0 = comp, 1 = svideo */
710 REG_FLD_MOD(dss
, DSS_CONTROL
, l
, 6, 6);
713 void dss_set_dac_pwrdn_bgz(struct dss_device
*dss
, bool enable
)
715 /* DAC Power-Down Control */
716 REG_FLD_MOD(dss
, DSS_CONTROL
, enable
, 5, 5);
719 void dss_select_hdmi_venc_clk_source(struct dss_device
*dss
,
720 enum dss_hdmi_venc_clk_source_select src
)
722 enum omap_dss_output_id outputs
;
724 outputs
= dss
->feat
->outputs
[OMAP_DSS_CHANNEL_DIGIT
];
726 /* Complain about invalid selections */
727 WARN_ON((src
== DSS_VENC_TV_CLK
) && !(outputs
& OMAP_DSS_OUTPUT_VENC
));
728 WARN_ON((src
== DSS_HDMI_M_PCLK
) && !(outputs
& OMAP_DSS_OUTPUT_HDMI
));
730 /* Select only if we have options */
731 if ((outputs
& OMAP_DSS_OUTPUT_VENC
) &&
732 (outputs
& OMAP_DSS_OUTPUT_HDMI
))
733 /* VENC_HDMI_SWITCH */
734 REG_FLD_MOD(dss
, DSS_CONTROL
, src
, 15, 15);
737 static int dss_dpi_select_source_omap2_omap3(struct dss_device
*dss
, int port
,
738 enum omap_channel channel
)
740 if (channel
!= OMAP_DSS_CHANNEL_LCD
)
746 static int dss_dpi_select_source_omap4(struct dss_device
*dss
, int port
,
747 enum omap_channel channel
)
752 case OMAP_DSS_CHANNEL_LCD2
:
755 case OMAP_DSS_CHANNEL_DIGIT
:
762 REG_FLD_MOD(dss
, DSS_CONTROL
, val
, 17, 17);
767 static int dss_dpi_select_source_omap5(struct dss_device
*dss
, int port
,
768 enum omap_channel channel
)
773 case OMAP_DSS_CHANNEL_LCD
:
776 case OMAP_DSS_CHANNEL_LCD2
:
779 case OMAP_DSS_CHANNEL_LCD3
:
782 case OMAP_DSS_CHANNEL_DIGIT
:
789 REG_FLD_MOD(dss
, DSS_CONTROL
, val
, 17, 16);
794 static int dss_dpi_select_source_dra7xx(struct dss_device
*dss
, int port
,
795 enum omap_channel channel
)
799 return dss_dpi_select_source_omap5(dss
, port
, channel
);
801 if (channel
!= OMAP_DSS_CHANNEL_LCD2
)
805 if (channel
!= OMAP_DSS_CHANNEL_LCD3
)
815 int dss_dpi_select_source(struct dss_device
*dss
, int port
,
816 enum omap_channel channel
)
818 return dss
->feat
->ops
->dpi_select_source(dss
, port
, channel
);
821 static int dss_get_clocks(struct dss_device
*dss
)
825 clk
= devm_clk_get(&dss
->pdev
->dev
, "fck");
827 DSSERR("can't get clock fck\n");
833 if (dss
->feat
->parent_clk_name
) {
834 clk
= clk_get(NULL
, dss
->feat
->parent_clk_name
);
836 DSSERR("Failed to get %s\n",
837 dss
->feat
->parent_clk_name
);
844 dss
->parent_clk
= clk
;
849 static void dss_put_clocks(struct dss_device
*dss
)
852 clk_put(dss
->parent_clk
);
855 int dss_runtime_get(struct dss_device
*dss
)
859 DSSDBG("dss_runtime_get\n");
861 r
= pm_runtime_get_sync(&dss
->pdev
->dev
);
862 if (WARN_ON(r
< 0)) {
863 pm_runtime_put_noidle(&dss
->pdev
->dev
);
869 void dss_runtime_put(struct dss_device
*dss
)
873 DSSDBG("dss_runtime_put\n");
875 r
= pm_runtime_put_sync(&dss
->pdev
->dev
);
876 WARN_ON(r
< 0 && r
!= -ENOSYS
&& r
!= -EBUSY
);
879 struct dss_device
*dss_get_device(struct device
*dev
)
881 return dev_get_drvdata(dev
);
885 #if defined(CONFIG_OMAP2_DSS_DEBUGFS)
886 static int dss_initialize_debugfs(struct dss_device
*dss
)
890 dir
= debugfs_create_dir("omapdss", NULL
);
894 dss
->debugfs
.root
= dir
;
899 static void dss_uninitialize_debugfs(struct dss_device
*dss
)
901 debugfs_remove_recursive(dss
->debugfs
.root
);
904 struct dss_debugfs_entry
{
905 struct dentry
*dentry
;
906 int (*show_fn
)(struct seq_file
*s
, void *data
);
910 static int dss_debug_open(struct inode
*inode
, struct file
*file
)
912 struct dss_debugfs_entry
*entry
= inode
->i_private
;
914 return single_open(file
, entry
->show_fn
, entry
->data
);
917 static const struct file_operations dss_debug_fops
= {
918 .open
= dss_debug_open
,
921 .release
= single_release
,
924 struct dss_debugfs_entry
*
925 dss_debugfs_create_file(struct dss_device
*dss
, const char *name
,
926 int (*show_fn
)(struct seq_file
*s
, void *data
),
929 struct dss_debugfs_entry
*entry
;
931 entry
= kzalloc(sizeof(*entry
), GFP_KERNEL
);
933 return ERR_PTR(-ENOMEM
);
935 entry
->show_fn
= show_fn
;
937 entry
->dentry
= debugfs_create_file(name
, 0444, dss
->debugfs
.root
,
938 entry
, &dss_debug_fops
);
943 void dss_debugfs_remove_file(struct dss_debugfs_entry
*entry
)
945 if (IS_ERR_OR_NULL(entry
))
948 debugfs_remove(entry
->dentry
);
952 #else /* CONFIG_OMAP2_DSS_DEBUGFS */
953 static inline int dss_initialize_debugfs(struct dss_device
*dss
)
957 static inline void dss_uninitialize_debugfs(struct dss_device
*dss
)
960 #endif /* CONFIG_OMAP2_DSS_DEBUGFS */
962 static const struct dss_ops dss_ops_omap2_omap3
= {
963 .dpi_select_source
= &dss_dpi_select_source_omap2_omap3
,
966 static const struct dss_ops dss_ops_omap4
= {
967 .dpi_select_source
= &dss_dpi_select_source_omap4
,
968 .select_lcd_source
= &dss_lcd_clk_mux_omap4
,
971 static const struct dss_ops dss_ops_omap5
= {
972 .dpi_select_source
= &dss_dpi_select_source_omap5
,
973 .select_lcd_source
= &dss_lcd_clk_mux_omap5
,
976 static const struct dss_ops dss_ops_dra7
= {
977 .dpi_select_source
= &dss_dpi_select_source_dra7xx
,
978 .select_lcd_source
= &dss_lcd_clk_mux_dra7
,
981 static const enum omap_display_type omap2plus_ports
[] = {
982 OMAP_DISPLAY_TYPE_DPI
,
985 static const enum omap_display_type omap34xx_ports
[] = {
986 OMAP_DISPLAY_TYPE_DPI
,
987 OMAP_DISPLAY_TYPE_SDI
,
990 static const enum omap_display_type dra7xx_ports
[] = {
991 OMAP_DISPLAY_TYPE_DPI
,
992 OMAP_DISPLAY_TYPE_DPI
,
993 OMAP_DISPLAY_TYPE_DPI
,
996 static const enum omap_dss_output_id omap2_dss_supported_outputs
[] = {
997 /* OMAP_DSS_CHANNEL_LCD */
998 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
,
1000 /* OMAP_DSS_CHANNEL_DIGIT */
1001 OMAP_DSS_OUTPUT_VENC
,
1004 static const enum omap_dss_output_id omap3430_dss_supported_outputs
[] = {
1005 /* OMAP_DSS_CHANNEL_LCD */
1006 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1007 OMAP_DSS_OUTPUT_SDI
| OMAP_DSS_OUTPUT_DSI1
,
1009 /* OMAP_DSS_CHANNEL_DIGIT */
1010 OMAP_DSS_OUTPUT_VENC
,
1013 static const enum omap_dss_output_id omap3630_dss_supported_outputs
[] = {
1014 /* OMAP_DSS_CHANNEL_LCD */
1015 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1016 OMAP_DSS_OUTPUT_DSI1
,
1018 /* OMAP_DSS_CHANNEL_DIGIT */
1019 OMAP_DSS_OUTPUT_VENC
,
1022 static const enum omap_dss_output_id am43xx_dss_supported_outputs
[] = {
1023 /* OMAP_DSS_CHANNEL_LCD */
1024 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
,
1027 static const enum omap_dss_output_id omap4_dss_supported_outputs
[] = {
1028 /* OMAP_DSS_CHANNEL_LCD */
1029 OMAP_DSS_OUTPUT_DBI
| OMAP_DSS_OUTPUT_DSI1
,
1031 /* OMAP_DSS_CHANNEL_DIGIT */
1032 OMAP_DSS_OUTPUT_VENC
| OMAP_DSS_OUTPUT_HDMI
,
1034 /* OMAP_DSS_CHANNEL_LCD2 */
1035 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1036 OMAP_DSS_OUTPUT_DSI2
,
1039 static const enum omap_dss_output_id omap5_dss_supported_outputs
[] = {
1040 /* OMAP_DSS_CHANNEL_LCD */
1041 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1042 OMAP_DSS_OUTPUT_DSI1
| OMAP_DSS_OUTPUT_DSI2
,
1044 /* OMAP_DSS_CHANNEL_DIGIT */
1045 OMAP_DSS_OUTPUT_HDMI
,
1047 /* OMAP_DSS_CHANNEL_LCD2 */
1048 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1049 OMAP_DSS_OUTPUT_DSI1
,
1051 /* OMAP_DSS_CHANNEL_LCD3 */
1052 OMAP_DSS_OUTPUT_DPI
| OMAP_DSS_OUTPUT_DBI
|
1053 OMAP_DSS_OUTPUT_DSI2
,
1056 static const struct dss_features omap24xx_dss_feats
= {
1057 .model
= DSS_MODEL_OMAP2
,
1059 * fck div max is really 16, but the divider range has gaps. The range
1060 * from 1 to 6 has no gaps, so let's use that as a max.
1063 .fck_freq_max
= 133000000,
1064 .dss_fck_multiplier
= 2,
1065 .parent_clk_name
= "core_ck",
1066 .ports
= omap2plus_ports
,
1067 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1068 .outputs
= omap2_dss_supported_outputs
,
1069 .ops
= &dss_ops_omap2_omap3
,
1070 .dispc_clk_switch
= { 0, 0 },
1071 .has_lcd_clk_src
= false,
1074 static const struct dss_features omap34xx_dss_feats
= {
1075 .model
= DSS_MODEL_OMAP3
,
1077 .fck_freq_max
= 173000000,
1078 .dss_fck_multiplier
= 2,
1079 .parent_clk_name
= "dpll4_ck",
1080 .ports
= omap34xx_ports
,
1081 .outputs
= omap3430_dss_supported_outputs
,
1082 .num_ports
= ARRAY_SIZE(omap34xx_ports
),
1083 .ops
= &dss_ops_omap2_omap3
,
1084 .dispc_clk_switch
= { 0, 0 },
1085 .has_lcd_clk_src
= false,
1088 static const struct dss_features omap3630_dss_feats
= {
1089 .model
= DSS_MODEL_OMAP3
,
1091 .fck_freq_max
= 173000000,
1092 .dss_fck_multiplier
= 1,
1093 .parent_clk_name
= "dpll4_ck",
1094 .ports
= omap2plus_ports
,
1095 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1096 .outputs
= omap3630_dss_supported_outputs
,
1097 .ops
= &dss_ops_omap2_omap3
,
1098 .dispc_clk_switch
= { 0, 0 },
1099 .has_lcd_clk_src
= false,
1102 static const struct dss_features omap44xx_dss_feats
= {
1103 .model
= DSS_MODEL_OMAP4
,
1105 .fck_freq_max
= 186000000,
1106 .dss_fck_multiplier
= 1,
1107 .parent_clk_name
= "dpll_per_x2_ck",
1108 .ports
= omap2plus_ports
,
1109 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1110 .outputs
= omap4_dss_supported_outputs
,
1111 .ops
= &dss_ops_omap4
,
1112 .dispc_clk_switch
= { 9, 8 },
1113 .has_lcd_clk_src
= true,
1116 static const struct dss_features omap54xx_dss_feats
= {
1117 .model
= DSS_MODEL_OMAP5
,
1119 .fck_freq_max
= 209250000,
1120 .dss_fck_multiplier
= 1,
1121 .parent_clk_name
= "dpll_per_x2_ck",
1122 .ports
= omap2plus_ports
,
1123 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1124 .outputs
= omap5_dss_supported_outputs
,
1125 .ops
= &dss_ops_omap5
,
1126 .dispc_clk_switch
= { 9, 7 },
1127 .has_lcd_clk_src
= true,
1130 static const struct dss_features am43xx_dss_feats
= {
1131 .model
= DSS_MODEL_OMAP3
,
1133 .fck_freq_max
= 200000000,
1134 .dss_fck_multiplier
= 0,
1135 .parent_clk_name
= NULL
,
1136 .ports
= omap2plus_ports
,
1137 .num_ports
= ARRAY_SIZE(omap2plus_ports
),
1138 .outputs
= am43xx_dss_supported_outputs
,
1139 .ops
= &dss_ops_omap2_omap3
,
1140 .dispc_clk_switch
= { 0, 0 },
1141 .has_lcd_clk_src
= true,
1144 static const struct dss_features dra7xx_dss_feats
= {
1145 .model
= DSS_MODEL_DRA7
,
1147 .fck_freq_max
= 209250000,
1148 .dss_fck_multiplier
= 1,
1149 .parent_clk_name
= "dpll_per_x2_ck",
1150 .ports
= dra7xx_ports
,
1151 .num_ports
= ARRAY_SIZE(dra7xx_ports
),
1152 .outputs
= omap5_dss_supported_outputs
,
1153 .ops
= &dss_ops_dra7
,
1154 .dispc_clk_switch
= { 9, 7 },
1155 .has_lcd_clk_src
= true,
1158 static void __dss_uninit_ports(struct dss_device
*dss
, unsigned int num_ports
)
1160 struct platform_device
*pdev
= dss
->pdev
;
1161 struct device_node
*parent
= pdev
->dev
.of_node
;
1162 struct device_node
*port
;
1165 for (i
= 0; i
< num_ports
; i
++) {
1166 port
= of_graph_get_port_by_id(parent
, i
);
1170 switch (dss
->feat
->ports
[i
]) {
1171 case OMAP_DISPLAY_TYPE_DPI
:
1172 dpi_uninit_port(port
);
1174 case OMAP_DISPLAY_TYPE_SDI
:
1175 sdi_uninit_port(port
);
1184 static int dss_init_ports(struct dss_device
*dss
)
1186 struct platform_device
*pdev
= dss
->pdev
;
1187 struct device_node
*parent
= pdev
->dev
.of_node
;
1188 struct device_node
*port
;
1192 for (i
= 0; i
< dss
->feat
->num_ports
; i
++) {
1193 port
= of_graph_get_port_by_id(parent
, i
);
1197 switch (dss
->feat
->ports
[i
]) {
1198 case OMAP_DISPLAY_TYPE_DPI
:
1199 r
= dpi_init_port(dss
, pdev
, port
, dss
->feat
->model
);
1204 case OMAP_DISPLAY_TYPE_SDI
:
1205 r
= sdi_init_port(dss
, pdev
, port
);
1220 __dss_uninit_ports(dss
, i
);
1224 static void dss_uninit_ports(struct dss_device
*dss
)
1226 __dss_uninit_ports(dss
, dss
->feat
->num_ports
);
1229 static int dss_video_pll_probe(struct dss_device
*dss
)
1231 struct platform_device
*pdev
= dss
->pdev
;
1232 struct device_node
*np
= pdev
->dev
.of_node
;
1233 struct regulator
*pll_regulator
;
1239 if (of_property_read_bool(np
, "syscon-pll-ctrl")) {
1240 dss
->syscon_pll_ctrl
= syscon_regmap_lookup_by_phandle(np
,
1242 if (IS_ERR(dss
->syscon_pll_ctrl
)) {
1244 "failed to get syscon-pll-ctrl regmap\n");
1245 return PTR_ERR(dss
->syscon_pll_ctrl
);
1248 if (of_property_read_u32_index(np
, "syscon-pll-ctrl", 1,
1249 &dss
->syscon_pll_ctrl_offset
)) {
1251 "failed to get syscon-pll-ctrl offset\n");
1256 pll_regulator
= devm_regulator_get(&pdev
->dev
, "vdda_video");
1257 if (IS_ERR(pll_regulator
)) {
1258 r
= PTR_ERR(pll_regulator
);
1262 pll_regulator
= NULL
;
1266 return -EPROBE_DEFER
;
1269 DSSERR("can't get DPLL VDDA regulator\n");
1274 if (of_property_match_string(np
, "reg-names", "pll1") >= 0) {
1275 dss
->video1_pll
= dss_video_pll_init(dss
, pdev
, 0,
1277 if (IS_ERR(dss
->video1_pll
))
1278 return PTR_ERR(dss
->video1_pll
);
1281 if (of_property_match_string(np
, "reg-names", "pll2") >= 0) {
1282 dss
->video2_pll
= dss_video_pll_init(dss
, pdev
, 1,
1284 if (IS_ERR(dss
->video2_pll
)) {
1285 dss_video_pll_uninit(dss
->video1_pll
);
1286 return PTR_ERR(dss
->video2_pll
);
1293 /* DSS HW IP initialisation */
1294 static const struct of_device_id dss_of_match
[] = {
1295 { .compatible
= "ti,omap2-dss", .data
= &omap24xx_dss_feats
},
1296 { .compatible
= "ti,omap3-dss", .data
= &omap3630_dss_feats
},
1297 { .compatible
= "ti,omap4-dss", .data
= &omap44xx_dss_feats
},
1298 { .compatible
= "ti,omap5-dss", .data
= &omap54xx_dss_feats
},
1299 { .compatible
= "ti,dra7-dss", .data
= &dra7xx_dss_feats
},
1302 MODULE_DEVICE_TABLE(of
, dss_of_match
);
1304 static const struct soc_device_attribute dss_soc_devices
[] = {
1305 { .machine
= "OMAP3430/3530", .data
= &omap34xx_dss_feats
},
1306 { .machine
= "AM35??", .data
= &omap34xx_dss_feats
},
1307 { .family
= "AM43xx", .data
= &am43xx_dss_feats
},
1311 static int dss_bind(struct device
*dev
)
1313 struct dss_device
*dss
= dev_get_drvdata(dev
);
1314 struct platform_device
*drm_pdev
;
1315 struct dss_pdata pdata
;
1318 r
= component_bind_all(dev
, NULL
);
1322 pm_set_vt_switch(0);
1325 drm_pdev
= platform_device_register_data(NULL
, "omapdrm", 0,
1326 &pdata
, sizeof(pdata
));
1327 if (IS_ERR(drm_pdev
)) {
1328 component_unbind_all(dev
, NULL
);
1329 return PTR_ERR(drm_pdev
);
1332 dss
->drm_pdev
= drm_pdev
;
1337 static void dss_unbind(struct device
*dev
)
1339 struct dss_device
*dss
= dev_get_drvdata(dev
);
1341 platform_device_unregister(dss
->drm_pdev
);
1343 component_unbind_all(dev
, NULL
);
1346 static const struct component_master_ops dss_component_ops
= {
1348 .unbind
= dss_unbind
,
1351 struct dss_component_match_data
{
1353 struct component_match
**match
;
1356 static int dss_add_child_component(struct device
*dev
, void *data
)
1358 struct dss_component_match_data
*cmatch
= data
;
1359 struct component_match
**match
= cmatch
->match
;
1363 * We don't have a working driver for rfbi, so skip it here always.
1364 * Otherwise dss will never get probed successfully, as it will wait
1365 * for rfbi to get probed.
1367 if (strstr(dev_name(dev
), "rfbi"))
1371 * Handle possible interconnect target modules defined within the DSS.
1372 * The DSS components can be children of an interconnect target module
1373 * after the device tree has been updated for the module data.
1374 * See also omapdss_boot_init() for compatible fixup.
1376 if (strstr(dev_name(dev
), "target-module"))
1377 return device_for_each_child(dev
, cmatch
,
1378 dss_add_child_component
);
1380 component_match_add(cmatch
->dev
, match
, component_compare_dev
, dev
);
1385 static int dss_probe_hardware(struct dss_device
*dss
)
1390 r
= dss_runtime_get(dss
);
1394 dss
->dss_clk_rate
= clk_get_rate(dss
->dss_clk
);
1397 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, 0, 0);
1399 dss_select_dispc_clk_source(dss
, DSS_CLK_SRC_FCK
);
1401 #ifdef CONFIG_OMAP2_DSS_VENC
1402 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, 4, 4); /* venc dac demen */
1403 REG_FLD_MOD(dss
, DSS_CONTROL
, 1, 3, 3); /* venc clock 4x enable */
1404 REG_FLD_MOD(dss
, DSS_CONTROL
, 0, 2, 2); /* venc clock mode = normal */
1406 dss
->dsi_clk_source
[0] = DSS_CLK_SRC_FCK
;
1407 dss
->dsi_clk_source
[1] = DSS_CLK_SRC_FCK
;
1408 dss
->dispc_clk_source
= DSS_CLK_SRC_FCK
;
1409 dss
->lcd_clk_source
[0] = DSS_CLK_SRC_FCK
;
1410 dss
->lcd_clk_source
[1] = DSS_CLK_SRC_FCK
;
1412 rev
= dss_read_reg(dss
, DSS_REVISION
);
1413 pr_info("OMAP DSS rev %d.%d\n", FLD_GET(rev
, 7, 4), FLD_GET(rev
, 3, 0));
1415 dss_runtime_put(dss
);
1420 static int dss_probe(struct platform_device
*pdev
)
1422 const struct soc_device_attribute
*soc
;
1423 struct dss_component_match_data cmatch
;
1424 struct component_match
*match
= NULL
;
1425 struct dss_device
*dss
;
1428 dss
= kzalloc(sizeof(*dss
), GFP_KERNEL
);
1433 platform_set_drvdata(pdev
, dss
);
1435 r
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
1437 dev_err(&pdev
->dev
, "Failed to set the DMA mask\n");
1442 * The various OMAP3-based SoCs can't be told apart using the compatible
1443 * string, use SoC device matching.
1445 soc
= soc_device_match(dss_soc_devices
);
1447 dss
->feat
= soc
->data
;
1449 dss
->feat
= device_get_match_data(&pdev
->dev
);
1451 /* Map I/O registers, get and setup clocks. */
1452 dss
->base
= devm_platform_ioremap_resource(pdev
, 0);
1453 if (IS_ERR(dss
->base
)) {
1454 r
= PTR_ERR(dss
->base
);
1458 r
= dss_get_clocks(dss
);
1462 r
= dss_setup_default_clock(dss
);
1464 goto err_put_clocks
;
1466 /* Setup the video PLLs and the DPI and SDI ports. */
1467 r
= dss_video_pll_probe(dss
);
1469 goto err_put_clocks
;
1471 r
= dss_init_ports(dss
);
1473 goto err_uninit_plls
;
1475 /* Enable runtime PM and probe the hardware. */
1476 pm_runtime_enable(&pdev
->dev
);
1478 r
= dss_probe_hardware(dss
);
1480 goto err_pm_runtime_disable
;
1482 /* Initialize debugfs. */
1483 r
= dss_initialize_debugfs(dss
);
1485 goto err_pm_runtime_disable
;
1487 dss
->debugfs
.clk
= dss_debugfs_create_file(dss
, "clk",
1488 dss_debug_dump_clocks
, dss
);
1489 dss
->debugfs
.dss
= dss_debugfs_create_file(dss
, "dss", dss_dump_regs
,
1492 /* Add all the child devices as components. */
1493 r
= of_platform_populate(pdev
->dev
.of_node
, NULL
, NULL
, &pdev
->dev
);
1495 goto err_uninit_debugfs
;
1497 omapdss_gather_components(&pdev
->dev
);
1499 cmatch
.dev
= &pdev
->dev
;
1500 cmatch
.match
= &match
;
1501 device_for_each_child(&pdev
->dev
, &cmatch
, dss_add_child_component
);
1503 r
= component_master_add_with_match(&pdev
->dev
, &dss_component_ops
, match
);
1505 goto err_of_depopulate
;
1510 of_platform_depopulate(&pdev
->dev
);
1513 dss_debugfs_remove_file(dss
->debugfs
.clk
);
1514 dss_debugfs_remove_file(dss
->debugfs
.dss
);
1515 dss_uninitialize_debugfs(dss
);
1517 err_pm_runtime_disable
:
1518 pm_runtime_disable(&pdev
->dev
);
1519 dss_uninit_ports(dss
);
1522 if (dss
->video1_pll
)
1523 dss_video_pll_uninit(dss
->video1_pll
);
1524 if (dss
->video2_pll
)
1525 dss_video_pll_uninit(dss
->video2_pll
);
1528 dss_put_clocks(dss
);
1536 static void dss_remove(struct platform_device
*pdev
)
1538 struct dss_device
*dss
= platform_get_drvdata(pdev
);
1540 of_platform_depopulate(&pdev
->dev
);
1542 component_master_del(&pdev
->dev
, &dss_component_ops
);
1544 dss_debugfs_remove_file(dss
->debugfs
.clk
);
1545 dss_debugfs_remove_file(dss
->debugfs
.dss
);
1546 dss_uninitialize_debugfs(dss
);
1548 pm_runtime_disable(&pdev
->dev
);
1550 dss_uninit_ports(dss
);
1552 if (dss
->video1_pll
)
1553 dss_video_pll_uninit(dss
->video1_pll
);
1555 if (dss
->video2_pll
)
1556 dss_video_pll_uninit(dss
->video2_pll
);
1558 dss_put_clocks(dss
);
1563 static void dss_shutdown(struct platform_device
*pdev
)
1565 DSSDBG("shutdown\n");
1568 static __maybe_unused
int dss_runtime_suspend(struct device
*dev
)
1570 struct dss_device
*dss
= dev_get_drvdata(dev
);
1572 dss_save_context(dss
);
1573 dss_set_min_bus_tput(dev
, 0);
1575 pinctrl_pm_select_sleep_state(dev
);
1580 static __maybe_unused
int dss_runtime_resume(struct device
*dev
)
1582 struct dss_device
*dss
= dev_get_drvdata(dev
);
1585 pinctrl_pm_select_default_state(dev
);
1588 * Set an arbitrarily high tput request to ensure OPP100.
1589 * What we should really do is to make a request to stay in OPP100,
1590 * without any tput requirements, but that is not currently possible
1594 r
= dss_set_min_bus_tput(dev
, 1000000000);
1598 dss_restore_context(dss
);
1602 static const struct dev_pm_ops dss_pm_ops
= {
1603 SET_RUNTIME_PM_OPS(dss_runtime_suspend
, dss_runtime_resume
, NULL
)
1604 SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
, pm_runtime_force_resume
)
1607 struct platform_driver omap_dsshw_driver
= {
1609 .remove
= dss_remove
,
1610 .shutdown
= dss_shutdown
,
1612 .name
= "omapdss_dss",
1614 .of_match_table
= dss_of_match
,
1615 .suppress_bind_attrs
= true,
1620 static struct platform_driver
* const omap_dss_drivers
[] = {
1622 &omap_dispchw_driver
,
1623 #ifdef CONFIG_OMAP2_DSS_DSI
1626 #ifdef CONFIG_OMAP2_DSS_VENC
1627 &omap_venchw_driver
,
1629 #ifdef CONFIG_OMAP4_DSS_HDMI
1630 &omapdss_hdmi4hw_driver
,
1632 #ifdef CONFIG_OMAP5_DSS_HDMI
1633 &omapdss_hdmi5hw_driver
,
1637 int __init
omap_dss_init(void)
1639 return platform_register_drivers(omap_dss_drivers
,
1640 ARRAY_SIZE(omap_dss_drivers
));
1643 void omap_dss_exit(void)
1645 platform_unregister_drivers(omap_dss_drivers
,
1646 ARRAY_SIZE(omap_dss_drivers
));