1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/drivers/video/omap2/dss/overlay.c
5 * Copyright (C) 2009 Nokia Corporation
6 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
8 * Some code and ideas taken from drivers/video/omap/ driver
12 #define DSS_SUBSYS_NAME "OVERLAY"
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/err.h>
17 #include <linux/sysfs.h>
18 #include <linux/platform_device.h>
19 #include <linux/delay.h>
20 #include <linux/slab.h>
22 #include <video/omapfb_dss.h>
25 #include "dss_features.h"
27 static int num_overlays
;
28 static struct omap_overlay
*overlays
;
30 int omap_dss_get_num_overlays(void)
34 EXPORT_SYMBOL(omap_dss_get_num_overlays
);
36 struct omap_overlay
*omap_dss_get_overlay(int num
)
38 if (num
>= num_overlays
)
41 return &overlays
[num
];
43 EXPORT_SYMBOL(omap_dss_get_overlay
);
45 void dss_init_overlays(struct platform_device
*pdev
)
49 num_overlays
= dss_feat_get_num_ovls();
51 overlays
= kcalloc(num_overlays
, sizeof(struct omap_overlay
),
54 BUG_ON(overlays
== NULL
);
56 for (i
= 0; i
< num_overlays
; ++i
) {
57 struct omap_overlay
*ovl
= &overlays
[i
];
62 ovl
->id
= OMAP_DSS_GFX
;
66 ovl
->id
= OMAP_DSS_VIDEO1
;
70 ovl
->id
= OMAP_DSS_VIDEO2
;
74 ovl
->id
= OMAP_DSS_VIDEO3
;
78 ovl
->caps
= dss_feat_get_overlay_caps(ovl
->id
);
79 ovl
->supported_modes
=
80 dss_feat_get_supported_color_modes(ovl
->id
);
82 r
= dss_overlay_kobj_init(ovl
, pdev
);
84 DSSERR("failed to create sysfs file\n");
88 void dss_uninit_overlays(struct platform_device
*pdev
)
92 for (i
= 0; i
< num_overlays
; ++i
) {
93 struct omap_overlay
*ovl
= &overlays
[i
];
94 dss_overlay_kobj_uninit(ovl
);
102 int dss_ovl_simple_check(struct omap_overlay
*ovl
,
103 const struct omap_overlay_info
*info
)
105 if ((ovl
->caps
& OMAP_DSS_OVL_CAP_SCALE
) == 0) {
106 if (info
->out_width
!= 0 && info
->width
!= info
->out_width
) {
107 DSSERR("check_overlay: overlay %d doesn't support "
108 "scaling\n", ovl
->id
);
112 if (info
->out_height
!= 0 && info
->height
!= info
->out_height
) {
113 DSSERR("check_overlay: overlay %d doesn't support "
114 "scaling\n", ovl
->id
);
119 if ((ovl
->supported_modes
& info
->color_mode
) == 0) {
120 DSSERR("check_overlay: overlay %d doesn't support mode %d\n",
121 ovl
->id
, info
->color_mode
);
125 if (info
->zorder
>= omap_dss_get_num_overlays()) {
126 DSSERR("check_overlay: zorder %d too high\n", info
->zorder
);
130 if (dss_feat_rotation_type_supported(info
->rotation_type
) == 0) {
131 DSSERR("check_overlay: rotation type %d not supported\n",
132 info
->rotation_type
);
139 int dss_ovl_check(struct omap_overlay
*ovl
, struct omap_overlay_info
*info
,
140 const struct omap_video_timings
*mgr_timings
)
145 dw
= mgr_timings
->x_res
;
146 dh
= mgr_timings
->y_res
;
148 if ((ovl
->caps
& OMAP_DSS_OVL_CAP_SCALE
) == 0) {
152 if (info
->out_width
== 0)
155 outw
= info
->out_width
;
157 if (info
->out_height
== 0)
160 outh
= info
->out_height
;
163 if (dw
< info
->pos_x
+ outw
) {
164 DSSERR("overlay %d horizontally not inside the display area "
166 ovl
->id
, info
->pos_x
, outw
, dw
);
170 if (dh
< info
->pos_y
+ outh
) {
171 DSSERR("overlay %d vertically not inside the display area "
173 ovl
->id
, info
->pos_y
, outh
, dh
);
181 * Checks if replication logic should be used. Only use when overlay is in
182 * RGB12U or RGB16 mode, and video port width interface is 18bpp or 24bpp
184 bool dss_ovl_use_replication(struct dss_lcd_mgr_config config
,
185 enum omap_color_mode mode
)
187 if (mode
!= OMAP_DSS_COLOR_RGB12U
&& mode
!= OMAP_DSS_COLOR_RGB16
)
190 return config
.video_port_width
> 16;