From patchwork Wed Nov 7 14:44:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: archit taneja X-Patchwork-Id: 1710801 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id A9F95DFB7A for ; Wed, 7 Nov 2012 14:45:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753945Ab2KGOpP (ORCPT ); Wed, 7 Nov 2012 09:45:15 -0500 Received: from comal.ext.ti.com ([198.47.26.152]:47567 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753794Ab2KGOpN (ORCPT ); Wed, 7 Nov 2012 09:45:13 -0500 Received: from dlelxv30.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id qA7EjCbY026061; Wed, 7 Nov 2012 08:45:12 -0600 Received: from DLEE74.ent.ti.com (dlee74.ent.ti.com [157.170.170.8]) by dlelxv30.itg.ti.com (8.13.8/8.13.8) with ESMTP id qA7EjCgM010824; Wed, 7 Nov 2012 08:45:12 -0600 Received: from dlelxv24.itg.ti.com (172.17.1.199) by DLEE74.ent.ti.com (157.170.170.8) with Microsoft SMTP Server id 14.1.323.3; Wed, 7 Nov 2012 08:45:12 -0600 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by dlelxv24.itg.ti.com (8.13.8/8.13.8) with ESMTP id qA7EjCKQ011101; Wed, 7 Nov 2012 08:45:12 -0600 Received: from localhost (a0393947pc.apr.dhcp.ti.com [172.24.136.151]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id qA7EjBw12897; Wed, 7 Nov 2012 08:45:11 -0600 (CST) From: Archit Taneja To: CC: , , Archit Taneja Subject: [RFC 07/11] OMAPDSS: writeback: add mechanism to do mem to mem updates Date: Wed, 7 Nov 2012 20:14:25 +0530 Message-ID: <1352299469-17609-8-git-send-email-archit@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1352299469-17609-1-git-send-email-archit@ti.com> References: <1352299469-17609-1-git-send-email-archit@ti.com> MIME-Version: 1.0 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org writeback in mem to mem mode works like an overlay manager connected to a display in stallmode. When we set ENABLE in DISPC_WB_ATTRIBUTES writeback, it starts a mem to mem transfer. On completion, we get a FRAMEDONEWB interrupt and the ENABLE bit is cleared by HW. In APPLY, we add dss_wb_start_update, this function is similar to dss_mgr_start_update, but is responsible for configuring both the manager(and the overlays connected to it) and the writeback registers. We add an updating field in the writeback private data which tells APPLY when we are busy and when we are done with a mem to mem transfer. We register to the framedone isr when needed and we update the updating field in dss_apply_irq_handler when we are done with the transfer. In the writeback output driver, we add a semaphore based way to lock the writeback resource as we do in DSI command mode. The writeback user is expected to lock the bus, call omapdss_writeback_update and mention a callback along with it, and unlock the bus in the callback. omapdss_writeback_update registers to the FRAMEDONE interrupt to trigger the callback and starts the update by calling the corresponding APPLY function. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/apply.c | 83 +++++++++++++++++++++++++++ drivers/video/omap2/dss/dss.h | 1 + drivers/video/omap2/dss/writeback.c | 106 +++++++++++++++++++++++++++++++++++ include/video/omapdss.h | 4 ++ 4 files changed, 194 insertions(+) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index a205ed4..2fd08d8 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -114,6 +114,9 @@ struct wb_priv_data { bool info_dirty; struct omap_dss_writeback_info info; + /* If true, writeback output is enabled */ + bool updating; + /* * If true in memory to memory mode, a manager is connected to it. * However, it may not be active. @@ -285,6 +288,7 @@ static int dss_check_settings_apply(struct omap_overlay_manager *mgr) static bool need_isr(void) { const int num_mgrs = dss_feat_get_num_mgrs(); + const int num_wbs = dss_feat_get_num_wbs(); int i; for (i = 0; i < num_mgrs; ++i) { @@ -362,6 +366,20 @@ static bool need_isr(void) } } + for (i = 0; i < num_wbs; i++) { + struct omap_dss_output *wb = omap_dss_get_writeback(); + struct wb_priv_data *wp = get_wb_priv(wb); + + if (!wp->enabled) + continue; + + if (wb_manual_update(wb)) { + /* to catch FRAMEDONEWB */ + if (wp->updating) + return true; + } + } + return false; } @@ -841,6 +859,7 @@ static void dss_apply_irq_handler(void *data, u32 mask); static void dss_register_vsync_isr(void) { const int num_mgrs = dss_feat_get_num_mgrs(); + const int num_wbs = dss_feat_get_num_wbs(); u32 mask; int r, i; @@ -851,6 +870,9 @@ static void dss_register_vsync_isr(void) for (i = 0; i < num_mgrs; ++i) mask |= dispc_mgr_get_framedone_irq(i); + for (i = 0; i < num_wbs; i++) + mask |= dispc_wb_get_framedone_irq(); + r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask); WARN_ON(r); @@ -860,6 +882,7 @@ static void dss_register_vsync_isr(void) static void dss_unregister_vsync_isr(void) { const int num_mgrs = dss_feat_get_num_mgrs(); + const int num_wbs = dss_feat_get_num_wbs(); u32 mask; int r, i; @@ -870,6 +893,9 @@ static void dss_unregister_vsync_isr(void) for (i = 0; i < num_mgrs; ++i) mask |= dispc_mgr_get_framedone_irq(i); + for (i = 0; i < num_wbs; i++) + mask |= dispc_wb_get_framedone_irq(); + r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask); WARN_ON(r); @@ -879,6 +905,7 @@ static void dss_unregister_vsync_isr(void) static void dss_apply_irq_handler(void *data, u32 mask) { const int num_mgrs = dss_feat_get_num_mgrs(); + const int num_wbs = dss_feat_get_num_wbs(); int i; bool extra_updating; @@ -906,6 +933,16 @@ static void dss_apply_irq_handler(void *data, u32 mask) } } + for (i = 0; i < num_wbs; i++) { + struct omap_dss_output *wb = omap_dss_get_writeback(); + struct wb_priv_data *wp = get_wb_priv(wb); + + if (!wp->enabled) + continue; + + wp->updating = dispc_wb_is_enabled(); + } + dss_write_regs(); dss_set_go_bits(); @@ -1685,6 +1722,11 @@ void dss_wb_disable(struct omap_dss_output *wb) if (!wp->enabled) goto out; + if (wp->updating) { + DSSERR("can't disable writeback in the middle of an update\n"); + goto out; + } + spin_lock_irqsave(&data_lock, flags); wp->updating = false; @@ -1694,3 +1736,44 @@ void dss_wb_disable(struct omap_dss_output *wb) out: mutex_unlock(&apply_lock); } + +/* + * When doing a writeback mem to mem update, the updating field for writeback + * private data is true, but for manager private data the updating field is + * false. This is because a manager isn't really 'enabled' in HW, it's the + * writeback pipeline which initiates the transfer. + */ +void dss_wb_start_update(struct omap_dss_output *wb) +{ + struct omap_overlay_manager *mgr = wb->manager; + struct wb_priv_data *wp = get_wb_priv(wb); + unsigned long flags; + int r; + + spin_lock_irqsave(&data_lock, flags); + + WARN_ON(wp->updating); + + /* add some similar check for writeback later */ + + r = dss_check_settings(mgr); + if (r) { + DSSERR("cannot start manual update: illegal configuration\n"); + spin_unlock_irqrestore(&data_lock, flags); + return; + } + + dss_wb_write_regs(wb); + + dss_mgr_write_regs(mgr); + dss_mgr_write_regs_extra(mgr); + + wp->updating = true; + + if (!dss_data.irq_enabled && need_isr()) + dss_register_vsync_isr(); + + dispc_wb_enable(true); + + spin_unlock_irqrestore(&data_lock, flags); +} diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index f9e7074..8c70b08 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -217,6 +217,7 @@ void dss_wb_get_info(struct omap_dss_output *wb, int omap_dss_wb_apply(struct omap_dss_output *wb); int dss_wb_enable(struct omap_dss_output *wb); void dss_wb_disable(struct omap_dss_output *wb); +void dss_wb_start_update(struct omap_dss_output *wb); /* output */ void dss_register_output(struct omap_dss_output *out); diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c index 09394fb..7a25e99 100644 --- a/drivers/video/omap2/dss/writeback.c +++ b/drivers/video/omap2/dss/writeback.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include