apply.c revision 04576d415e01aa08752bf3884db9862cfbba9115
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;
7582153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen
7682153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	/*
7782153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	 * True if overlay is to be enabled. Used to check and calculate configs
7882153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	 * for the overlay before it is enabled in the HW.
7982153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	 */
8082153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	bool enabling;
8158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen};
8258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
83af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinenstruct mgr_priv_data {
84388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen
85388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	bool user_info_dirty;
86388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	struct omap_overlay_manager_info user_info;
87388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen
880b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	bool info_dirty;
8958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_manager_info info;
9058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
910b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	bool shadow_info_dirty;
920b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen
9343a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	/* If true, GO bit is up and shadow registers cannot be written.
9443a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	 * Never true for manual update displays */
9543a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	bool busy;
9643a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
9734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	/* If true, dispc output is enabled */
9834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	bool updating;
9934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
100bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	/* If true, a display is enabled using this manager */
101bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	bool enabled;
10258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen};
10358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic struct {
105c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
106af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
10758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool irq_enabled;
109d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen} dss_data;
11058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
111d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen/* protects dss_data */
112063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinenstatic spinlock_t data_lock;
1135558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen/* lock for blocking functions */
1145558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenstatic DEFINE_MUTEX(apply_lock);
115f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinenstatic DECLARE_COMPLETION(extra_updated_completion);
116063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen
11775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic void dss_register_vsync_isr(void);
11875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
119c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinenstatic struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
120c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen{
121d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	return &dss_data.ovl_priv_data_array[ovl->id];
122c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen}
123c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen
124af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinenstatic struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
125af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen{
126d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	return &dss_data.mgr_priv_data_array[mgr->id];
127af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen}
128af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen
12958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenvoid dss_apply_init(void)
13058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
131c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	const int num_ovls = dss_feat_get_num_ovls();
132c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	int i;
133c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
134063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen	spin_lock_init(&data_lock);
135c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
136c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	for (i = 0; i < num_ovls; ++i) {
137c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		struct ovl_priv_data *op;
138c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
139c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		op = &dss_data.ovl_priv_data_array[i];
140c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
141c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		op->info.global_alpha = 255;
142c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
143c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		switch (i) {
144c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		case 0:
145c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			op->info.zorder = 0;
146c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			break;
147c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		case 1:
148c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			op->info.zorder =
149c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen				dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
150c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			break;
151c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		case 2:
152c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			op->info.zorder =
153c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen				dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
154c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			break;
155c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		case 3:
156c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			op->info.zorder =
157c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen				dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
158c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen			break;
159c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		}
160c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen
161c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen		op->user_info = op->info;
162c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	}
16358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
16458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
16558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic bool ovl_manual_update(struct omap_overlay *ovl)
16658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
16758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
16858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
16958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
17058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic bool mgr_manual_update(struct omap_overlay_manager *mgr)
17158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
17258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
17358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
17458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
17539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen/* Check if overlay parameters are compatible with display */
17639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_ovl_check(struct omap_overlay *ovl,
17739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_info *info, struct omap_dss_device *dssdev)
17839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
17939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	u16 outw, outh;
18039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	u16 dw, dh;
18139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
18239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (dssdev == NULL)
18339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return 0;
18439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
18539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	dssdev->driver->get_resolution(dssdev, &dw, &dh);
18639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
18739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
18839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		outw = info->width;
18939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		outh = info->height;
19039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	} else {
19139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (info->out_width == 0)
19239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			outw = info->width;
19339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		else
19439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			outw = info->out_width;
19539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
19639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (info->out_height == 0)
19739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			outh = info->height;
19839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		else
19939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			outh = info->out_height;
20039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
20139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
20239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (dw < info->pos_x + outw) {
20339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("overlay %d horizontally not inside the display area "
20439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				"(%d + %d >= %d)\n",
20539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				ovl->id, info->pos_x, outw, dw);
20639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return -EINVAL;
20739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
20839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
20939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (dh < info->pos_y + outh) {
21039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("overlay %d vertically not inside the display area "
21139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				"(%d + %d >= %d)\n",
21239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				ovl->id, info->pos_y, outh, dh);
21339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return -EINVAL;
21439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
21539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
21639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return 0;
21739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
21839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
21939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_mgr_check_zorder(struct omap_overlay_manager *mgr,
22039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_info **overlay_infos)
22139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
22239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay *ovl1, *ovl2;
22339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct ovl_priv_data *op1, *op2;
22439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay_info *info1, *info2;
22539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
22639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	list_for_each_entry(ovl1, &mgr->overlays, list) {
22739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		op1 = get_ovl_priv(ovl1);
22839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		info1 = overlay_infos[ovl1->id];
22939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
23039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (info1 == NULL)
23139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			continue;
23239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
23339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		list_for_each_entry(ovl2, &mgr->overlays, list) {
23439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			if (ovl1 == ovl2)
23539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				continue;
23639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
23739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			op2 = get_ovl_priv(ovl2);
23839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			info2 = overlay_infos[ovl2->id];
23939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
24039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			if (info2 == NULL)
24139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				continue;
24239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
24339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			if (info1->zorder == info2->zorder) {
24439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				DSSERR("overlays %d and %d have the same "
24539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen						"zorder %d\n",
24639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen					ovl1->id, ovl2->id, info1->zorder);
24739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				return -EINVAL;
24839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			}
24939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		}
25039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
25139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
25239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return 0;
25339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
25439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
25539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_mgr_check(struct omap_overlay_manager *mgr,
25639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_dss_device *dssdev,
25739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_manager_info *info,
25839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_info **overlay_infos)
25939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
26039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay *ovl;
26139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
26239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
26339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) {
26439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		r = dss_mgr_check_zorder(mgr, overlay_infos);
26539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (r)
26639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			return r;
26739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
26839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
26939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
27039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_overlay_info *oi;
27139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		int r;
27239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
27339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		oi = overlay_infos[ovl->id];
27439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
27539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (oi == NULL)
27639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			continue;
27739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
27839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		r = dss_ovl_check(ovl, oi, dssdev);
27939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (r)
28039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			return r;
28139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
28239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
28339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return 0;
28439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
28539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_check_settings_low(struct omap_overlay_manager *mgr,
28639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_dss_device *dssdev, bool applying)
28739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
28839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay_info *oi;
28939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay_manager_info *mi;
29039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay *ovl;
29139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct omap_overlay_info *ois[MAX_DSS_OVERLAYS];
29239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct ovl_priv_data *op;
29339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	struct mgr_priv_data *mp;
29439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
29539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	mp = get_mgr_priv(mgr);
29639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
29739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (applying && mp->user_info_dirty)
29839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		mi = &mp->user_info;
29939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	else
30039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		mi = &mp->info;
30139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
30239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	/* collect the infos to be tested into the array */
30339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
30439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		op = get_ovl_priv(ovl);
30539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
30682153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen		if (!op->enabled && !op->enabling)
30739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			oi = NULL;
30839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		else if (applying && op->user_info_dirty)
30939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			oi = &op->user_info;
31039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		else
31139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			oi = &op->info;
31239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
31339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		ois[ovl->id] = oi;
31439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
31539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
31639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return dss_mgr_check(mgr, dssdev, mi, ois);
31739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
31839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
31939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen/*
32039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen * check manager and overlay settings using overlay_info from data->info
32139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen */
32239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_check_settings(struct omap_overlay_manager *mgr,
32339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_dss_device *dssdev)
32439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
32539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return dss_check_settings_low(mgr, dssdev, false);
32639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
32739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
32839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen/*
32939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen * check manager and overlay settings using overlay_info from ovl->info if
33039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen * dirty and from data->info otherwise
33139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen */
33239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenstatic int dss_check_settings_apply(struct omap_overlay_manager *mgr,
33339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		struct omap_dss_device *dssdev)
33439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen{
33539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	return dss_check_settings_low(mgr, dssdev, true);
33639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen}
33739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
33875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic bool need_isr(void)
33975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen{
34075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
34175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	int i;
34275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
34375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
34475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct omap_overlay_manager *mgr;
34575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct mgr_priv_data *mp;
34675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct omap_overlay *ovl;
34775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
34875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
34975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		mp = get_mgr_priv(mgr);
35075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
35175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		if (!mp->enabled)
35275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen			continue;
35375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
35434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		if (mgr_manual_update(mgr)) {
35534861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			/* to catch FRAMEDONE */
35634861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			if (mp->updating)
35734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				return true;
35834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		} else {
35934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			/* to catch GO bit going down */
36034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			if (mp->busy)
36134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				return true;
36275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
36334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			/* to write new values to registers */
3640b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen			if (mp->info_dirty)
36534861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				return true;
36675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
3679f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen			/* to set GO bit */
3689f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen			if (mp->shadow_info_dirty)
3699f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				return true;
3709f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
37134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			list_for_each_entry(ovl, &mgr->overlays, list) {
37234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				struct ovl_priv_data *op;
37375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
37434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				op = get_ovl_priv(ovl);
37575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
3769f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				/*
3779f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				 * NOTE: we check extra_info flags even for
3789f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				 * disabled overlays, as extra_infos need to be
3799f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				 * always written.
3809f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				 */
3819f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
3829f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				/* to write new values to registers */
3839f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				if (op->extra_info_dirty)
3849f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen					return true;
3859f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
3869f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				/* to set GO bit */
3879f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				if (op->shadow_extra_info_dirty)
3889f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen					return true;
3899f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
39034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				if (!op->enabled)
39134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen					continue;
39275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
39334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen				/* to write new values to registers */
3949f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				if (op->info_dirty)
3959f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen					return true;
3969f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen
3979f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				/* to set GO bit */
3989f808956d3cd07c8dc69e213931b19bad56344fbTomi Valkeinen				if (op->shadow_info_dirty)
39934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen					return true;
40034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen			}
40175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		}
40275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
40375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
40475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	return false;
40575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
40675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
40775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic bool need_go(struct omap_overlay_manager *mgr)
40875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen{
40975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct omap_overlay *ovl;
41075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct mgr_priv_data *mp;
41175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct ovl_priv_data *op;
41275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
41375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	mp = get_mgr_priv(mgr);
41475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
4150b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (mp->shadow_info_dirty)
41675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return true;
41775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
41875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
41975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		op = get_ovl_priv(ovl);
4200b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		if (op->shadow_info_dirty || op->shadow_extra_info_dirty)
42175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen			return true;
42275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
42375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
42475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	return false;
42575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
42675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
427f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen/* returns true if an extra_info field is currently being updated */
428f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinenstatic bool extra_info_update_ongoing(void)
429f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen{
430f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	const int num_ovls = omap_dss_get_num_overlays();
431f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct ovl_priv_data *op;
432f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct omap_overlay *ovl;
433f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	struct mgr_priv_data *mp;
434f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	int i;
435f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
436f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	for (i = 0; i < num_ovls; ++i) {
437f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		ovl = omap_dss_get_overlay(i);
438f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		op = get_ovl_priv(ovl);
439f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
440f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		mp = get_mgr_priv(ovl->manager);
441f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
442f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		if (!mp->enabled)
443f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
444f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
445153b6e7357778267e6914f2370a059e79a751371Tomi Valkeinen		if (!mp->updating)
446f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen			continue;
447f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
448153b6e7357778267e6914f2370a059e79a751371Tomi Valkeinen		if (op->extra_info_dirty || op->shadow_extra_info_dirty)
449153b6e7357778267e6914f2370a059e79a751371Tomi Valkeinen			return true;
450f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	}
451f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
452f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	return false;
453f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen}
454f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
455f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen/* wait until no extra_info updates are pending */
456f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinenstatic void wait_pending_extra_info_updates(void)
457f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen{
458f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	bool updating;
459f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	unsigned long flags;
460f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	unsigned long t;
461f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
462f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
463f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
464f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	updating = extra_info_update_ongoing();
465f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
466f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	if (!updating) {
467f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
468f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		return;
469f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	}
470f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
471f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	init_completion(&extra_updated_completion);
472f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
473f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
474f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
475f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	t = msecs_to_jiffies(500);
476f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	wait_for_completion_timeout(&extra_updated_completion, t);
477f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
478f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	updating = extra_info_update_ongoing();
479f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
480f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	WARN_ON(updating);
481f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen}
482f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
48358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
48458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
48558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long timeout = msecs_to_jiffies(500);
486af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
48758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq;
48858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
48958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
49058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev = mgr->device;
49158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
49358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
49458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (mgr_manual_update(mgr))
49658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
49758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
498bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	irq = dispc_mgr_get_vsync_irq(mgr->id);
49958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
500af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	mp = get_mgr_priv(mgr);
50158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	i = 0;
50258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	while (1) {
50358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		unsigned long flags;
50458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		bool shadow_dirty, dirty;
50558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
506063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_lock_irqsave(&data_lock, flags);
5070b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		dirty = mp->info_dirty;
5080b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		shadow_dirty = mp->shadow_info_dirty;
509063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
51058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!dirty && !shadow_dirty) {
51258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
51358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
51458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
51558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* 4 iterations is the worst case:
51758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
51858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 2 - first VSYNC, dirty = true
51958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 3 - dirty = false, shadow_dirty = true
52058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 4 - shadow_dirty = false */
52158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (i++ == 3) {
52258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("mgr(%d)->wait_for_go() not finishing\n",
52358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen					mgr->id);
52458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
52558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
52658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
52758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
52858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
52958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r == -ERESTARTSYS)
53058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
53158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r) {
53358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
53458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
53558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
53658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
53758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
53958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
54058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
54158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
54258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
54358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long timeout = msecs_to_jiffies(500);
544c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
54558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
54658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq;
54758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
54858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
54958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!ovl->manager)
55158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
55258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
55458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
55658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
55758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (ovl_manual_update(ovl))
55958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
56058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
561bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
56258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
563c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	op = get_ovl_priv(ovl);
56458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	i = 0;
56558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	while (1) {
56658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		unsigned long flags;
56758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		bool shadow_dirty, dirty;
56858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
569063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_lock_irqsave(&data_lock, flags);
5700b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		dirty = op->info_dirty;
5710b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		shadow_dirty = op->shadow_info_dirty;
572063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
57358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
57458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!dirty && !shadow_dirty) {
57558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
57658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
57758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
57858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
57958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* 4 iterations is the worst case:
58058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
58158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 2 - first VSYNC, dirty = true
58258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 3 - dirty = false, shadow_dirty = true
58358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 4 - shadow_dirty = false */
58458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (i++ == 3) {
58558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("ovl(%d)->wait_for_go() not finishing\n",
58658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen					ovl->id);
58758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
58858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
58958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
59058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
59258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r == -ERESTARTSYS)
59358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
59458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r) {
59658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
59758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
59858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
59958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
60058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
60158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
60258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
60358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
60475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic void dss_ovl_write_regs(struct omap_overlay *ovl)
60558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
60675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
60758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_info *oi;
60858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool ilace, replication;
60934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	struct mgr_priv_data *mp;
61058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
61158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
612f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	DSSDBGF("%d", ovl->id);
61358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
6140b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (!op->enabled || !op->info_dirty)
61575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
61658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
61775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	oi = &op->info;
61858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
61958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	replication = dss_use_replication(ovl->manager->device, oi->color_mode);
62058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
62158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
62258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
623f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
62458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (r) {
62575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		/*
62675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 * We can't do much here, as this function can be called from
62775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 * vsync interrupt.
62875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		 */
629f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen		DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id);
63075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
63175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		/* This will leave fifo configurations in a nonoptimal state */
63275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		op->enabled = false;
63375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_ovl_enable(ovl->id, false);
63475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
63558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
63658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
63734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp = get_mgr_priv(ovl->manager);
63834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
6390b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	op->info_dirty = false;
64034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (mp->updating)
6410b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		op->shadow_info_dirty = true;
64258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
64358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
644aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenstatic void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
645aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
646aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
64734861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	struct mgr_priv_data *mp;
648aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
649aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	DSSDBGF("%d", ovl->id);
650aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
65175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!op->extra_info_dirty)
65275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
65375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
654aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	/* note: write also when op->enabled == false, so that the ovl gets
655aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	 * disabled */
656aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
657aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	dispc_ovl_enable(ovl->id, op->enabled);
6585d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	dispc_ovl_set_channel_out(ovl->id, op->channel);
6596dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
66075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
66134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp = get_mgr_priv(ovl->manager);
66234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
66375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	op->extra_info_dirty = false;
66434861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (mp->updating)
66534861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		op->shadow_extra_info_dirty = true;
666aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
667aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
668f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinenstatic void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
66958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
67075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
67175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	struct omap_overlay *ovl;
67258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
673f6a5e0871f22428a7c74c07ddd791197c5f5d38fTomi Valkeinen	DSSDBGF("%d", mgr->id);
67458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
67575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!mp->enabled)
67675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		return;
67758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
67875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	WARN_ON(mp->busy);
67958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
68058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* Commit overlay settings */
68175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
68275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_ovl_write_regs(ovl);
683aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		dss_ovl_write_regs_extra(ovl);
684aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
685aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
6860b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	if (mp->info_dirty) {
68775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_mgr_setup(mgr->id, &mp->info);
68858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
6890b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		mp->info_dirty = false;
69034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		if (mp->updating)
6910b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen			mp->shadow_info_dirty = true;
69258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
69375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen}
69475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
69575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinenstatic void dss_write_regs(void)
69675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen{
69775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	const int num_mgrs = omap_dss_get_num_overlay_managers();
69875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	int i;
69958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
70058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
70175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct omap_overlay_manager *mgr;
70275c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		struct mgr_priv_data *mp;
70339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		int r;
70475c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
705af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
706af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen		mp = get_mgr_priv(mgr);
70758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
70875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
70958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
71058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
71139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		r = dss_check_settings(mgr, mgr->device);
71239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		if (r) {
71339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			DSSERR("cannot write registers for manager %s: "
71439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen					"illegal configuration\n", mgr->name);
71539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen			continue;
71639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		}
71739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
71875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_mgr_write_regs(mgr);
7193ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	}
7203ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen}
72175c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
7223ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinenstatic void dss_set_go_bits(void)
7233ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen{
7243ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	const int num_mgrs = omap_dss_get_num_overlay_managers();
7253ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	int i;
72658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7273ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
7283ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		struct omap_overlay_manager *mgr;
7293ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		struct mgr_priv_data *mp;
73058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7313ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
7323ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		mp = get_mgr_priv(mgr);
7333ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7343ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
7353ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen			continue;
7363ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7373ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		if (!need_go(mgr))
7383ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen			continue;
7393ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7403ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		mp->busy = true;
7413ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7423ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		if (!dss_data.irq_enabled && need_isr())
7433ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen			dss_register_vsync_isr();
7443ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
7453ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen		dispc_mgr_go(mgr->id);
74675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	}
7473ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen
74858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
74958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
75058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenvoid dss_mgr_start_update(struct omap_overlay_manager *mgr)
75158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
752af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
753e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
75439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
755e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
756e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
75758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
75834861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	WARN_ON(mp->updating);
75934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
76039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(mgr, mgr->device);
76139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
76239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("cannot start manual update: illegal configuration\n");
76339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
76439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return;
76539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
76639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
76775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_mgr_write_regs(mgr);
76858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
76934861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp->updating = true;
77058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
77134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (!dss_data.irq_enabled && need_isr())
77234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		dss_register_vsync_isr();
77358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7747797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen	dispc_mgr_enable(mgr->id, true);
775e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
776e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
77758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
77858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
779dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_apply_irq_handler(void *data, u32 mask);
780dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
781dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_register_vsync_isr(void)
782dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen{
783bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
784dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	u32 mask;
785bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	int r, i;
786dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
787bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	mask = 0;
788bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
789bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen		mask |= dispc_mgr_get_vsync_irq(i);
790dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
79134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
79234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mask |= dispc_mgr_get_framedone_irq(i);
79334861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
794dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
795dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	WARN_ON(r);
796dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
797d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	dss_data.irq_enabled = true;
798dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen}
799dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
800dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinenstatic void dss_unregister_vsync_isr(void)
801dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen{
802bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
803dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	u32 mask;
804bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	int r, i;
805dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
806bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	mask = 0;
807bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
808bc1a95181f7069920c13fcef0159ffa7d61160f1Tomi Valkeinen		mask |= dispc_mgr_get_vsync_irq(i);
809dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
81034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	for (i = 0; i < num_mgrs; ++i)
81134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mask |= dispc_mgr_get_framedone_irq(i);
81234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
813dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
814dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen	WARN_ON(r);
815dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
816d09c7aa8989caf44e8754e8aa81ce80217a0e98aTomi Valkeinen	dss_data.irq_enabled = false;
817dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen}
818dbce0160af31d2ea323656c201d8debf5af789bfTomi Valkeinen
8197609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinenstatic void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
82058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
821c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct omap_overlay *ovl;
822af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
823c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
8247609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
8257609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	mp = get_mgr_priv(mgr);
8260b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	mp->shadow_info_dirty = false;
8277609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
8287609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
8297609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		op = get_ovl_priv(ovl);
8300b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen		op->shadow_info_dirty = false;
8317609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		op->shadow_extra_info_dirty = false;
8327609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	}
8337609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen}
8347609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
8357609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinenstatic void dss_apply_irq_handler(void *data, u32 mask)
8367609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen{
83758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
83875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	int i;
839f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	bool extra_updating;
84058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
841063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen	spin_lock(&data_lock);
84258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8437609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen	/* clear busy, updating flags, shadow_dirty flags */
84443a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen	for (i = 0; i < num_mgrs; i++) {
8457609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		struct omap_overlay_manager *mgr;
8467609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		struct mgr_priv_data *mp;
8475b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen		bool was_updating;
8487609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen
84943a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
85043a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen		mp = get_mgr_priv(mgr);
85143a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8527609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		if (!mp->enabled)
85343a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen			continue;
85443a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8555b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen		was_updating = mp->updating;
8567609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		mp->updating = dispc_mgr_is_enabled(i);
85758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8587609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		if (!mgr_manual_update(mgr)) {
8595b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen			bool was_busy = mp->busy;
8607609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen			mp->busy = dispc_mgr_go_busy(i);
86143a972d96b6ea2b9e3d6b55b9724c9f61d802c68Tomi Valkeinen
8625b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen			if (was_busy && !mp->busy)
8637609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen				mgr_clear_shadow_dirty(mgr);
8647609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		} else {
8655b2141719aa8a14ebd242c60b4ce6a580276f7cdTomi Valkeinen			if (was_updating && !mp->updating)
8667609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen				mgr_clear_shadow_dirty(mgr);
8677609893c637b422eec88b57d204f02d8798cfc65Tomi Valkeinen		}
86858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
86958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
87075c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
8713ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
87258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
873f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	extra_updating = extra_info_update_ongoing();
874f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen	if (!extra_updating)
875f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen		complete_all(&extra_updated_completion);
876f1577ce18004337ec2f6f48109ca14cac10a0a4fTomi Valkeinen
87775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!need_isr())
87875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dss_unregister_vsync_isr();
87958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
880063fd701abba3b58c36b6043d5feacf0fdc76cbdTomi Valkeinen	spin_unlock(&data_lock);
88158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
88258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8835738b633136a41923b4ba75e6b1a160d08539c99Tomi Valkeinenstatic void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
88458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
885c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	struct ovl_priv_data *op;
88658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
887c10c6f042b6a5940c522a334a716d57b40f7dec9Tomi Valkeinen	op = get_ovl_priv(ovl);
88858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
889c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	if (!op->user_info_dirty)
8905738b633136a41923b4ba75e6b1a160d08539c99Tomi Valkeinen		return;
89158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
892c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info_dirty = false;
8930b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	op->info_dirty = true;
894c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->info = op->user_info;
89558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
89658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
89758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
89858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
899af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	struct mgr_priv_data *mp;
90058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
901af3d64b2c674bc6246bb04654b484f34287fbbc3Tomi Valkeinen	mp = get_mgr_priv(mgr);
90258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
903388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	if (!mp->user_info_dirty)
90458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return;
90558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
906388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info_dirty = false;
9070b53f17971700f673492e2e91b5069893e5f2d0bTomi Valkeinen	mp->info_dirty = true;
908388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->info = mp->user_info;
90958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
91058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9116dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenint omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
91258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
9136dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	unsigned long flags;
9146dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct omap_overlay *ovl;
91539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
9166dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9176dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
9186dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9196dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
9206dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
92139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings_apply(mgr, mgr->device);
92239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
92339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
92439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to apply settings: illegal configuration.\n");
92539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		return r;
92639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
92739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
9286dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	/* Configure overlays */
9296dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list)
9306dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		omap_dss_mgr_apply_ovl(ovl);
9316dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9326dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	/* Configure manager */
9336dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	omap_dss_mgr_apply_mgr(mgr);
9346dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9356dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	dss_write_regs();
9363ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
9376dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
9386dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
9396dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
940e70f98acaa84ec9ad55e544d0dc8b2d0a36bbecaTomi Valkeinen	return 0;
9416dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen}
9426dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
943841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinenstatic void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable)
944841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen{
945841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	struct ovl_priv_data *op;
946841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
947841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op = get_ovl_priv(ovl);
948841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
949841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	if (op->enabled == enable)
950841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen		return;
951841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
952841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op->enabled = enable;
953841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	op->extra_info_dirty = true;
954841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen}
955841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen
95604576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinenstatic void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
95704576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen		u32 fifo_low, u32 fifo_high)
95804576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen{
95904576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
96004576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen
96104576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen	if (op->fifo_low == fifo_low && op->fifo_high == fifo_high)
96204576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen		return;
96304576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen
96404576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen	op->fifo_low = fifo_low;
96504576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen	op->fifo_high = fifo_high;
96604576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen	op->extra_info_dirty = true;
96704576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen}
96804576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen
9696dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenstatic void dss_ovl_setup_fifo(struct omap_overlay *ovl)
9706dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen{
9716dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
97258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
97358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 size, burst_size;
9746dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	u32 fifo_low, fifo_high;
97558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
97675ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen	if (!op->enabled && !op->enabling)
97775ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen		return;
97875ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen
97958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
98058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
98158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	size = dispc_ovl_get_fifo_size(ovl->id);
98258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
98358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	burst_size = dispc_ovl_get_burst_size(ovl->id);
98458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
98558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	switch (dssdev->type) {
98658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DPI:
98758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DBI:
98858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_SDI:
98958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_VENC:
99058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_HDMI:
99158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		default_get_overlay_fifo_thresholds(ovl->id, size,
9926dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen				burst_size, &fifo_low, &fifo_high);
99358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		break;
99458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_DSI
99558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DSI:
99658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		dsi_get_overlay_fifo_thresholds(ovl->id, size,
9976dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen				burst_size, &fifo_low, &fifo_high);
99858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		break;
99958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#endif
100058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	default:
100158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		BUG();
100258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
10036dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
100404576d415e01aa08752bf3884db9862cfbba9115Tomi Valkeinen	dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
100558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
100658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10076dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinenstatic void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
100858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
100907e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	struct omap_overlay *ovl;
10106dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	struct mgr_priv_data *mp;
101158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10126dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	mp = get_mgr_priv(mgr);
101358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10146dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	if (!mp->enabled)
10156dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen		return;
101658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
101775ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list)
101875ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen		dss_ovl_setup_fifo(ovl);
101975ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen}
102058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
102175ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinenstatic void dss_setup_fifos(void)
102275ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen{
102375ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen	const int num_mgrs = omap_dss_get_num_overlay_managers();
102475ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen	struct omap_overlay_manager *mgr;
102575ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen	int i;
102658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
102775ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
102875ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen		mgr = omap_dss_get_overlay_manager(i);
102975ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen		dss_mgr_setup_fifos(mgr);
10306dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen	}
103158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
103258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10332a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinenint dss_mgr_enable(struct omap_overlay_manager *mgr)
10347797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen{
1035bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1036bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	unsigned long flags;
103739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	int r;
1038bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
10395558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
10405558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1041e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (mp->enabled)
1042e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto out;
1043e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
1044bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1045bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
1046bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	mp->enabled = true;
1047a6b24f83601530f69ee36ac48527336e3c79bea8Tomi Valkeinen
104839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(mgr, mgr->device);
104939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
105039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to enable manager %d: check_settings failed\n",
105139518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				mgr->id);
10522a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen		goto err;
105339518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
105439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
105575ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen	dss_setup_fifos();
10566dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
105775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
10583ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
105975c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
106034861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	if (!mgr_manual_update(mgr))
106134861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen		mp->updating = true;
106234861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen
1063bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10645558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
106575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	if (!mgr_manual_update(mgr))
106675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen		dispc_mgr_enable(mgr->id, true);
106775c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1068e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinenout:
10695558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
10702a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen
10712a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	return 0;
10722a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen
10732a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinenerr:
1074a6b24f83601530f69ee36ac48527336e3c79bea8Tomi Valkeinen	mp->enabled = false;
10752a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10762a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	mutex_unlock(&apply_lock);
10772a4ee7ee685f3bf996461ed0d148857ce85a00e2Tomi Valkeinen	return r;
10787797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen}
10797797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen
10807797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinenvoid dss_mgr_disable(struct omap_overlay_manager *mgr)
10817797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen{
1082bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1083bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	unsigned long flags;
1084bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
10855558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
10865558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1087e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (!mp->enabled)
1088e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto out;
1089e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
10909a147a65de1ac89e506ef90413f41ebd96e03fd3Tomi Valkeinen	if (!mgr_manual_update(mgr))
10919a147a65de1ac89e506ef90413f41ebd96e03fd3Tomi Valkeinen		dispc_mgr_enable(mgr->id, false);
1092bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
1093bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1094bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
109534861378a54e3fcac0eb87317ded2554b087494eTomi Valkeinen	mp->updating = false;
1096bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	mp->enabled = false;
1097bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen
1098bf213523fe9708572a0b0a9149f7196a4f058564Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
10995558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1100e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinenout:
11015558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11027797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen}
11037797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen
1104f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinenstatic int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
1105f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		const struct omap_overlay_manager_info *info)
1106f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen{
1107f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
1108f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		/*
1109f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * OMAP3 supports only graphics source transparency color key
1110f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * and alpha blending simultaneously. See TRM 15.4.2.4.2.2
1111f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 * Alpha Mode.
1112f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		 */
1113f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		if (info->partial_alpha_enabled && info->trans_enabled
1114f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			&& info->trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST) {
1115f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			DSSERR("check_manager: illegal transparency key\n");
1116f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen			return -EINVAL;
1117f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		}
1118f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	}
1119f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1120f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	return 0;
1121f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen}
1122f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1123eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_set_info(struct omap_overlay_manager *mgr,
1124eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_overlay_manager_info *info)
1125eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1126388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1127e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1128f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	int r;
1129f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen
1130f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	r = dss_mgr_simple_check(mgr, info);
1131f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen	if (r)
1132f17d04fbbb201c05700359e94e2747c210f99852Tomi Valkeinen		return r;
1133e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1134e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1135e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1136388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info = *info;
1137388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	mp->user_info_dirty = true;
1138eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1139e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1140e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1141eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
1142eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1143eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1144eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenvoid dss_mgr_get_info(struct omap_overlay_manager *mgr,
1145eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_overlay_manager_info *info)
1146eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1147388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	struct mgr_priv_data *mp = get_mgr_priv(mgr);
1148e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1149e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1150e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1151e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1152388c4c6cbb335e69fe23c8d18bd4b0e8dd66901bTomi Valkeinen	*info = mp->user_info;
1153e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1154e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1155eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1156eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1157eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_set_device(struct omap_overlay_manager *mgr,
1158eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		struct omap_dss_device *dssdev)
1159eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
1160eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	int r;
1161eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
11625558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
11635558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1164eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if (dssdev->manager) {
1165eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("display '%s' already has a manager '%s'\n",
1166eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen			       dssdev->name, dssdev->manager->name);
11675558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11685558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1169eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1170eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1171eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if ((mgr->supported_displays & dssdev->type) == 0) {
1172eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("display '%s' does not support manager '%s'\n",
1173eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen			       dssdev->name, mgr->name);
11745558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11755558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1176eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1177eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1178eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	dssdev->manager = mgr;
1179eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device = dssdev;
1180eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
11815558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11825558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1183eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
11845558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
11855558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
11865558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1187eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1188eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1189eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinenint dss_mgr_unset_device(struct omap_overlay_manager *mgr)
1190eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen{
11915558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
11925558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
11935558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
11945558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1195eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	if (!mgr->device) {
1196eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen		DSSERR("failed to unset display, display not set.\n");
11975558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
11985558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1199eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	}
1200eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1201eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	/*
1202eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 * Don't allow currently enabled displays to have the overlay manager
1203eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 * pulled out from underneath them
1204eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	 */
12055558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
12065558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
12075558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
12085558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	}
1209eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1210eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device->manager = NULL;
1211eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	mgr->device = NULL;
1212eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
12135558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
12145558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1215eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen	return 0;
12165558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
12175558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
12185558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1219eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen}
1220eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1221eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1222fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinenstatic int dss_ovl_simple_check(struct omap_overlay *ovl,
1223fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		const struct omap_overlay_info *info)
1224fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen{
1225fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (info->paddr == 0) {
1226fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: paddr cannot be 0\n");
1227fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1228fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1229fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1230fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
1231fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		if (info->out_width != 0 && info->width != info->out_width) {
1232fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			DSSERR("check_overlay: overlay %d doesn't support "
1233fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen					"scaling\n", ovl->id);
1234fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			return -EINVAL;
1235fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		}
1236fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1237fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		if (info->out_height != 0 && info->height != info->out_height) {
1238fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			DSSERR("check_overlay: overlay %d doesn't support "
1239fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen					"scaling\n", ovl->id);
1240fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen			return -EINVAL;
1241fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		}
1242fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1243fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1244fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if ((ovl->supported_modes & info->color_mode) == 0) {
1245fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: overlay %d doesn't support mode %d\n",
1246fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen				ovl->id, info->color_mode);
1247fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1248fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1249fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1250fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (info->zorder >= omap_dss_get_num_overlays()) {
1251fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		DSSERR("check_overlay: zorder %d too high\n", info->zorder);
1252fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return -EINVAL;
1253fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	}
1254fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1255fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	return 0;
1256fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen}
1257eb70d739adf2266e744a784a1272f1c92a257b81Tomi Valkeinen
1258f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_set_info(struct omap_overlay *ovl,
1259f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_info *info)
1260f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1261c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1262e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1263fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	int r;
1264fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen
1265fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	r = dss_ovl_simple_check(ovl, info);
1266fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen	if (r)
1267fcc764dca80ead39b7391ff2c67a6b78de16d7a9Tomi Valkeinen		return r;
1268e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1269e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1270e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1271c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info = *info;
1272c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	op->user_info_dirty = true;
1273f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1274e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1275e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1276f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
1277f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1278f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1279f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenvoid dss_ovl_get_info(struct omap_overlay *ovl,
1280f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_info *info)
1281f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1282c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1283e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	unsigned long flags;
1284e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1285e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1286e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1287c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen	*info = op->user_info;
1288e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen
1289e0a2aa5b3d1a26969ba906447c816d44c018969dTomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1290f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1291f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1292f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_set_manager(struct omap_overlay *ovl,
1293f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		struct omap_overlay_manager *mgr)
1294f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1295aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1296aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
12975558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
12985558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1299f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (!mgr)
1300f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		return -EINVAL;
1301f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
13025558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
13035558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1304f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (ovl->manager) {
1305f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay '%s' already has a manager '%s'\n",
1306f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen				ovl->name, ovl->manager->name);
13075558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
13085558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1309f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1310f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1311aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1312aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1313aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (op->enabled) {
1314aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
1315f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay has to be disabled to change the manager\n");
13165558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
13175558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1318f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1319f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
13205d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->channel = mgr->id;
13215d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->extra_info_dirty = true;
13225d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen
1323f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	ovl->manager = mgr;
1324f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	list_add_tail(&ovl->list, &mgr->overlays);
1325f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1326aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1327aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1328f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	/* XXX: When there is an overlay on a DSI manual update display, and
1329f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * the overlay is first disabled, then moved to tv, and enabled, we
1330f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * seem to get SYNC_LOST_DIGIT error.
1331f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 *
1332f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * Waiting doesn't seem to help, but updating the manual update display
1333f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * after disabling the overlay seems to fix this. This hints that the
1334f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * overlay is perhaps somehow tied to the LCD output until the output
1335f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * is updated.
1336f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 *
1337f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * Userspace workaround for this is to update the LCD after disabling
1338f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 * the overlay, but before moving the overlay to TV.
1339f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	 */
1340f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
13415558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
13425558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1343f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
13445558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
13455558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
13465558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1347f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1348f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1349f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinenint dss_ovl_unset_manager(struct omap_overlay *ovl)
1350f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen{
1351aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1352aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
13535558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	int r;
13545558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
13555558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_lock(&apply_lock);
13565558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1357f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	if (!ovl->manager) {
1358f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("failed to detach overlay: manager not set\n");
13595558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
13605558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1361f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1362f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1363aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1364aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1365aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (op->enabled) {
1366aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		spin_unlock_irqrestore(&data_lock, flags);
1367f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen		DSSERR("overlay has to be disabled to unset the manager\n");
13685558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		r = -EINVAL;
13695558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen		goto err;
1370f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	}
1371f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
13725d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen	op->channel = -1;
13735d5a97a6fbf98f82ae50c837eba3ebcfea0902f8Tomi Valkeinen
1374f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	ovl->manager = NULL;
1375f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	list_del(&ovl->list);
1376f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1377aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1378aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1379aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1380aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1381aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return 0;
1382aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenerr:
1383aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1384aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return r;
1385aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1386aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1387aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenbool dss_ovl_is_enabled(struct omap_overlay *ovl)
1388aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1389aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1390aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1391aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	bool e;
1392aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1393aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1394aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1395aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	e = op->enabled;
1396aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1397aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1398aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1399aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return e;
1400aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1401aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1402aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenint dss_ovl_enable(struct omap_overlay *ovl)
1403aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1404aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1405aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1406aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	int r;
1407aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1408aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_lock(&apply_lock);
1409aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1410e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (op->enabled) {
1411e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		r = 0;
141239518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err1;
1413e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	}
1414e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
1415aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (ovl->manager == NULL || ovl->manager->device == NULL) {
1416aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		r = -EINVAL;
141739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err1;
1418aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
1419aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1420aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1421aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
142282153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	op->enabling = true;
142382153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen
142439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	r = dss_check_settings(ovl->manager, ovl->manager->device);
142539518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	if (r) {
142639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		DSSERR("failed to enable overlay %d: check_settings failed\n",
142739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen				ovl->id);
142839518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen		goto err2;
142939518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	}
143039518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen
143175ae118a0028810f93a746c25f4bb018fb044323Tomi Valkeinen	dss_setup_fifos();
14326dc802e2901d33e02efad3c90bb2034fd20c79e7Tomi Valkeinen
143382153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	op->enabling = false;
143482153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	dss_apply_ovl_enable(ovl, true);
143582153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen
143675c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
14373ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
143875c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1439aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1440aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1441aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1442aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1443aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return 0;
144439518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenerr2:
144582153eda076ee4df434bb1008f24e46590f76dfcTomi Valkeinen	op->enabling = false;
144639518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
144739518356ccd6e439abae24e1a24d84dcd12ff207Tomi Valkeinenerr1:
1448aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_unlock(&apply_lock);
1449aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	return r;
1450aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen}
1451aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1452aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinenint dss_ovl_disable(struct omap_overlay *ovl)
1453aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen{
1454aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	struct ovl_priv_data *op = get_ovl_priv(ovl);
1455aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	unsigned long flags;
1456aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	int r;
1457aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1458aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	mutex_lock(&apply_lock);
1459aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1460e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	if (!op->enabled) {
1461e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		r = 0;
1462e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen		goto err;
1463e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen	}
1464e4f7ad702ef271d2b0c03e9904b05f9bcbf0808bTomi Valkeinen
1465aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	if (ovl->manager == NULL || ovl->manager->device == NULL) {
1466aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		r = -EINVAL;
1467aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen		goto err;
1468aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	}
1469aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1470aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_lock_irqsave(&data_lock, flags);
1471aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
1472841c09c7975c67fe7741564d98265de28a5764d0Tomi Valkeinen	dss_apply_ovl_enable(ovl, false);
147375c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen	dss_write_regs();
14743ab15b2aa70369e0360f12e35e47bca1a269138bTomi Valkeinen	dss_set_go_bits();
147575c949653fdf77a17753ffb8462a3c458c476271Tomi Valkeinen
1476aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen	spin_unlock_irqrestore(&data_lock, flags);
1477aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
14785558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
14795558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen
1480f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen	return 0;
1481aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen
14825558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinenerr:
14835558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	mutex_unlock(&apply_lock);
14845558db3fdd52e3928d5eaabe363e1576dc5fe473Tomi Valkeinen	return r;
1485f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen}
1486f77b30700e5c0a6b5220b3a964bf6c40d5e71416Tomi Valkeinen
1487