apply.c revision 3ab15b2aa70369e0360f12e35e47bca1a269138b
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
3619f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen			/* to set GO bit */
3629f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen			if (mp->shadow_info_dirty)
3639f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				return true;
3649f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
36534861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			list_for_each_entry(ovl, &mgr->overlays, list) {
36634861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				struct ovl_priv_data *op;
36775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
36834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				op = get_ovl_priv(ovl);
36975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
3709f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				/*
3719f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				 * NOTE: we check extra_info flags even for
3729f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				 * disabled overlays, as extra_infos need to be
3739f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				 * always written.
3749f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				 */
3759f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
3769f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				/* to write new values to registers */
3779f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				if (op->extra_info_dirty)
3789f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen					return true;
3799f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
3809f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				/* to set GO bit */
3819f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				if (op->shadow_extra_info_dirty)
3829f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen					return true;
3839f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
38434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				if (!op->enabled)
38534861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen					continue;
38675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
38734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				/* to write new values to registers */
3889f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				if (op->info_dirty)
3899f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen					return true;
3909f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
3919f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				/* to set GO bit */
3929f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				if (op->shadow_info_dirty)
39334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen					return true;
39434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			}
39575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		}
39675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
39775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
39875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	return false;
39975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
40075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
40175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic bool need_go(struct omap_overlay_manager *mgr)
40275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen{
40375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct omap_overlay *ovl;
40475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct mgr_priv_data *mp;
40575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct ovl_priv_data *op;
40675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
40775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	mp = get_mgr_priv(mgr);
40875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
4090b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (mp->shadow_info_dirty)
41075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return true;
41175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
41275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
41375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		op = get_ovl_priv(ovl);
4140b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		if (op->shadow_info_dirty || op->shadow_extra_info_dirty)
41575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen			return true;
41675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
41775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
41875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	return false;
41975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
42075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
421f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen/* returns true if an extra_info field is currently being updated */
422f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinenstatic bool extra_info_update_ongoing(void)
423f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen{
424f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	const int num_ovls = omap_dss_get_num_overlays();
425f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct ovl_priv_data *op;
426f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct omap_overlay *ovl;
427f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct mgr_priv_data *mp;
428f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	int i;
429f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	bool eid;
430f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
431f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	for (i = 0; i < num_ovls; ++i) {
432f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		ovl = omap_dss_get_overlay(i);
433f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		op = get_ovl_priv(ovl);
434f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
435f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		mp = get_mgr_priv(ovl->manager);
436f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
437f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		if (!mp->enabled)
438f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
439f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
440f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		eid = op->extra_info_dirty || op->shadow_extra_info_dirty;
441f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
442f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		if (!eid)
443f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
444f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
445f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		if (ovl_manual_update(ovl) && !mp->updating)
446f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
447f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
448f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		return true;
449f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	}
450f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
451f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	return false;
452f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen}
453f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
454f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen/* wait until no extra_info updates are pending */
455f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinenstatic void wait_pending_extra_info_updates(void)
456f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen{
457f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	bool updating;
458f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	unsigned long flags;
459f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	unsigned long t;
460f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
461f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
462f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
463f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	updating = extra_info_update_ongoing();
464f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
465f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	if (!updating) {
466f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
467f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		return;
468f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	}
469f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
470f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	init_completion(&extra_updated_completion);
471f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
472f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
473f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
474f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	t = msecs_to_jiffies(500);
475f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	wait_for_completion_timeout(&extra_updated_completion, t);
476f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
477f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	updating = extra_info_update_ongoing();
478f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
479f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	WARN_ON(updating);
480f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen}
481f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
48258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
48358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
48458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long timeout = msecs_to_jiffies(500);
485af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
48658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq;
48758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
48858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
48958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev = mgr->device;
49058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
49258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
49358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (mgr_manual_update(mgr))
49558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
49658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
497bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	irq = dispc_mgr_get_vsync_irq(mgr->id);
49858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
499af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	mp = get_mgr_priv(mgr);
50058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	i = 0;
50158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	while (1) {
50258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		unsigned long flags;
50358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		bool shadow_dirty, dirty;
50458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
505063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_lock_irqsave(&data_lock, flags);
5060b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		dirty = mp->info_dirty;
5070b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		shadow_dirty = mp->shadow_info_dirty;
508063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
50958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!dirty && !shadow_dirty) {
51158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
51258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
51358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
51458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* 4 iterations is the worst case:
51658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
51758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 2 - first VSYNC, dirty = true
51858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 3 - dirty = false, shadow_dirty = true
51958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 4 - shadow_dirty = false */
52058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (i++ == 3) {
52158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("mgr(%d)->wait_for_go() not finishing\n",
52258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen					mgr->id);
52358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
52458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
52558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
52658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
52758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
52858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r == -ERESTARTSYS)
52958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
53058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r) {
53258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
53358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
53458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
53558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
53658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
53858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
53958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
54058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
54158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
54258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long timeout = msecs_to_jiffies(500);
543c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
54458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
54558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq;
54658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
54758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
54858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
54958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!ovl->manager)
55058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
55158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
55358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
55558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
55658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (ovl_manual_update(ovl))
55858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
55958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
560bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
56158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
562c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	op = get_ovl_priv(ovl);
56358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	i = 0;
56458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	while (1) {
56558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		unsigned long flags;
56658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		bool shadow_dirty, dirty;
56758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
568063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_lock_irqsave(&data_lock, flags);
5690b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		dirty = op->info_dirty;
5700b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		shadow_dirty = op->shadow_info_dirty;
571063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
57258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
57358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!dirty && !shadow_dirty) {
57458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
57558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
57658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
57758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
57858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* 4 iterations is the worst case:
57958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
58058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 2 - first VSYNC, dirty = true
58158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 3 - dirty = false, shadow_dirty = true
58258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 4 - shadow_dirty = false */
58358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (i++ == 3) {
58458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("ovl(%d)->wait_for_go() not finishing\n",
58558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen					ovl->id);
58658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
58758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
58858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
58958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
59158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r == -ERESTARTSYS)
59258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
59358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r) {
59558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
59658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
59758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
59858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
59958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
60058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
60158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
60258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
60375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic void dss_ovl_write_regs(struct omap_overlay *ovl)
60458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
60575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
60658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_info *oi;
60758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool ilace, replication;
60834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	struct mgr_priv_data *mp;
60958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
61058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
611f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	DSSDBGF("%d", ovl->id);
61258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
6130b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (!op->enabled || !op->info_dirty)
61475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
61558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
61675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	oi = &op->info;
61758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
61858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	replication = dss_use_replication(ovl->manager->device, oi->color_mode);
61958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
62058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
62158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
622f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
62358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (r) {
62475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		/*
62575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 * We can't do much here, as this function can be called from
62675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 * vsync interrupt.
62775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 */
628f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen		DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id);
62975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
63075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		/* This will leave fifo configurations in a nonoptimal state */
63175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		op->enabled = false;
63275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_ovl_enable(ovl->id, false);
63375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
63458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
63558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
63634861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp = get_mgr_priv(ovl->manager);
63734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
6380b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	op->info_dirty = false;
63934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (mp->updating)
6400b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		op->shadow_info_dirty = true;
64158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
64258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
643aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenstatic void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
644aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
645aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
64634861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	struct mgr_priv_data *mp;
647aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
648aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	DSSDBGF("%d", ovl->id);
649aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
65075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!op->extra_info_dirty)
65175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
65275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
653aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	/* note: write also when op->enabled == false, so that the ovl gets
654aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	 * disabled */
655aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
656aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	dispc_ovl_enable(ovl->id, op->enabled);
6575d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	dispc_ovl_set_channel_out(ovl->id, op->channel);
6586dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
65975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
66034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp = get_mgr_priv(ovl->manager);
66134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
66275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	op->extra_info_dirty = false;
66334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (mp->updating)
66434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		op->shadow_extra_info_dirty = true;
665aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
666aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
667f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinenstatic void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
66858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
66975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
67075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct omap_overlay *ovl;
67158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
672f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	DSSDBGF("%d", mgr->id);
67358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
67475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!mp->enabled)
67575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
67658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
67775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	WARN_ON(mp->busy);
67858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
67958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* Commit overlay settings */
68075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
68175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_ovl_write_regs(ovl);
682aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		dss_ovl_write_regs_extra(ovl);
683aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
684aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
6850b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (mp->info_dirty) {
68675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_mgr_setup(mgr->id, &mp->info);
68758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
6880b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		mp->info_dirty = false;
68934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		if (mp->updating)
6900b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen			mp->shadow_info_dirty = true;
69158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
69275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
69375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
69475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic void dss_write_regs(void)
69575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen{
69675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	const int num_mgrs = omap_dss_get_num_overlay_managers();
69775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	int i;
69858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
69958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
70075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct omap_overlay_manager *mgr;
70175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct mgr_priv_data *mp;
70239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		int r;
70375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
704af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
705af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen		mp = get_mgr_priv(mgr);
70658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
70775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
70858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
70958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
71039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		r = dss_check_settings(mgr, mgr->device);
71139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (r) {
71239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			DSSERR("cannot write registers for manager %s: "
71339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen					"illegal configuration\n", mgr->name);
71439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			continue;
71539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		}
71639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
71775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_mgr_write_regs(mgr);
7183ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	}
7193ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen}
72075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
7213ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinenstatic void dss_set_go_bits(void)
7223ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen{
7233ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	const int num_mgrs = omap_dss_get_num_overlay_managers();
7243ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	int i;
72558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7263ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
7273ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		struct omap_overlay_manager *mgr;
7283ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		struct mgr_priv_data *mp;
72958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7303ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
7313ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		mp = get_mgr_priv(mgr);
7323ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7333ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
7343ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen			continue;
7353ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7363ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		if (!need_go(mgr))
7373ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen			continue;
7383ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7393ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		mp->busy = true;
7403ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7413ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		if (!dss_data.irq_enabled && need_isr())
7423ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen			dss_register_vsync_isr();
7433ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7443ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		dispc_mgr_go(mgr->id);
74575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
7463ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
74758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
74858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
74958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenvoid dss_mgr_start_update(struct omap_overlay_manager *mgr)
75058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
751af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
752e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
75339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
754e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
755e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
75658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
75734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	WARN_ON(mp->updating);
75834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
75939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(mgr, mgr->device);
76039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
76139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("cannot start manual update: illegal configuration\n");
76239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
76339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return;
76439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
76539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
76675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_mgr_write_regs(mgr);
76758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
76834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp->updating = true;
76958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
77034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (!dss_data.irq_enabled && need_isr())
77134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		dss_register_vsync_isr();
77258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7737797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen	dispc_mgr_enable(mgr->id, true);
774e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
775e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
77658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
77758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
778dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_apply_irq_handler(void *data, u32 mask);
779dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
780dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_register_vsync_isr(void)
781dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen{
782bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
783dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	u32 mask;
784bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	int r, i;
785dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
786bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	mask = 0;
787bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
788bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen		mask |= dispc_mgr_get_vsync_irq(i);
789dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
79034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
79134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mask |= dispc_mgr_get_framedone_irq(i);
79234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
793dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
794dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	WARN_ON(r);
795dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
796d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	dss_data.irq_enabled = true;
797dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen}
798dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
799dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_unregister_vsync_isr(void)
800dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen{
801bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
802dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	u32 mask;
803bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	int r, i;
804dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
805bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	mask = 0;
806bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
807bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen		mask |= dispc_mgr_get_vsync_irq(i);
808dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
80934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
81034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mask |= dispc_mgr_get_framedone_irq(i);
81134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
812dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
813dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	WARN_ON(r);
814dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
815d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	dss_data.irq_enabled = false;
816dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen}
817dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
8187609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinenstatic void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
81958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
820c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct omap_overlay *ovl;
821af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
822c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
8237609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
8247609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	mp = get_mgr_priv(mgr);
8250b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	mp->shadow_info_dirty = false;
8267609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
8277609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
8287609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		op = get_ovl_priv(ovl);
8290b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		op->shadow_info_dirty = false;
8307609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		op->shadow_extra_info_dirty = false;
8317609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	}
8327609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen}
8337609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
8347609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinenstatic void dss_apply_irq_handler(void *data, u32 mask)
8357609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen{
83658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
83775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	int i;
838f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	bool extra_updating;
83958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
840063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen	spin_lock(&data_lock);
84158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8427609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	/* clear busy, updating flags, shadow_dirty flags */
84343a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	for (i = 0; i < num_mgrs; i++) {
8447609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		struct omap_overlay_manager *mgr;
8457609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		struct mgr_priv_data *mp;
8465b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen		bool was_updating;
8477609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
84843a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
84943a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen		mp = get_mgr_priv(mgr);
85043a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8517609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		if (!mp->enabled)
85243a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen			continue;
85343a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8545b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen		was_updating = mp->updating;
8557609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		mp->updating = dispc_mgr_is_enabled(i);
85658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8577609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		if (!mgr_manual_update(mgr)) {
8585b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen			bool was_busy = mp->busy;
8597609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen			mp->busy = dispc_mgr_go_busy(i);
86043a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8615b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen			if (was_busy && !mp->busy)
8627609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen				mgr_clear_shadow_dirty(mgr);
8637609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		} else {
8645b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen			if (was_updating && !mp->updating)
8657609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen				mgr_clear_shadow_dirty(mgr);
8667609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		}
86758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
86858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
86975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
8703ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
87158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
872f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	extra_updating = extra_info_update_ongoing();
873f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	if (!extra_updating)
874f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		complete_all(&extra_updated_completion);
875f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
87675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!need_isr())
87775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_unregister_vsync_isr();
87858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
879063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen	spin_unlock(&data_lock);
88058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
88158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8825738b633136a41923b4ba75e6b1a160d08539c99Tomi Valkeinenstatic void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
88358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
884c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
88558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
886c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	op = get_ovl_priv(ovl);
88758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
888c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	if (!op->user_info_dirty)
8895738b633136a41923b4ba75e6b1a160d08539c99Tomi Valkeinen		return;
89058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
891c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info_dirty = false;
8920b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	op->info_dirty = true;
893c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->info = op->user_info;
89458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
89558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
89658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
89758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
898af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
89958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
900af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	mp = get_mgr_priv(mgr);
90158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
902388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	if (!mp->user_info_dirty)
90358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return;
90458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
905388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info_dirty = false;
9060b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	mp->info_dirty = true;
907388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->info = mp->user_info;
90858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
90958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9106dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenint omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
91158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
9126dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	unsigned long flags;
9136dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct omap_overlay *ovl;
91439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
9156dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9166dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
9176dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9186dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
9196dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
92039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings_apply(mgr, mgr->device);
92139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
92239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
92339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to apply settings: illegal configuration.\n");
92439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return r;
92539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
92639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
9276dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	/* Configure overlays */
9286dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list)
9296dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		omap_dss_mgr_apply_ovl(ovl);
9306dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9316dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	/* Configure manager */
9326dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	omap_dss_mgr_apply_mgr(mgr);
9336dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9346dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dss_write_regs();
9353ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
9366dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9376dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
9386dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
939e70f98acaa84ec9ad55e544d0dc8b2d0a36bbecaTomi Valkeinen	return 0;
9406dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen}
9416dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
942841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinenstatic void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable)
943841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen{
944841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	struct ovl_priv_data *op;
945841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
946841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op = get_ovl_priv(ovl);
947841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
948841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	if (op->enabled == enable)
949841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen		return;
950841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
951841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op->enabled = enable;
952841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op->extra_info_dirty = true;
953841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen}
954841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
9556dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenstatic void dss_ovl_setup_fifo(struct omap_overlay *ovl)
9566dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen{
9576dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
95858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
95958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 size, burst_size;
9606dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	u32 fifo_low, fifo_high;
96158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
96258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
96358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
96458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	size = dispc_ovl_get_fifo_size(ovl->id);
96558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
96658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	burst_size = dispc_ovl_get_burst_size(ovl->id);
96758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
96858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	switch (dssdev->type) {
96958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DPI:
97058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DBI:
97158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_SDI:
97258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_VENC:
97358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_HDMI:
97458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		default_get_overlay_fifo_thresholds(ovl->id, size,
9756dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen				burst_size, &fifo_low, &fifo_high);
97658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		break;
97758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_DSI
97858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DSI:
97958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		dsi_get_overlay_fifo_thresholds(ovl->id, size,
9806dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen				burst_size, &fifo_low, &fifo_high);
98158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		break;
98258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#endif
98358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	default:
98458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		BUG();
98558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
9866dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9876dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	op->fifo_low = fifo_low;
9886dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	op->fifo_high = fifo_high;
9896dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	op->extra_info_dirty = true;
99058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
99158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9926dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenstatic void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
99358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
99407e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	struct omap_overlay *ovl;
9956dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct ovl_priv_data *op;
9966dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct mgr_priv_data *mp;
99758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9986dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	mp = get_mgr_priv(mgr);
99958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10006dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	if (!mp->enabled)
10016dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		return;
100258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10036dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
10046dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		op = get_ovl_priv(ovl);
100558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10066dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		if (!op->enabled)
10076dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen			continue;
100858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10096dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		dss_ovl_setup_fifo(ovl);
10106dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	}
101158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
101258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10132a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinenint dss_mgr_enable(struct omap_overlay_manager *mgr)
10147797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen{
1015bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1016bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	unsigned long flags;
101739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
1018bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
10195558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
10205558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1021e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (mp->enabled)
1022e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto out;
1023e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
1024bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1025bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
1026bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	mp->enabled = true;
102739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(mgr, mgr->device);
102839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	mp->enabled = false;
102939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
103039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to enable manager %d: check_settings failed\n",
103139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				mgr->id);
10322a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen		goto err;
103339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
103439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
103539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	mp->enabled = true;
1036bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
10376dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dss_mgr_setup_fifos(mgr);
10386dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
103975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
10403ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
104175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
104234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (!mgr_manual_update(mgr))
104334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mp->updating = true;
104434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
1045bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10465558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
104775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!mgr_manual_update(mgr))
104875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_mgr_enable(mgr->id, true);
104975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1050e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinenout:
10515558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
10522a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen
10532a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	return 0;
10542a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen
10552a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinenerr:
10562a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10572a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	mutex_unlock(&apply_lock);
10582a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	return r;
10597797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen}
10607797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen
10617797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinenvoid dss_mgr_disable(struct omap_overlay_manager *mgr)
10627797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen{
1063bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1064bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	unsigned long flags;
1065bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
10665558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
10675558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1068e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (!mp->enabled)
1069e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto out;
1070e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
10719a147a65de1ac89e506ef90413f41ebd96e03fd3Tomi Valkeinen	if (!mgr_manual_update(mgr))
10729a147a65de1ac89e506ef90413f41ebd96e03fd3Tomi Valkeinen		dispc_mgr_enable(mgr->id, false);
1073bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
1074bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1075bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
107634861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp->updating = false;
1077bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	mp->enabled = false;
1078bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
1079bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10805558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1081e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinenout:
10825558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
10837797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen}
10847797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen
1085f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinenstatic int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
1086f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		const struct omap_overlay_manager_info *info)
1087f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen{
1088f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
1089f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		/*
1090f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * OMAP3 supports only graphics source transparency color key
1091f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * and alpha blending simultaneously. See TRM 15.4.2.4.2.2
1092f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * Alpha Mode.
1093f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 */
1094f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		if (info->partial_alpha_enabled && info->trans_enabled
1095f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			&& info->trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST) {
1096f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			DSSERR("check_manager: illegal transparency key\n");
1097f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			return -EINVAL;
1098f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		}
1099f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	}
1100f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1101f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	return 0;
1102f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen}
1103f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1104eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_set_info(struct omap_overlay_manager *mgr,
1105eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_overlay_manager_info *info)
1106eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1107388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1108e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1109f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	int r;
1110f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1111f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	r = dss_mgr_simple_check(mgr, info);
1112f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	if (r)
1113f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		return r;
1114e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1115e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1116e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1117388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info = *info;
1118388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info_dirty = true;
1119eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1120e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1121e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1122eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
1123eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1124eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1125eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenvoid dss_mgr_get_info(struct omap_overlay_manager *mgr,
1126eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_overlay_manager_info *info)
1127eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1128388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1129e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1130e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1131e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1132e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1133388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	*info = mp->user_info;
1134e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1135e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1136eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1137eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1138eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_set_device(struct omap_overlay_manager *mgr,
1139eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_dss_device *dssdev)
1140eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1141eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	int r;
1142eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
11435558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
11445558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1145eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if (dssdev->manager) {
1146eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("display '%s' already has a manager '%s'\n",
1147eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen			       dssdev->name, dssdev->manager->name);
11485558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11495558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1150eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1151eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1152eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if ((mgr->supported_displays & dssdev->type) == 0) {
1153eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("display '%s' does not support manager '%s'\n",
1154eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen			       dssdev->name, mgr->name);
11555558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11565558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1157eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1158eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1159eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	dssdev->manager = mgr;
1160eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device = dssdev;
1161eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
11625558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11635558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1164eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
11655558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
11665558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11675558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1168eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1169eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1170eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_unset_device(struct omap_overlay_manager *mgr)
1171eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
11725558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
11735558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
11745558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
11755558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1176eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if (!mgr->device) {
1177eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("failed to unset display, display not set.\n");
11785558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11795558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1180eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1181eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1182eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	/*
1183eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 * Don't allow currently enabled displays to have the overlay manager
1184eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 * pulled out from underneath them
1185eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 */
11865558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
11875558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11885558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
11895558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	}
1190eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1191eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device->manager = NULL;
1192eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device = NULL;
1193eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
11945558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11955558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1196eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
11975558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
11985558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11995558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1200eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1201eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1202eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1203fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinenstatic int dss_ovl_simple_check(struct omap_overlay *ovl,
1204fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		const struct omap_overlay_info *info)
1205fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen{
1206fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (info->paddr == 0) {
1207fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: paddr cannot be 0\n");
1208fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1209fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1210fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1211fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
1212fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		if (info->out_width != 0 && info->width != info->out_width) {
1213fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			DSSERR("check_overlay: overlay %d doesn't support "
1214fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen					"scaling\n", ovl->id);
1215fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			return -EINVAL;
1216fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		}
1217fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1218fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		if (info->out_height != 0 && info->height != info->out_height) {
1219fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			DSSERR("check_overlay: overlay %d doesn't support "
1220fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen					"scaling\n", ovl->id);
1221fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			return -EINVAL;
1222fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		}
1223fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1224fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1225fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if ((ovl->supported_modes & info->color_mode) == 0) {
1226fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: overlay %d doesn't support mode %d\n",
1227fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen				ovl->id, info->color_mode);
1228fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1229fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1230fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1231fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (info->zorder >= omap_dss_get_num_overlays()) {
1232fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: zorder %d too high\n", info->zorder);
1233fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1234fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1235fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1236fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	return 0;
1237fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen}
1238eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1239f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_set_info(struct omap_overlay *ovl,
1240f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_info *info)
1241f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1242c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1243e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1244fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	int r;
1245fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1246fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	r = dss_ovl_simple_check(ovl, info);
1247fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (r)
1248fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return r;
1249e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1250e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1251e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1252c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info = *info;
1253c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info_dirty = true;
1254f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1255e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1256e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1257f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
1258f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1259f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1260f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenvoid dss_ovl_get_info(struct omap_overlay *ovl,
1261f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_info *info)
1262f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1263c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1264e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1265e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1266e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1267e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1268c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	*info = op->user_info;
1269e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1270e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1271f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1272f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1273f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_set_manager(struct omap_overlay *ovl,
1274f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_manager *mgr)
1275f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1276aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1277aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
12785558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
12795558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1280f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (!mgr)
1281f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		return -EINVAL;
1282f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
12835558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
12845558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1285f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (ovl->manager) {
1286f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay '%s' already has a manager '%s'\n",
1287f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen				ovl->name, ovl->manager->name);
12885558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
12895558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1290f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1291f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1292aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1293aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1294aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (op->enabled) {
1295aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
1296f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay has to be disabled to change the manager\n");
12975558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
12985558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1299f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1300f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
13015d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->channel = mgr->id;
13025d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->extra_info_dirty = true;
13035d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen
1304f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	ovl->manager = mgr;
1305f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	list_add_tail(&ovl->list, &mgr->overlays);
1306f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1307aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1308aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1309f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	/* XXX: When there is an overlay on a DSI manual update display, and
1310f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * the overlay is first disabled, then moved to tv, and enabled, we
1311f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * seem to get SYNC_LOST_DIGIT error.
1312f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 *
1313f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * Waiting doesn't seem to help, but updating the manual update display
1314f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * after disabling the overlay seems to fix this. This hints that the
1315f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * overlay is perhaps somehow tied to the LCD output until the output
1316f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * is updated.
1317f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 *
1318f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * Userspace workaround for this is to update the LCD after disabling
1319f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * the overlay, but before moving the overlay to TV.
1320f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 */
1321f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
13225558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
13235558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1324f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
13255558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
13265558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
13275558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1328f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1329f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1330f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_unset_manager(struct omap_overlay *ovl)
1331f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1332aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1333aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
13345558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
13355558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
13365558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
13375558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1338f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (!ovl->manager) {
1339f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("failed to detach overlay: manager not set\n");
13405558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
13415558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1342f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1343f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1344aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1345aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1346aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (op->enabled) {
1347aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
1348f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay has to be disabled to unset the manager\n");
13495558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
13505558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1351f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1352f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
13535d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->channel = -1;
13545d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen
1355f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	ovl->manager = NULL;
1356f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	list_del(&ovl->list);
1357f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1358aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1359aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1360aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1361aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1362aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return 0;
1363aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenerr:
1364aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1365aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return r;
1366aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1367aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1368aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenbool dss_ovl_is_enabled(struct omap_overlay *ovl)
1369aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1370aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1371aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1372aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	bool e;
1373aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1374aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1375aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1376aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	e = op->enabled;
1377aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1378aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1379aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1380aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return e;
1381aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1382aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1383aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenint dss_ovl_enable(struct omap_overlay *ovl)
1384aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1385aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1386aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1387aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	int r;
1388aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1389aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_lock(&apply_lock);
1390aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1391e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (op->enabled) {
1392e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		r = 0;
139339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err1;
1394e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	}
1395e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
1396aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (ovl->manager == NULL || ovl->manager->device == NULL) {
1397aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		r = -EINVAL;
139839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err1;
1399aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
1400aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1401aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1402aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
140339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	op->enabled = true;
140439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(ovl->manager, ovl->manager->device);
140539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	op->enabled = false;
140639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
140739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to enable overlay %d: check_settings failed\n",
140839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				ovl->id);
140939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err2;
141039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
141139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
1412841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	dss_apply_ovl_enable(ovl, true);
1413aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
14146dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dss_ovl_setup_fifo(ovl);
14156dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
141675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
14173ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
141875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1419aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1420aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1421aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1422aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1423aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return 0;
142439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenerr2:
142539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
142639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenerr1:
1427aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1428aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return r;
1429aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1430aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1431aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenint dss_ovl_disable(struct omap_overlay *ovl)
1432aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1433aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1434aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1435aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	int r;
1436aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1437aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_lock(&apply_lock);
1438aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1439e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (!op->enabled) {
1440e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		r = 0;
1441e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto err;
1442e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	}
1443e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
1444aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (ovl->manager == NULL || ovl->manager->device == NULL) {
1445aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		r = -EINVAL;
1446aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		goto err;
1447aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
1448aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1449aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1450aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1451841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	dss_apply_ovl_enable(ovl, false);
145275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
14533ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
145475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1455aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1456aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
14575558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
14585558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1459f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
1460aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
14615558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
14625558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
14635558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1464f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1465f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1466