File Index
Files and directories
Sign in
FILE

manager.c

File preview with syntax highlighting.

linux-6.19.14/drivers/video/fbdev/omap2/omapfb/dss/manager.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * linux/drivers/video/omap2/dss/manager.c
  4 *
  5 * Copyright (C) 2009 Nokia Corporation
  6 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
  7 *
  8 * Some code and ideas taken from drivers/video/omap/ driver
  9 * by Imre Deak.
 10 */
 11
 12#define DSS_SUBSYS_NAME "MANAGER"
 13
 14#include <linux/export.h>
 15#include <linux/kernel.h>
 16#include <linux/slab.h>
 17#include <linux/module.h>
 18#include <linux/platform_device.h>
 19#include <linux/jiffies.h>
 20
 21#include <video/omapfb_dss.h>
 22
 23#include "dss.h"
 24#include "dss_features.h"
 25
 26static int num_managers;
 27static struct omap_overlay_manager *managers;
 28
 29int dss_init_overlay_managers(void)
 30{
 31	int i;
 32
 33	num_managers = dss_feat_get_num_mgrs();
 34
 35	managers = kcalloc(num_managers, sizeof(struct omap_overlay_manager),
 36			   GFP_KERNEL);
 37
 38	BUG_ON(managers == NULL);
 39
 40	for (i = 0; i < num_managers; ++i) {
 41		struct omap_overlay_manager *mgr = &managers[i];
 42
 43		switch (i) {
 44		case 0:
 45			mgr->name = "lcd";
 46			mgr->id = OMAP_DSS_CHANNEL_LCD;
 47			break;
 48		case 1:
 49			mgr->name = "tv";
 50			mgr->id = OMAP_DSS_CHANNEL_DIGIT;
 51			break;
 52		case 2:
 53			mgr->name = "lcd2";
 54			mgr->id = OMAP_DSS_CHANNEL_LCD2;
 55			break;
 56		case 3:
 57			mgr->name = "lcd3";
 58			mgr->id = OMAP_DSS_CHANNEL_LCD3;
 59			break;
 60		}
 61
 62		mgr->supported_displays =
 63			dss_feat_get_supported_displays(mgr->id);
 64		mgr->supported_outputs =
 65			dss_feat_get_supported_outputs(mgr->id);
 66
 67		INIT_LIST_HEAD(&mgr->overlays);
 68	}
 69
 70	return 0;
 71}
 72
 73int dss_init_overlay_managers_sysfs(struct platform_device *pdev)
 74{
 75	int i, r;
 76
 77	for (i = 0; i < num_managers; ++i) {
 78		struct omap_overlay_manager *mgr = &managers[i];
 79
 80		r = dss_manager_kobj_init(mgr, pdev);
 81		if (r)
 82			DSSERR("failed to create sysfs file\n");
 83	}
 84
 85	return 0;
 86}
 87
 88void dss_uninit_overlay_managers(void)
 89{
 90	kfree(managers);
 91	managers = NULL;
 92	num_managers = 0;
 93}
 94
 95void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev)
 96{
 97	int i;
 98
 99	for (i = 0; i < num_managers; ++i) {
100		struct omap_overlay_manager *mgr = &managers[i];
101
102		dss_manager_kobj_uninit(mgr);
103	}
104}
105
106int omap_dss_get_num_overlay_managers(void)
107{
108	return num_managers;
109}
110EXPORT_SYMBOL(omap_dss_get_num_overlay_managers);
111
112struct omap_overlay_manager *omap_dss_get_overlay_manager(int num)
113{
114	if (num >= num_managers)
115		return NULL;
116
117	return &managers[num];
118}
119EXPORT_SYMBOL(omap_dss_get_overlay_manager);
120
121int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
122		const struct omap_overlay_manager_info *info)
123{
124	if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
125		/*
126		 * OMAP3 supports only graphics source transparency color key
127		 * and alpha blending simultaneously. See TRM 15.4.2.4.2.2
128		 * Alpha Mode.
129		 */
130		if (info->partial_alpha_enabled && info->trans_enabled
131			&& info->trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST) {
132			DSSERR("check_manager: illegal transparency key\n");
133			return -EINVAL;
134		}
135	}
136
137	return 0;
138}
139
140static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr,
141		struct omap_overlay_info **overlay_infos)
142{
143	struct omap_overlay *ovl1, *ovl2;
144	struct omap_overlay_info *info1, *info2;
145
146	list_for_each_entry(ovl1, &mgr->overlays, list) {
147		info1 = overlay_infos[ovl1->id];
148
149		if (info1 == NULL)
150			continue;
151
152		list_for_each_entry(ovl2, &mgr->overlays, list) {
153			if (ovl1 == ovl2)
154				continue;
155
156			info2 = overlay_infos[ovl2->id];
157
158			if (info2 == NULL)
159				continue;
160
161			if (info1->zorder == info2->zorder) {
162				DSSERR("overlays %d and %d have the same "
163						"zorder %d\n",
164					ovl1->id, ovl2->id, info1->zorder);
165				return -EINVAL;
166			}
167		}
168	}
169
170	return 0;
171}
172
173int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
174		const struct omap_video_timings *timings)
175{
176	if (!dispc_mgr_timings_ok(mgr->id, timings)) {
177		DSSERR("check_manager: invalid timings\n");
178		return -EINVAL;
179	}
180
181	return 0;
182}
183
184static int dss_mgr_check_lcd_config(struct omap_overlay_manager *mgr,
185		const struct dss_lcd_mgr_config *config)
186{
187	struct dispc_clock_info cinfo = config->clock_info;
188	int dl = config->video_port_width;
189	bool stallmode = config->stallmode;
190	bool fifohandcheck = config->fifohandcheck;
191
192	if (cinfo.lck_div < 1 || cinfo.lck_div > 255)
193		return -EINVAL;
194
195	if (cinfo.pck_div < 1 || cinfo.pck_div > 255)
196		return -EINVAL;
197
198	if (dl != 12 && dl != 16 && dl != 18 && dl != 24)
199		return -EINVAL;
200
201	/* fifohandcheck should be used only with stallmode */
202	if (!stallmode && fifohandcheck)
203		return -EINVAL;
204
205	/*
206	 * io pad mode can be only checked by using dssdev connected to the
207	 * manager. Ignore checking these for now, add checks when manager
208	 * is capable of holding information related to the connected interface
209	 */
210
211	return 0;
212}
213
214int dss_mgr_check(struct omap_overlay_manager *mgr,
215		struct omap_overlay_manager_info *info,
216		const struct omap_video_timings *mgr_timings,
217		const struct dss_lcd_mgr_config *lcd_config,
218		struct omap_overlay_info **overlay_infos)
219{
220	struct omap_overlay *ovl;
221	int r;
222
223	if (dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) {
224		r = dss_mgr_check_zorder(mgr, overlay_infos);
225		if (r)
226			return r;
227	}
228
229	r = dss_mgr_check_timings(mgr, mgr_timings);
230	if (r)
231		return r;
232
233	r = dss_mgr_check_lcd_config(mgr, lcd_config);
234	if (r)
235		return r;
236
237	list_for_each_entry(ovl, &mgr->overlays, list) {
238		struct omap_overlay_info *oi;
239		int r;
240
241		oi = overlay_infos[ovl->id];
242
243		if (oi == NULL)
244			continue;
245
246		r = dss_ovl_check(ovl, oi, mgr_timings);
247		if (r)
248			return r;
249	}
250
251	return 0;
252}
~/ Read-only file preview.