apply.c revision 2a4ee7ee685f3bf996461ed0d148857ce85a00e2
158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen/*
258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * Copyright (C) 2011 Texas Instruments
358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *
558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * This program is free software; you can redistribute it and/or modify it
658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * under the terms of the GNU General Public License version 2 as published by
758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * the Free Software Foundation.
858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *
958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * This program is distributed in the hope that it will be useful, but WITHOUT
1058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * more details.
1358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *
1458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * You should have received a copy of the GNU General Public License along with
1558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * this program.  If not, see <http://www.gnu.org/licenses/>.
1658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen */
1758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
1858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#define DSS_SUBSYS_NAME "APPLY"
1958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
2058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#include <linux/kernel.h>
2158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#include <linux/slab.h>
2258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#include <linux/spinlock.h>
2358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#include <linux/jiffies.h>
2458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
2558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#include <video/omapdss.h>
2658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
2758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#include "dss.h"
2858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#include "dss_features.h"
2958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
3058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen/*
3158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * We have 4 levels of cache for the dispc settings. First two are in SW and
3258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * the latter two in HW.
3358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *
340b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen *       set_info()
350b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen *          v
3658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
370b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen * |     user_info      |
3858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
3958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
4058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *        apply()
4158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
4258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
43d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen * |       info         |
4458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
4558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
46f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen *      write_regs()
4758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
4858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
4958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * |  shadow registers  |
5058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
5158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
5258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * VFP or lcd/digit_enable
5358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
5458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
5558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * |      registers     |
5658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
5758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen */
5858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinenstruct ovl_priv_data {
60c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
61c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	bool user_info_dirty;
62c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	struct omap_overlay_info user_info;
63c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
640b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	bool info_dirty;
6558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_info info;
6658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
670b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	bool shadow_info_dirty;
680b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen
69aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	bool extra_info_dirty;
70aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	bool shadow_extra_info_dirty;
71aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
72aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	bool enabled;
735d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	enum omap_channel channel;
746dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	u32 fifo_low, fifo_high;
7558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen};
7658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
77af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinenstruct mgr_priv_data {
78388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen
79388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	bool user_info_dirty;
80388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	struct omap_overlay_manager_info user_info;
81388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen
820b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	bool info_dirty;
8358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_manager_info info;
8458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
850b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	bool shadow_info_dirty;
860b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen
8743a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	/* If true, GO bit is up and shadow registers cannot be written.
8843a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	 * Never true for manual update displays */
8943a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	bool busy;
9043a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
9134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	/* If true, dispc output is enabled */
9234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	bool updating;
9334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
94bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	/* If true, a display is enabled using this manager */
95bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	bool enabled;
9658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen};
9758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic struct {
99c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
100af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
10158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool irq_enabled;
103d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen} dss_data;
10458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
105d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen/* protects dss_data */
106063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinenstatic spinlock_t data_lock;
1075558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen/* lock for blocking functions */
1085558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenstatic DEFINE_MUTEX(apply_lock);
109f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinenstatic DECLARE_COMPLETION(extra_updated_completion);
110063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen
11175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic void dss_register_vsync_isr(void);
11275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
113c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinenstatic struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
114c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen{
115d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	return &dss_data.ovl_priv_data_array[ovl->id];
116c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen}
117c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen
118af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinenstatic struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
119af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen{
120d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	return &dss_data.mgr_priv_data_array[mgr->id];
121af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen}
122af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen
12358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenvoid dss_apply_init(void)
12458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
125c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	const int num_ovls = dss_feat_get_num_ovls();
126c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	int i;
127c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
128063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen	spin_lock_init(&data_lock);
129c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
130c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	for (i = 0; i < num_ovls; ++i) {
131c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		struct ovl_priv_data *op;
132c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
133c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		op = &dss_data.ovl_priv_data_array[i];
134c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
135c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		op->info.global_alpha = 255;
136c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
137c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		switch (i) {
138c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		case 0:
139c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			op->info.zorder = 0;
140c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			break;
141c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		case 1:
142c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			op->info.zorder =
143c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen				dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
144c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			break;
145c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		case 2:
146c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			op->info.zorder =
147c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen				dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
148c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			break;
149c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		case 3:
150c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			op->info.zorder =
151c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen				dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
152c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			break;
153c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		}
154c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
155c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		op->user_info = op->info;
156c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	}
15758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
15858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
15958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic bool ovl_manual_update(struct omap_overlay *ovl)
16058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
16158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
16258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
16358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
16458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic bool mgr_manual_update(struct omap_overlay_manager *mgr)
16558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
16658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
16758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
16858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
16939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen/* Check if overlay parameters are compatible with display */
17039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_ovl_check(struct omap_overlay *ovl,
17139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_info *info, struct omap_dss_device *dssdev)
17239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
17339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	u16 outw, outh;
17439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	u16 dw, dh;
17539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
17639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (dssdev == NULL)
17739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return 0;
17839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
17939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	dssdev->driver->get_resolution(dssdev, &dw, &dh);
18039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
18139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
18239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		outw = info->width;
18339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		outh = info->height;
18439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	} else {
18539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (info->out_width == 0)
18639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			outw = info->width;
18739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		else
18839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			outw = info->out_width;
18939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
19039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (info->out_height == 0)
19139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			outh = info->height;
19239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		else
19339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			outh = info->out_height;
19439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
19539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
19639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (dw < info->pos_x + outw) {
19739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("overlay %d horizontally not inside the display area "
19839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				"(%d + %d >= %d)\n",
19939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				ovl->id, info->pos_x, outw, dw);
20039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return -EINVAL;
20139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
20239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
20339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (dh < info->pos_y + outh) {
20439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("overlay %d vertically not inside the display area "
20539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				"(%d + %d >= %d)\n",
20639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				ovl->id, info->pos_y, outh, dh);
20739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return -EINVAL;
20839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
20939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
21039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return 0;
21139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
21239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
21339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_mgr_check_zorder(struct omap_overlay_manager *mgr,
21439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_info **overlay_infos)
21539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
21639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay *ovl1, *ovl2;
21739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct ovl_priv_data *op1, *op2;
21839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay_info *info1, *info2;
21939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
22039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	list_for_each_entry(ovl1, &mgr->overlays, list) {
22139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		op1 = get_ovl_priv(ovl1);
22239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		info1 = overlay_infos[ovl1->id];
22339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
22439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (info1 == NULL)
22539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			continue;
22639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
22739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		list_for_each_entry(ovl2, &mgr->overlays, list) {
22839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			if (ovl1 == ovl2)
22939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				continue;
23039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
23139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			op2 = get_ovl_priv(ovl2);
23239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			info2 = overlay_infos[ovl2->id];
23339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
23439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			if (info2 == NULL)
23539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				continue;
23639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
23739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			if (info1->zorder == info2->zorder) {
23839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				DSSERR("overlays %d and %d have the same "
23939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen						"zorder %d\n",
24039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen					ovl1->id, ovl2->id, info1->zorder);
24139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				return -EINVAL;
24239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			}
24339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		}
24439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
24539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
24639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return 0;
24739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
24839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
24939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_mgr_check(struct omap_overlay_manager *mgr,
25039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_dss_device *dssdev,
25139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_manager_info *info,
25239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_info **overlay_infos)
25339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
25439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay *ovl;
25539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
25639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
25739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) {
25839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		r = dss_mgr_check_zorder(mgr, overlay_infos);
25939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (r)
26039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			return r;
26139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
26239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
26339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
26439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_info *oi;
26539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		int r;
26639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
26739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		oi = overlay_infos[ovl->id];
26839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
26939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (oi == NULL)
27039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			continue;
27139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
27239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		r = dss_ovl_check(ovl, oi, dssdev);
27339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (r)
27439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			return r;
27539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
27639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
27739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return 0;
27839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
27939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_check_settings_low(struct omap_overlay_manager *mgr,
28039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_dss_device *dssdev, bool applying)
28139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
28239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay_info *oi;
28339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay_manager_info *mi;
28439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay *ovl;
28539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay_info *ois[MAX_DSS_OVERLAYS];
28639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct ovl_priv_data *op;
28739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct mgr_priv_data *mp;
28839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
28939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	mp = get_mgr_priv(mgr);
29039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
29139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (applying && mp->user_info_dirty)
29239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		mi = &mp->user_info;
29339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	else
29439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		mi = &mp->info;
29539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
29639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	/* collect the infos to be tested into the array */
29739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
29839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		op = get_ovl_priv(ovl);
29939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
30039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (!op->enabled)
30139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			oi = NULL;
30239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		else if (applying && op->user_info_dirty)
30339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			oi = &op->user_info;
30439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		else
30539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			oi = &op->info;
30639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
30739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		ois[ovl->id] = oi;
30839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
30939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
31039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return dss_mgr_check(mgr, dssdev, mi, ois);
31139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
31239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
31339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen/*
31439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen * check manager and overlay settings using overlay_info from data->info
31539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen */
31639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_check_settings(struct omap_overlay_manager *mgr,
31739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_dss_device *dssdev)
31839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
31939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return dss_check_settings_low(mgr, dssdev, false);
32039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
32139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
32239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen/*
32339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen * check manager and overlay settings using overlay_info from ovl->info if
32439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen * dirty and from data->info otherwise
32539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen */
32639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_check_settings_apply(struct omap_overlay_manager *mgr,
32739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_dss_device *dssdev)
32839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
32939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return dss_check_settings_low(mgr, dssdev, true);
33039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
33139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
33275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic bool need_isr(void)
33375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen{
33475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
33575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	int i;
33675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
33775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
33875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct omap_overlay_manager *mgr;
33975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct mgr_priv_data *mp;
34075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct omap_overlay *ovl;
34175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
34275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
34375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		mp = get_mgr_priv(mgr);
34475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
34575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		if (!mp->enabled)
34675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen			continue;
34775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
34834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		if (mgr_manual_update(mgr)) {
34934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			/* to catch FRAMEDONE */
35034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			if (mp->updating)
35134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				return true;
35234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		} else {
35334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			/* to catch GO bit going down */
35434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			if (mp->busy)
35534861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				return true;
35675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
35734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			/* to write new values to registers */
3580b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen			if (mp->info_dirty)
35934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				return true;
36075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
36134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			list_for_each_entry(ovl, &mgr->overlays, list) {
36234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				struct ovl_priv_data *op;
36375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
36434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				op = get_ovl_priv(ovl);
36575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
36634861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				if (!op->enabled)
36734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen					continue;
36875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
36934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				/* to write new values to registers */
3700b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen				if (op->info_dirty || op->extra_info_dirty)
37134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen					return true;
37234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			}
37375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		}
37475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
37575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
37675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	return false;
37775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
37875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
37975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic bool need_go(struct omap_overlay_manager *mgr)
38075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen{
38175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct omap_overlay *ovl;
38275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct mgr_priv_data *mp;
38375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct ovl_priv_data *op;
38475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
38575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	mp = get_mgr_priv(mgr);
38675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
3870b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (mp->shadow_info_dirty)
38875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return true;
38975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
39075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
39175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		op = get_ovl_priv(ovl);
3920b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		if (op->shadow_info_dirty || op->shadow_extra_info_dirty)
39375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen			return true;
39475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
39575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
39675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	return false;
39775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
39875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
399f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen/* returns true if an extra_info field is currently being updated */
400f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinenstatic bool extra_info_update_ongoing(void)
401f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen{
402f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	const int num_ovls = omap_dss_get_num_overlays();
403f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct ovl_priv_data *op;
404f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct omap_overlay *ovl;
405f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct mgr_priv_data *mp;
406f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	int i;
407f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	bool eid;
408f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
409f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	for (i = 0; i < num_ovls; ++i) {
410f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		ovl = omap_dss_get_overlay(i);
411f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		op = get_ovl_priv(ovl);
412f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
413f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		if (!op->enabled)
414f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
415f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
416f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		mp = get_mgr_priv(ovl->manager);
417f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
418f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		if (!mp->enabled)
419f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
420f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
421f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		eid = op->extra_info_dirty || op->shadow_extra_info_dirty;
422f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
423f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		if (!eid)
424f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
425f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
426f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		if (ovl_manual_update(ovl) && !mp->updating)
427f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
428f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
429f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		return true;
430f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	}
431f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
432f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	return false;
433f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen}
434f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
435f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen/* wait until no extra_info updates are pending */
436f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinenstatic void wait_pending_extra_info_updates(void)
437f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen{
438f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	bool updating;
439f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	unsigned long flags;
440f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	unsigned long t;
441f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
442f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
443f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
444f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	updating = extra_info_update_ongoing();
445f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
446f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	if (!updating) {
447f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
448f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		return;
449f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	}
450f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
451f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	init_completion(&extra_updated_completion);
452f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
453f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
454f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
455f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	t = msecs_to_jiffies(500);
456f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	wait_for_completion_timeout(&extra_updated_completion, t);
457f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
458f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	updating = extra_info_update_ongoing();
459f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
460f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	WARN_ON(updating);
461f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen}
462f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
46358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
46458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
46558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long timeout = msecs_to_jiffies(500);
466af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
46758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq;
46858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
46958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
47058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev = mgr->device;
47158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
47258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
47358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
47458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
47558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (mgr_manual_update(mgr))
47658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
47758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
478bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	irq = dispc_mgr_get_vsync_irq(mgr->id);
47958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
480af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	mp = get_mgr_priv(mgr);
48158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	i = 0;
48258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	while (1) {
48358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		unsigned long flags;
48458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		bool shadow_dirty, dirty;
48558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
486063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_lock_irqsave(&data_lock, flags);
4870b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		dirty = mp->info_dirty;
4880b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		shadow_dirty = mp->shadow_info_dirty;
489063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
49058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!dirty && !shadow_dirty) {
49258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
49358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
49458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
49558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* 4 iterations is the worst case:
49758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
49858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 2 - first VSYNC, dirty = true
49958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 3 - dirty = false, shadow_dirty = true
50058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 4 - shadow_dirty = false */
50158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (i++ == 3) {
50258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("mgr(%d)->wait_for_go() not finishing\n",
50358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen					mgr->id);
50458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
50558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
50658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
50758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
50858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
50958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r == -ERESTARTSYS)
51058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
51158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r) {
51358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
51458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
51558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
51658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
51758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
51958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
52058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
52158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
52258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
52358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long timeout = msecs_to_jiffies(500);
524c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
52558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
52658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq;
52758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
52858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
52958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!ovl->manager)
53158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
53258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
53458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
53658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
53758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (ovl_manual_update(ovl))
53958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
54058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
541bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
54258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
543c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	op = get_ovl_priv(ovl);
54458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	i = 0;
54558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	while (1) {
54658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		unsigned long flags;
54758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		bool shadow_dirty, dirty;
54858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
549063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_lock_irqsave(&data_lock, flags);
5500b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		dirty = op->info_dirty;
5510b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		shadow_dirty = op->shadow_info_dirty;
552063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
55358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!dirty && !shadow_dirty) {
55558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
55658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
55758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
55858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* 4 iterations is the worst case:
56058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
56158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 2 - first VSYNC, dirty = true
56258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 3 - dirty = false, shadow_dirty = true
56358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 4 - shadow_dirty = false */
56458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (i++ == 3) {
56558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("ovl(%d)->wait_for_go() not finishing\n",
56658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen					ovl->id);
56758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
56858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
56958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
57058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
57158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
57258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r == -ERESTARTSYS)
57358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
57458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
57558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r) {
57658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
57758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
57858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
57958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
58058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
58158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
58258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
58358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
58475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic void dss_ovl_write_regs(struct omap_overlay *ovl)
58558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
58675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
58758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_info *oi;
58858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool ilace, replication;
58934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	struct mgr_priv_data *mp;
59058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
59158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
592f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	DSSDBGF("%d", ovl->id);
59358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
5940b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (!op->enabled || !op->info_dirty)
59575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
59658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	oi = &op->info;
59858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	replication = dss_use_replication(ovl->manager->device, oi->color_mode);
60058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
60158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
60258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
603f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
60458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (r) {
60575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		/*
60675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 * We can't do much here, as this function can be called from
60775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 * vsync interrupt.
60875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 */
609f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen		DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id);
61075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
61175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		/* This will leave fifo configurations in a nonoptimal state */
61275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		op->enabled = false;
61375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_ovl_enable(ovl->id, false);
61475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
61558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
61658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
61734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp = get_mgr_priv(ovl->manager);
61834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
6190b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	op->info_dirty = false;
62034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (mp->updating)
6210b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		op->shadow_info_dirty = true;
62258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
62358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
624aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenstatic void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
625aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
626aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
62734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	struct mgr_priv_data *mp;
628aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
629aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	DSSDBGF("%d", ovl->id);
630aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
63175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!op->extra_info_dirty)
63275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
63375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
634aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	/* note: write also when op->enabled == false, so that the ovl gets
635aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	 * disabled */
636aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
637aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	dispc_ovl_enable(ovl->id, op->enabled);
6385d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	dispc_ovl_set_channel_out(ovl->id, op->channel);
6396dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
64075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
64134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp = get_mgr_priv(ovl->manager);
64234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
64375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	op->extra_info_dirty = false;
64434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (mp->updating)
64534861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		op->shadow_extra_info_dirty = true;
646aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
647aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
648f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinenstatic void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
64958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
65075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
65175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct omap_overlay *ovl;
65258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
653f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	DSSDBGF("%d", mgr->id);
65458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
65575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!mp->enabled)
65675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
65758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
65875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	WARN_ON(mp->busy);
65958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
66058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* Commit overlay settings */
66175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
66275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_ovl_write_regs(ovl);
663aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		dss_ovl_write_regs_extra(ovl);
664aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
665aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
6660b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (mp->info_dirty) {
66775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_mgr_setup(mgr->id, &mp->info);
66858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
6690b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		mp->info_dirty = false;
67034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		if (mp->updating)
6710b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen			mp->shadow_info_dirty = true;
67258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
67375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
67475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
67575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic void dss_write_regs(void)
67675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen{
67775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	const int num_mgrs = omap_dss_get_num_overlay_managers();
67875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	int i;
67958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
68058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
68175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct omap_overlay_manager *mgr;
68275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct mgr_priv_data *mp;
68339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		int r;
68475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
685af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
686af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen		mp = get_mgr_priv(mgr);
68758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
68875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
68958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
69058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
69139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		r = dss_check_settings(mgr, mgr->device);
69239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (r) {
69339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			DSSERR("cannot write registers for manager %s: "
69439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen					"illegal configuration\n", mgr->name);
69539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			continue;
69639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		}
69739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
69875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_mgr_write_regs(mgr);
69975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
70075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		if (need_go(mgr)) {
70143a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen			mp->busy = true;
70258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
70375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen			if (!dss_data.irq_enabled && need_isr())
70475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen				dss_register_vsync_isr();
70558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
70675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen			dispc_mgr_go(mgr->id);
70775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		}
70875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
70958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
71058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
71158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenvoid dss_mgr_start_update(struct omap_overlay_manager *mgr)
71258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
713af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
714e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
71539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
716e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
717e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
71858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
71934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	WARN_ON(mp->updating);
72034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
72139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(mgr, mgr->device);
72239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
72339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("cannot start manual update: illegal configuration\n");
72439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
72539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return;
72639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
72739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
72875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_mgr_write_regs(mgr);
72958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
73034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp->updating = true;
73158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
73234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (!dss_data.irq_enabled && need_isr())
73334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		dss_register_vsync_isr();
73458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7357797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen	dispc_mgr_enable(mgr->id, true);
736e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
737e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
73858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
73958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
740dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_apply_irq_handler(void *data, u32 mask);
741dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
742dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_register_vsync_isr(void)
743dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen{
744bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
745dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	u32 mask;
746bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	int r, i;
747dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
748bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	mask = 0;
749bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
750bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen		mask |= dispc_mgr_get_vsync_irq(i);
751dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
75234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
75334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mask |= dispc_mgr_get_framedone_irq(i);
75434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
755dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
756dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	WARN_ON(r);
757dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
758d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	dss_data.irq_enabled = true;
759dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen}
760dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
761dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_unregister_vsync_isr(void)
762dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen{
763bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
764dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	u32 mask;
765bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	int r, i;
766dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
767bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	mask = 0;
768bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
769bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen		mask |= dispc_mgr_get_vsync_irq(i);
770dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
77134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
77234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mask |= dispc_mgr_get_framedone_irq(i);
77334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
774dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
775dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	WARN_ON(r);
776dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
777d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	dss_data.irq_enabled = false;
778dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen}
779dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
7807609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinenstatic void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
78158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
782c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct omap_overlay *ovl;
783af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
784c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
7857609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
7867609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	mp = get_mgr_priv(mgr);
7870b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	mp->shadow_info_dirty = false;
7887609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
7897609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
7907609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		op = get_ovl_priv(ovl);
7910b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		op->shadow_info_dirty = false;
7927609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		op->shadow_extra_info_dirty = false;
7937609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	}
7947609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen}
7957609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
7967609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinenstatic void dss_apply_irq_handler(void *data, u32 mask)
7977609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen{
79858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
79975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	int i;
800f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	bool extra_updating;
80158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
802063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen	spin_lock(&data_lock);
80358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8047609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	/* clear busy, updating flags, shadow_dirty flags */
80543a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	for (i = 0; i < num_mgrs; i++) {
8067609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		struct omap_overlay_manager *mgr;
8077609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		struct mgr_priv_data *mp;
8087609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
80943a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
81043a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen		mp = get_mgr_priv(mgr);
81143a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8127609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		if (!mp->enabled)
81343a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen			continue;
81443a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8157609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		mp->updating = dispc_mgr_is_enabled(i);
81658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8177609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		if (!mgr_manual_update(mgr)) {
8187609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen			mp->busy = dispc_mgr_go_busy(i);
81943a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8207609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen			if (!mp->busy)
8217609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen				mgr_clear_shadow_dirty(mgr);
8227609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		} else {
8237609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen			if (!mp->updating)
8247609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen				mgr_clear_shadow_dirty(mgr);
8257609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		}
82658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
82758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
82875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
82958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
830f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	extra_updating = extra_info_update_ongoing();
831f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	if (!extra_updating)
832f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		complete_all(&extra_updated_completion);
833f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
83475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!need_isr())
83575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_unregister_vsync_isr();
83658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
837063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen	spin_unlock(&data_lock);
83858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
83958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8405738b633136a41923b4ba75e6b1a160d08539c99Tomi Valkeinenstatic void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
84158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
842c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
84358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
844c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	op = get_ovl_priv(ovl);
84558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
846c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	if (!op->user_info_dirty)
8475738b633136a41923b4ba75e6b1a160d08539c99Tomi Valkeinen		return;
84858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
849c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info_dirty = false;
8500b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	op->info_dirty = true;
851c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->info = op->user_info;
85258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
85358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
85458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
85558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
856af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
85758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
858af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	mp = get_mgr_priv(mgr);
85958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
860388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	if (!mp->user_info_dirty)
86158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return;
86258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
863388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info_dirty = false;
8640b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	mp->info_dirty = true;
865388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->info = mp->user_info;
86658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
86758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8686dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenint omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
86958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
8706dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	unsigned long flags;
8716dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct omap_overlay *ovl;
87239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
8736dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
8746dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
8756dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
8766dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
8776dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
87839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings_apply(mgr, mgr->device);
87939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
88039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
88139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to apply settings: illegal configuration.\n");
88239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return r;
88339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
88439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
8856dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	/* Configure overlays */
8866dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list)
8876dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		omap_dss_mgr_apply_ovl(ovl);
8886dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
8896dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	/* Configure manager */
8906dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	omap_dss_mgr_apply_mgr(mgr);
8916dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
8926dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dss_write_regs();
8936dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
8946dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
8956dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
896e70f98acaa84ec9ad55e544d0dc8b2d0a36bbecaTomi Valkeinen	return 0;
8976dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen}
8986dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
899841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinenstatic void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable)
900841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen{
901841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	struct ovl_priv_data *op;
902841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
903841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op = get_ovl_priv(ovl);
904841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
905841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	if (op->enabled == enable)
906841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen		return;
907841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
908841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op->enabled = enable;
909841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op->extra_info_dirty = true;
910841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen}
911841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
9126dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenstatic void dss_ovl_setup_fifo(struct omap_overlay *ovl)
9136dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen{
9146dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
91558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
91658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 size, burst_size;
9176dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	u32 fifo_low, fifo_high;
91858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
91958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
92058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
92158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	size = dispc_ovl_get_fifo_size(ovl->id);
92258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
92358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	burst_size = dispc_ovl_get_burst_size(ovl->id);
92458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
92558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	switch (dssdev->type) {
92658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DPI:
92758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DBI:
92858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_SDI:
92958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_VENC:
93058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_HDMI:
93158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		default_get_overlay_fifo_thresholds(ovl->id, size,
9326dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen				burst_size, &fifo_low, &fifo_high);
93358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		break;
93458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_DSI
93558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DSI:
93658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		dsi_get_overlay_fifo_thresholds(ovl->id, size,
9376dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen				burst_size, &fifo_low, &fifo_high);
93858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		break;
93958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#endif
94058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	default:
94158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		BUG();
94258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
9436dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9446dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	op->fifo_low = fifo_low;
9456dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	op->fifo_high = fifo_high;
9466dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	op->extra_info_dirty = true;
94758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
94858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9496dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenstatic void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
95058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
95107e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	struct omap_overlay *ovl;
9526dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct ovl_priv_data *op;
9536dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct mgr_priv_data *mp;
95458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9556dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	mp = get_mgr_priv(mgr);
95658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9576dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	if (!mp->enabled)
9586dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		return;
95958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9606dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
9616dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		op = get_ovl_priv(ovl);
96258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9636dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		if (!op->enabled)
9646dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen			continue;
96558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9666dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		dss_ovl_setup_fifo(ovl);
9676dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	}
96858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
96958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9702a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinenint dss_mgr_enable(struct omap_overlay_manager *mgr)
9717797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen{
972bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
973bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	unsigned long flags;
97439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
975bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
9765558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
9775558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
978e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (mp->enabled)
979e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto out;
980e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
981bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
982bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
983bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	mp->enabled = true;
98439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(mgr, mgr->device);
98539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	mp->enabled = false;
98639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
98739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to enable manager %d: check_settings failed\n",
98839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				mgr->id);
9892a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen		goto err;
99039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
99139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
99239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	mp->enabled = true;
993bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
9946dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dss_mgr_setup_fifos(mgr);
9956dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
99675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
99775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
99834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (!mgr_manual_update(mgr))
99934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mp->updating = true;
100034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
1001bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10025558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
100375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!mgr_manual_update(mgr))
100475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_mgr_enable(mgr->id, true);
100575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1006e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinenout:
10075558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
10082a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen
10092a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	return 0;
10102a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen
10112a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinenerr:
10122a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10132a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	mutex_unlock(&apply_lock);
10142a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	return r;
10157797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen}
10167797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen
10177797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinenvoid dss_mgr_disable(struct omap_overlay_manager *mgr)
10187797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen{
1019bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1020bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	unsigned long flags;
1021bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
10225558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
10235558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1024e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (!mp->enabled)
1025e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto out;
1026e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
10279a147a65de1ac89e506ef90413f41ebd96e03fd3Tomi Valkeinen	if (!mgr_manual_update(mgr))
10289a147a65de1ac89e506ef90413f41ebd96e03fd3Tomi Valkeinen		dispc_mgr_enable(mgr->id, false);
1029bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
1030bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1031bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
103234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp->updating = false;
1033bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	mp->enabled = false;
1034bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
1035bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10365558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1037e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinenout:
10385558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
10397797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen}
10407797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen
1041f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinenstatic int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
1042f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		const struct omap_overlay_manager_info *info)
1043f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen{
1044f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
1045f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		/*
1046f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * OMAP3 supports only graphics source transparency color key
1047f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * and alpha blending simultaneously. See TRM 15.4.2.4.2.2
1048f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * Alpha Mode.
1049f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 */
1050f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		if (info->partial_alpha_enabled && info->trans_enabled
1051f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			&& info->trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST) {
1052f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			DSSERR("check_manager: illegal transparency key\n");
1053f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			return -EINVAL;
1054f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		}
1055f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	}
1056f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1057f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	return 0;
1058f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen}
1059f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1060eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_set_info(struct omap_overlay_manager *mgr,
1061eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_overlay_manager_info *info)
1062eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1063388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1064e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1065f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	int r;
1066f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1067f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	r = dss_mgr_simple_check(mgr, info);
1068f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	if (r)
1069f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		return r;
1070e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1071e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1072e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1073388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info = *info;
1074388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info_dirty = true;
1075eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1076e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1077e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1078eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
1079eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1080eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1081eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenvoid dss_mgr_get_info(struct omap_overlay_manager *mgr,
1082eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_overlay_manager_info *info)
1083eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1084388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1085e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1086e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1087e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1088e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1089388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	*info = mp->user_info;
1090e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1091e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1092eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1093eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1094eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_set_device(struct omap_overlay_manager *mgr,
1095eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_dss_device *dssdev)
1096eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1097eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	int r;
1098eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
10995558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
11005558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1101eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if (dssdev->manager) {
1102eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("display '%s' already has a manager '%s'\n",
1103eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen			       dssdev->name, dssdev->manager->name);
11045558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11055558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1106eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1107eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1108eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if ((mgr->supported_displays & dssdev->type) == 0) {
1109eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("display '%s' does not support manager '%s'\n",
1110eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen			       dssdev->name, mgr->name);
11115558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11125558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1113eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1114eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1115eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	dssdev->manager = mgr;
1116eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device = dssdev;
1117eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
11185558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11195558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1120eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
11215558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
11225558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11235558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1124eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1125eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1126eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_unset_device(struct omap_overlay_manager *mgr)
1127eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
11285558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
11295558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
11305558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
11315558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1132eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if (!mgr->device) {
1133eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("failed to unset display, display not set.\n");
11345558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11355558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1136eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1137eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1138eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	/*
1139eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 * Don't allow currently enabled displays to have the overlay manager
1140eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 * pulled out from underneath them
1141eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 */
11425558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
11435558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11445558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
11455558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	}
1146eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1147eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device->manager = NULL;
1148eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device = NULL;
1149eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
11505558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11515558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1152eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
11535558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
11545558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11555558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1156eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1157eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1158eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1159fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinenstatic int dss_ovl_simple_check(struct omap_overlay *ovl,
1160fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		const struct omap_overlay_info *info)
1161fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen{
1162fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (info->paddr == 0) {
1163fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: paddr cannot be 0\n");
1164fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1165fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1166fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1167fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
1168fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		if (info->out_width != 0 && info->width != info->out_width) {
1169fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			DSSERR("check_overlay: overlay %d doesn't support "
1170fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen					"scaling\n", ovl->id);
1171fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			return -EINVAL;
1172fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		}
1173fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1174fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		if (info->out_height != 0 && info->height != info->out_height) {
1175fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			DSSERR("check_overlay: overlay %d doesn't support "
1176fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen					"scaling\n", ovl->id);
1177fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			return -EINVAL;
1178fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		}
1179fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1180fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1181fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if ((ovl->supported_modes & info->color_mode) == 0) {
1182fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: overlay %d doesn't support mode %d\n",
1183fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen				ovl->id, info->color_mode);
1184fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1185fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1186fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1187fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (info->zorder >= omap_dss_get_num_overlays()) {
1188fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: zorder %d too high\n", info->zorder);
1189fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1190fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1191fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1192fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	return 0;
1193fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen}
1194eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1195f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_set_info(struct omap_overlay *ovl,
1196f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_info *info)
1197f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1198c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1199e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1200fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	int r;
1201fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1202fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	r = dss_ovl_simple_check(ovl, info);
1203fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (r)
1204fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return r;
1205e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1206e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1207e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1208c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info = *info;
1209c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info_dirty = true;
1210f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1211e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1212e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1213f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
1214f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1215f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1216f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenvoid dss_ovl_get_info(struct omap_overlay *ovl,
1217f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_info *info)
1218f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1219c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1220e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1221e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1222e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1223e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1224c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	*info = op->user_info;
1225e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1226e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1227f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1228f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1229f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_set_manager(struct omap_overlay *ovl,
1230f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_manager *mgr)
1231f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1232aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1233aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
12345558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
12355558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1236f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (!mgr)
1237f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		return -EINVAL;
1238f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
12395558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
12405558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1241f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (ovl->manager) {
1242f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay '%s' already has a manager '%s'\n",
1243f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen				ovl->name, ovl->manager->name);
12445558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
12455558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1246f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1247f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1248aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1249aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1250aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (op->enabled) {
1251aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
1252f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay has to be disabled to change the manager\n");
12535558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
12545558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1255f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1256f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
12575d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->channel = mgr->id;
12585d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->extra_info_dirty = true;
12595d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen
1260f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	ovl->manager = mgr;
1261f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	list_add_tail(&ovl->list, &mgr->overlays);
1262f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1263aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1264aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1265f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	/* XXX: When there is an overlay on a DSI manual update display, and
1266f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * the overlay is first disabled, then moved to tv, and enabled, we
1267f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * seem to get SYNC_LOST_DIGIT error.
1268f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 *
1269f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * Waiting doesn't seem to help, but updating the manual update display
1270f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * after disabling the overlay seems to fix this. This hints that the
1271f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * overlay is perhaps somehow tied to the LCD output until the output
1272f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * is updated.
1273f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 *
1274f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * Userspace workaround for this is to update the LCD after disabling
1275f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * the overlay, but before moving the overlay to TV.
1276f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 */
1277f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
12785558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
12795558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1280f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
12815558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
12825558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
12835558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1284f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1285f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1286f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_unset_manager(struct omap_overlay *ovl)
1287f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1288aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1289aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
12905558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
12915558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
12925558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
12935558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1294f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (!ovl->manager) {
1295f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("failed to detach overlay: manager not set\n");
12965558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
12975558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1298f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1299f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1300aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1301aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1302aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (op->enabled) {
1303aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
1304f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay has to be disabled to unset the manager\n");
13055558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
13065558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1307f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1308f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
13095d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->channel = -1;
13105d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen
1311f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	ovl->manager = NULL;
1312f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	list_del(&ovl->list);
1313f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1314aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1315aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1316aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1317aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1318aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return 0;
1319aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenerr:
1320aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1321aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return r;
1322aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1323aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1324aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenbool dss_ovl_is_enabled(struct omap_overlay *ovl)
1325aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1326aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1327aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1328aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	bool e;
1329aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1330aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1331aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1332aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	e = op->enabled;
1333aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1334aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1335aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1336aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return e;
1337aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1338aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1339aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenint dss_ovl_enable(struct omap_overlay *ovl)
1340aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1341aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1342aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1343aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	int r;
1344aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1345aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_lock(&apply_lock);
1346aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1347e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (op->enabled) {
1348e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		r = 0;
134939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err1;
1350e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	}
1351e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
1352aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (ovl->manager == NULL || ovl->manager->device == NULL) {
1353aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		r = -EINVAL;
135439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err1;
1355aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
1356aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1357aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1358aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
135939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	op->enabled = true;
136039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(ovl->manager, ovl->manager->device);
136139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	op->enabled = false;
136239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
136339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to enable overlay %d: check_settings failed\n",
136439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				ovl->id);
136539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err2;
136639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
136739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
1368841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	dss_apply_ovl_enable(ovl, true);
1369aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
13706dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dss_ovl_setup_fifo(ovl);
13716dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
137275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
137375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1374aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1375aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1376aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1377aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1378aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return 0;
137939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenerr2:
138039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
138139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenerr1:
1382aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1383aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return r;
1384aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1385aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1386aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenint dss_ovl_disable(struct omap_overlay *ovl)
1387aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1388aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1389aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1390aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	int r;
1391aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1392aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_lock(&apply_lock);
1393aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1394e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (!op->enabled) {
1395e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		r = 0;
1396e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto err;
1397e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	}
1398e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
1399aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (ovl->manager == NULL || ovl->manager->device == NULL) {
1400aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		r = -EINVAL;
1401aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		goto err;
1402aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
1403aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1404aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1405aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1406841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	dss_apply_ovl_enable(ovl, false);
1407aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
140875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
140975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1410aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1411aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
14125558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
14135558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1414f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
1415aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
14165558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
14175558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
14185558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1419f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1420f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1421