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