apply.c revision 07e327c9c18b382656bf455051759be8182627ae
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 *
3458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
3558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * |overlay/manager_info|
3658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
3758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
3858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *        apply()
3958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
4058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
4158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * |     dss_cache      |
4258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
4358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
4458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *      configure()
4558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
4658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
4758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * |  shadow registers  |
4858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
4958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
5058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * VFP or lcd/digit_enable
5158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen *          v
5258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
5358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * |      registers     |
5458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * +--------------------+
5558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen */
5658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
5758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstruct overlay_cache_data {
5858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* If true, cache changed, but not written to shadow registers. Set
5958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	 * in apply(), cleared when registers written. */
6058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool dirty;
6158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* If true, shadow registers contain changed values not yet in real
6258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	 * registers. Set when writing to shadow registers, cleared at
6358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	 * VSYNC/EVSYNC */
6458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool shadow_dirty;
6558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
6658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool enabled;
6758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
6858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_info info;
6958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	enum omap_channel channel;
7158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 fifo_low;
7358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 fifo_high;
7458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen};
7558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
7658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstruct manager_cache_data {
7758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* If true, cache changed, but not written to shadow registers. Set
7858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	 * in apply(), cleared when registers written. */
7958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool dirty;
8058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* If true, shadow registers contain changed values not yet in real
8158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	 * registers. Set when writing to shadow registers, cleared at
8258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	 * VSYNC/EVSYNC */
8358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool shadow_dirty;
8458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_manager_info info;
8658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
8758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool manual_update;
8858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool do_manual_update;
8958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen};
9058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic struct {
9258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	spinlock_t lock;
9358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct overlay_cache_data overlay_cache[MAX_DSS_OVERLAYS];
9458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct manager_cache_data manager_cache[MAX_DSS_MANAGERS];
9558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool irq_enabled;
9758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen} dss_cache;
9858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
9958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenvoid dss_apply_init(void)
10058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
10158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	spin_lock_init(&dss_cache.lock);
10258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
10358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic bool ovl_manual_update(struct omap_overlay *ovl)
10558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
10658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
10758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
10858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
10958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic bool mgr_manual_update(struct omap_overlay_manager *mgr)
11058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
11158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
11258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
11358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
11458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic int overlay_enabled(struct omap_overlay *ovl)
11558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
11658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return ovl->info.enabled && ovl->manager && ovl->manager->device;
11758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
11858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
11958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
12058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
12158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long timeout = msecs_to_jiffies(500);
12258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct manager_cache_data *mc;
12358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq;
12458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
12558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
12658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev = mgr->device;
12758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
12858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
12958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
13058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
13158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (mgr_manual_update(mgr))
13258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
13358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
13458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
13558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
13658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
13758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	} else {
13858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
13958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
14058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
14158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
14258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mc = &dss_cache.manager_cache[mgr->id];
14358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	i = 0;
14458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	while (1) {
14558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		unsigned long flags;
14658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		bool shadow_dirty, dirty;
14758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
14858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		spin_lock_irqsave(&dss_cache.lock, flags);
14958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		dirty = mc->dirty;
15058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		shadow_dirty = mc->shadow_dirty;
15158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		spin_unlock_irqrestore(&dss_cache.lock, flags);
15258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
15358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!dirty && !shadow_dirty) {
15458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
15558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
15658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
15758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
15858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* 4 iterations is the worst case:
15958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
16058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 2 - first VSYNC, dirty = true
16158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 3 - dirty = false, shadow_dirty = true
16258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 4 - shadow_dirty = false */
16358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (i++ == 3) {
16458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("mgr(%d)->wait_for_go() not finishing\n",
16558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen					mgr->id);
16658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
16758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
16858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
16958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
17058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
17158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r == -ERESTARTSYS)
17258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
17358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
17458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r) {
17558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
17658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
17758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
17858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
17958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
18058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
18158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
18258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
18358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
18458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
18558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long timeout = msecs_to_jiffies(500);
18658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct overlay_cache_data *oc;
18758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
18858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq;
18958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
19058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
19158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
19258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!ovl->manager)
19358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
19458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
19558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
19658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
19758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
19858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
19958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
20058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (ovl_manual_update(ovl))
20158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
20258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
20358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
20458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
20558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
20658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	} else {
20758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
20858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
20958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
21058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
21158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	oc = &dss_cache.overlay_cache[ovl->id];
21258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	i = 0;
21358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	while (1) {
21458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		unsigned long flags;
21558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		bool shadow_dirty, dirty;
21658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
21758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		spin_lock_irqsave(&dss_cache.lock, flags);
21858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		dirty = oc->dirty;
21958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		shadow_dirty = oc->shadow_dirty;
22058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		spin_unlock_irqrestore(&dss_cache.lock, flags);
22158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
22258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!dirty && !shadow_dirty) {
22358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
22458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
22558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
22658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
22758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* 4 iterations is the worst case:
22858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 1 - initial iteration, dirty = true (between VFP and VSYNC)
22958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 2 - first VSYNC, dirty = true
23058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 3 - dirty = false, shadow_dirty = true
23158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * 4 - shadow_dirty = false */
23258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (i++ == 3) {
23358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("ovl(%d)->wait_for_go() not finishing\n",
23458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen					ovl->id);
23558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			r = 0;
23658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
23758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
23858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
23958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
24058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r == -ERESTARTSYS)
24158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
24258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
24358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r) {
24458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
24558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			break;
24658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
24758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
24858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
24958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
25058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
25158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
25258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic int configure_overlay(enum omap_plane plane)
25358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
25458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay *ovl;
25558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct overlay_cache_data *c;
25658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_info *oi;
25758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool ilace, replication;
25858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
25958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
26058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	DSSDBGF("%d", plane);
26158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
26258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	c = &dss_cache.overlay_cache[plane];
26358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	oi = &c->info;
26458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
26558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!c->enabled) {
26658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		dispc_ovl_enable(plane, 0);
26758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
26858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
26958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
27058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	ovl = omap_dss_get_overlay(plane);
27158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
27258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	replication = dss_use_replication(ovl->manager->device, oi->color_mode);
27358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
27458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
27558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
27658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dispc_ovl_set_channel_out(plane, c->channel);
27758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
27858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	r = dispc_ovl_setup(plane, oi, ilace, replication);
27958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (r) {
28058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* this shouldn't happen */
28158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
28258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		dispc_ovl_enable(plane, 0);
28358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return r;
28458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
28558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
28658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dispc_ovl_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
28758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
28858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dispc_ovl_enable(plane, 1);
28958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
29058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return 0;
29158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
29258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
29358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic void configure_manager(enum omap_channel channel)
29458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
29558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_overlay_manager_info *mi;
29658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
29758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	DSSDBGF("%d", channel);
29858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
29958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* picking info from the cache */
30058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mi = &dss_cache.manager_cache[channel].info;
30158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
30258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dispc_mgr_setup(channel, mi);
30358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
30458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
30558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen/* configure_dispc() tries to write values from cache to shadow registers.
30658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * It writes only to those managers/overlays that are not busy.
30758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * returns 0 if everything could be written to shadow registers.
30858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen * returns 1 if not everything could be written to shadow registers. */
30958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic int configure_dispc(void)
31058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
31158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct overlay_cache_data *oc;
31258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct manager_cache_data *mc;
31358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	const int num_ovls = dss_feat_get_num_ovls();
31458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
31558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i;
31658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int r;
31758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool mgr_busy[MAX_DSS_MANAGERS];
31858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool mgr_go[MAX_DSS_MANAGERS];
31958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool busy;
32058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
32158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	r = 0;
32258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	busy = false;
32358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
32458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; i++) {
32558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mgr_busy[i] = dispc_mgr_go_busy(i);
32658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mgr_go[i] = false;
32758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
32858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
32958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* Commit overlay settings */
33058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_ovls; ++i) {
33158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		oc = &dss_cache.overlay_cache[i];
33258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mc = &dss_cache.manager_cache[oc->channel];
33358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
33458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!oc->dirty)
33558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
33658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
33758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (mc->manual_update && !mc->do_manual_update)
33858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
33958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
34058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (mgr_busy[oc->channel]) {
34158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			busy = true;
34258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
34358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
34458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
34558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = configure_overlay(i);
34658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (r)
34758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DSSERR("configure_overlay %d failed\n", i);
34858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
34958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		oc->dirty = false;
35058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		oc->shadow_dirty = true;
35158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mgr_go[oc->channel] = true;
35258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
35358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
35458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* Commit manager settings */
35558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
35658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mc = &dss_cache.manager_cache[i];
35758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
35858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!mc->dirty)
35958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
36058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
36158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (mc->manual_update && !mc->do_manual_update)
36258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
36358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
36458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (mgr_busy[i]) {
36558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			busy = true;
36658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
36758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
36858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
36958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		configure_manager(i);
37058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mc->dirty = false;
37158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mc->shadow_dirty = true;
37258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mgr_go[i] = true;
37358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
37458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
37558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* set GO */
37658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
37758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mc = &dss_cache.manager_cache[i];
37858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
37958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!mgr_go[i])
38058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			continue;
38158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
38258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		/* We don't need GO with manual update display. LCD iface will
38358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * always be turned off after frame, and new settings will be
38458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		 * taken in to use at next update */
38558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!mc->manual_update)
38658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			dispc_mgr_go(i);
38758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
38858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
38958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (busy)
39058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = 1;
39158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	else
39258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		r = 0;
39358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
39458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
39558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
39658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
39758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenvoid dss_mgr_start_update(struct omap_overlay_manager *mgr)
39858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
39958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct manager_cache_data *mc;
40058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct overlay_cache_data *oc;
40107e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	struct omap_overlay *ovl;
40258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
40358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mc = &dss_cache.manager_cache[mgr->id];
40458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
40558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mc->do_manual_update = true;
40658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	configure_dispc();
40758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mc->do_manual_update = false;
40858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
40907e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list) {
41007e327c9c18b382656bf455051759be8182627aeTomi Valkeinen		oc = &dss_cache.overlay_cache[ovl->id];
41158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		oc->shadow_dirty = false;
41258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
41358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
4146e53ca9dda65dd300ce150822832ba6e169643c7Tomi Valkeinen	mc = &dss_cache.manager_cache[mgr->id];
4156e53ca9dda65dd300ce150822832ba6e169643c7Tomi Valkeinen	mc->shadow_dirty = false;
41658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
4177797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen	dispc_mgr_enable(mgr->id, true);
41858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
41958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
42058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic void dss_apply_irq_handler(void *data, u32 mask)
42158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
42258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct manager_cache_data *mc;
42358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct overlay_cache_data *oc;
42458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	const int num_ovls = dss_feat_get_num_ovls();
42558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	const int num_mgrs = dss_feat_get_num_mgrs();
42658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	int i, r;
42758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	bool mgr_busy[MAX_DSS_MANAGERS];
42858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 irq_mask;
42958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
43058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; i++)
43158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mgr_busy[i] = dispc_mgr_go_busy(i);
43258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
43358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	spin_lock(&dss_cache.lock);
43458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
43558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_ovls; ++i) {
43658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		oc = &dss_cache.overlay_cache[i];
43758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!mgr_busy[oc->channel])
43858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			oc->shadow_dirty = false;
43958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
44058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
44158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
44258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mc = &dss_cache.manager_cache[i];
44358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (!mgr_busy[i])
44458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			mc->shadow_dirty = false;
44558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
44658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
44758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	r = configure_dispc();
44858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (r == 1)
44958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		goto end;
45058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
45158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* re-read busy flags */
45258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; i++)
45358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mgr_busy[i] = dispc_mgr_go_busy(i);
45458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
45558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* keep running as long as there are busy managers, so that
45658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	 * we can collect overlay-applied information */
45758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	for (i = 0; i < num_mgrs; ++i) {
45858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (mgr_busy[i])
45958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			goto end;
46058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
46158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
46258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
46358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			DISPC_IRQ_EVSYNC_EVEN;
46458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (dss_has_feature(FEAT_MGR_LCD2))
46558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		irq_mask |= DISPC_IRQ_VSYNC2;
46658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
46758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
46858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dss_cache.irq_enabled = false;
46958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
47058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenend:
47158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	spin_unlock(&dss_cache.lock);
47258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
47358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
47458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic int omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
47558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
47658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct overlay_cache_data *oc;
47758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
47858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
47958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	oc = &dss_cache.overlay_cache[ovl->id];
48058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
48158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (ovl->manager_changed) {
48258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		ovl->manager_changed = false;
48358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		ovl->info_dirty  = true;
48458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
48558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
48658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!overlay_enabled(ovl)) {
48758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (oc->enabled) {
48858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			oc->enabled = false;
48958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			oc->dirty = true;
49058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
49158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
49258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
49358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!ovl->info_dirty)
49558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return 0;
49658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
49858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
49958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (dss_check_overlay(ovl, dssdev)) {
50058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		if (oc->enabled) {
50158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			oc->enabled = false;
50258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen			oc->dirty = true;
50358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		}
50458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return -EINVAL;
50558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
50658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
50758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	ovl->info_dirty = false;
50858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	oc->dirty = true;
50958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	oc->info = ovl->info;
51058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	oc->channel = ovl->manager->id;
51258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	oc->enabled = true;
51458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return 0;
51658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
51758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
51858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
51958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
52058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct manager_cache_data *mc;
52158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
52258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mc = &dss_cache.manager_cache[mgr->id];
52358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
52458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (mgr->device_changed) {
52558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mgr->device_changed = false;
52658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		mgr->info_dirty  = true;
52758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
52858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
52958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!mgr->info_dirty)
53058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return;
53158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!mgr->device)
53358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return;
53458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mgr->info_dirty = false;
53658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mc->dirty = true;
53758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mc->info = mgr->info;
53858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
53958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	mc->manual_update = mgr_manual_update(mgr);
54058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
54158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
54258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenstatic void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl)
54358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
54458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct overlay_cache_data *oc;
54558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	struct omap_dss_device *dssdev;
54658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	u32 size, burst_size;
54758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
54858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	oc = &dss_cache.overlay_cache[ovl->id];
54958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (!oc->enabled)
55158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return;
55258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dssdev = ovl->manager->device;
55458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	size = dispc_ovl_get_fifo_size(ovl->id);
55658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	burst_size = dispc_ovl_get_burst_size(ovl->id);
55858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
55958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	switch (dssdev->type) {
56058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DPI:
56158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DBI:
56258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_SDI:
56358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_VENC:
56458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_HDMI:
56558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		default_get_overlay_fifo_thresholds(ovl->id, size,
56658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen				burst_size, &oc->fifo_low,
56758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen				&oc->fifo_high);
56858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		break;
56958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_DSI
57058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	case OMAP_DISPLAY_TYPE_DSI:
57158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		dsi_get_overlay_fifo_thresholds(ovl->id, size,
57258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen				burst_size, &oc->fifo_low,
57358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen				&oc->fifo_high);
57458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		break;
57558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen#endif
57658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	default:
57758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		BUG();
57858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	}
57958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
58058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
58158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinenint omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
58258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen{
58307e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	int r;
58458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	unsigned long flags;
58507e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	struct omap_overlay *ovl;
58658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
58758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
58858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
58958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	r = dispc_runtime_get();
59058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	if (r)
59158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		return r;
59258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	spin_lock_irqsave(&dss_cache.lock, flags);
59458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* Configure overlays */
59607e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list)
59758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		omap_dss_mgr_apply_ovl(ovl);
59858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
59958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* Configure manager */
60058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	omap_dss_mgr_apply_mgr(mgr);
60158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
60258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	/* Configure overlay fifos */
60307e327c9c18b382656bf455051759be8182627aeTomi Valkeinen	list_for_each_entry(ovl, &mgr->overlays, list)
60458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen		omap_dss_mgr_apply_ovl_fifos(ovl);
60558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
60658f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	r = 0;
60704f6643a8657bd080344d2928dde917e0b1b3800Tomi Valkeinen	if (mgr->enabled && !mgr_manual_update(mgr)) {
60818135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen		if (!dss_cache.irq_enabled) {
60918135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen			u32 mask;
61058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
61118135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen			mask = DISPC_IRQ_VSYNC	| DISPC_IRQ_EVSYNC_ODD |
61218135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen				DISPC_IRQ_EVSYNC_EVEN;
61318135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen			if (dss_has_feature(FEAT_MGR_LCD2))
61418135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen				mask |= DISPC_IRQ_VSYNC2;
61558f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
61618135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen			r = omap_dispc_register_isr(dss_apply_irq_handler,
61718135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen					NULL, mask);
61858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
61918135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen			if (r)
62018135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen				DSSERR("failed to register apply isr\n");
62158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
62218135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen			dss_cache.irq_enabled = true;
62318135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen		}
62458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
62518135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen		configure_dispc();
62618135eadac6f0fd1bf61b7af24f14e7174155e6dTomi Valkeinen	}
62758f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
62858f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	spin_unlock_irqrestore(&dss_cache.lock, flags);
62958f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
63058f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	dispc_runtime_put();
63158f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
63258f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen	return r;
63358f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen}
63458f2554807a7dc627f1583d1d4363b85758cf685Tomi Valkeinen
6357797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinenvoid dss_mgr_enable(struct omap_overlay_manager *mgr)
6367797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen{
6377797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen	dispc_mgr_enable(mgr->id, true);
638be729178f0e0f31ab14b42b3fe5d6b4463fbeb3aTomi Valkeinen	mgr->enabled = true;
6397797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen}
6407797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen
6417797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinenvoid dss_mgr_disable(struct omap_overlay_manager *mgr)
6427797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen{
6437797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen	dispc_mgr_enable(mgr->id, false);
644be729178f0e0f31ab14b42b3fe5d6b4463fbeb3aTomi Valkeinen	mgr->enabled = false;
6457797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen}
6467797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen
647