aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/dss/manager.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2015-12-09 13:26:00 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2015-12-29 04:07:48 -0500
commit9960aa7cb58caadef8edf3a2582e30664a6b68dd (patch)
treeff7cfe2855cca84c59beccba9f2ca7cea36541c2 /drivers/gpu/drm/omapdrm/dss/manager.c
parent5ca28914b8b4371cfa56b6ee2dec68debb99718f (diff)
drm/omap: move omapdss & displays under omapdrm
Now that omapfb has its own copy of omapdss and display drivers, we can move omapdss and display drivers which omapdrm uses to omapdrm's directory. We also need to change the main drm Makefile so that omapdrm directory is always entered, because omapdss has a file that can't be built as a module. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Acked-by: Dave Airlie <airlied@gmail.com> Acked-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/dss/manager.c')
-rw-r--r--drivers/gpu/drm/omapdrm/dss/manager.c263
1 files changed, 263 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/manager.c b/drivers/gpu/drm/omapdrm/dss/manager.c
new file mode 100644
index 000000000000..08a67f4f6a20
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/manager.c
@@ -0,0 +1,263 @@
1/*
2 * linux/drivers/video/omap2/dss/manager.c
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 *
7 * Some code and ideas taken from drivers/video/omap/ driver
8 * by Imre Deak.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#define DSS_SUBSYS_NAME "MANAGER"
24
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/jiffies.h>
30
31#include <video/omapdss.h>
32
33#include "dss.h"
34#include "dss_features.h"
35
36static int num_managers;
37static struct omap_overlay_manager *managers;
38
39int dss_init_overlay_managers(void)
40{
41 int i;
42
43 num_managers = dss_feat_get_num_mgrs();
44
45 managers = kzalloc(sizeof(struct omap_overlay_manager) * num_managers,
46 GFP_KERNEL);
47
48 BUG_ON(managers == NULL);
49
50 for (i = 0; i < num_managers; ++i) {
51 struct omap_overlay_manager *mgr = &managers[i];
52
53 switch (i) {
54 case 0:
55 mgr->name = "lcd";
56 mgr->id = OMAP_DSS_CHANNEL_LCD;
57 break;
58 case 1:
59 mgr->name = "tv";
60 mgr->id = OMAP_DSS_CHANNEL_DIGIT;
61 break;
62 case 2:
63 mgr->name = "lcd2";
64 mgr->id = OMAP_DSS_CHANNEL_LCD2;
65 break;
66 case 3:
67 mgr->name = "lcd3";
68 mgr->id = OMAP_DSS_CHANNEL_LCD3;
69 break;
70 }
71
72 mgr->caps = 0;
73 mgr->supported_displays =
74 dss_feat_get_supported_displays(mgr->id);
75 mgr->supported_outputs =
76 dss_feat_get_supported_outputs(mgr->id);
77
78 INIT_LIST_HEAD(&mgr->overlays);
79 }
80
81 return 0;
82}
83
84int dss_init_overlay_managers_sysfs(struct platform_device *pdev)
85{
86 int i, r;
87
88 for (i = 0; i < num_managers; ++i) {
89 struct omap_overlay_manager *mgr = &managers[i];
90
91 r = dss_manager_kobj_init(mgr, pdev);
92 if (r)
93 DSSERR("failed to create sysfs file\n");
94 }
95
96 return 0;
97}
98
99void dss_uninit_overlay_managers(void)
100{
101 kfree(managers);
102 managers = NULL;
103 num_managers = 0;
104}
105
106void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev)
107{
108 int i;
109
110 for (i = 0; i < num_managers; ++i) {
111 struct omap_overlay_manager *mgr = &managers[i];
112
113 dss_manager_kobj_uninit(mgr);
114 }
115}
116
117int omap_dss_get_num_overlay_managers(void)
118{
119 return num_managers;
120}
121EXPORT_SYMBOL(omap_dss_get_num_overlay_managers);
122
123struct omap_overlay_manager *omap_dss_get_overlay_manager(int num)
124{
125 if (num >= num_managers)
126 return NULL;
127
128 return &managers[num];
129}
130EXPORT_SYMBOL(omap_dss_get_overlay_manager);
131
132int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
133 const struct omap_overlay_manager_info *info)
134{
135 if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
136 /*
137 * OMAP3 supports only graphics source transparency color key
138 * and alpha blending simultaneously. See TRM 15.4.2.4.2.2
139 * Alpha Mode.
140 */
141 if (info->partial_alpha_enabled && info->trans_enabled
142 && info->trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST) {
143 DSSERR("check_manager: illegal transparency key\n");
144 return -EINVAL;
145 }
146 }
147
148 return 0;
149}
150
151static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr,
152 struct omap_overlay_info **overlay_infos)
153{
154 struct omap_overlay *ovl1, *ovl2;
155 struct omap_overlay_info *info1, *info2;
156
157 list_for_each_entry(ovl1, &mgr->overlays, list) {
158 info1 = overlay_infos[ovl1->id];
159
160 if (info1 == NULL)
161 continue;
162
163 list_for_each_entry(ovl2, &mgr->overlays, list) {
164 if (ovl1 == ovl2)
165 continue;
166
167 info2 = overlay_infos[ovl2->id];
168
169 if (info2 == NULL)
170 continue;
171
172 if (info1->zorder == info2->zorder) {
173 DSSERR("overlays %d and %d have the same "
174 "zorder %d\n",
175 ovl1->id, ovl2->id, info1->zorder);
176 return -EINVAL;
177 }
178 }
179 }
180
181 return 0;
182}
183
184int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
185 const struct omap_video_timings *timings)
186{
187 if (!dispc_mgr_timings_ok(mgr->id, timings)) {
188 DSSERR("check_manager: invalid timings\n");
189 return -EINVAL;
190 }
191
192 return 0;
193}
194
195static int dss_mgr_check_lcd_config(struct omap_overlay_manager *mgr,
196 const struct dss_lcd_mgr_config *config)
197{
198 struct dispc_clock_info cinfo = config->clock_info;
199 int dl = config->video_port_width;
200 bool stallmode = config->stallmode;
201 bool fifohandcheck = config->fifohandcheck;
202
203 if (cinfo.lck_div < 1 || cinfo.lck_div > 255)
204 return -EINVAL;
205
206 if (cinfo.pck_div < 1 || cinfo.pck_div > 255)
207 return -EINVAL;
208
209 if (dl != 12 && dl != 16 && dl != 18 && dl != 24)
210 return -EINVAL;
211
212 /* fifohandcheck should be used only with stallmode */
213 if (!stallmode && fifohandcheck)
214 return -EINVAL;
215
216 /*
217 * io pad mode can be only checked by using dssdev connected to the
218 * manager. Ignore checking these for now, add checks when manager
219 * is capable of holding information related to the connected interface
220 */
221
222 return 0;
223}
224
225int dss_mgr_check(struct omap_overlay_manager *mgr,
226 struct omap_overlay_manager_info *info,
227 const struct omap_video_timings *mgr_timings,
228 const struct dss_lcd_mgr_config *lcd_config,
229 struct omap_overlay_info **overlay_infos)
230{
231 struct omap_overlay *ovl;
232 int r;
233
234 if (dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) {
235 r = dss_mgr_check_zorder(mgr, overlay_infos);
236 if (r)
237 return r;
238 }
239
240 r = dss_mgr_check_timings(mgr, mgr_timings);
241 if (r)
242 return r;
243
244 r = dss_mgr_check_lcd_config(mgr, lcd_config);
245 if (r)
246 return r;
247
248 list_for_each_entry(ovl, &mgr->overlays, list) {
249 struct omap_overlay_info *oi;
250 int r;
251
252 oi = overlay_infos[ovl->id];
253
254 if (oi == NULL)
255 continue;
256
257 r = dss_ovl_check(ovl, oi, mgr_timings);
258 if (r)
259 return r;
260 }
261
262 return 0;
263}