From patchwork Fri Jul 15 10:07:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: YT Shen X-Patchwork-Id: 9231559 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A364D6075D for ; Fri, 15 Jul 2016 10:10:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9384F27FB7 for ; Fri, 15 Jul 2016 10:10:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 87CA228324; Fri, 15 Jul 2016 10:10:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1FBF827FB7 for ; Fri, 15 Jul 2016 10:10:44 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bO03d-00013O-Q2; Fri, 15 Jul 2016 10:09:21 +0000 Received: from [210.61.82.183] (helo=mailgw01.mediatek.com) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bO03E-0000bg-LY; Fri, 15 Jul 2016 10:08:59 +0000 Received: from mtkhts09.mediatek.inc [(172.21.101.70)] by mailgw01.mediatek.com (envelope-from ) (mhqrelay.mediatek.com ESMTP with TLS) with ESMTP id 1326534470; Fri, 15 Jul 2016 18:08:36 +0800 Received: from mtkslt301.mediatek.inc (10.21.14.114) by mtkhts09.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 14.3.266.1; Fri, 15 Jul 2016 18:08:35 +0800 From: YT Shen To: , Philipp Zabel Subject: [PATCH v4 3/8] drm/mediatek: add shadow register support Date: Fri, 15 Jul 2016 18:07:49 +0800 Message-ID: <1468577274-6178-4-git-send-email-yt.shen@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1468577274-6178-1-git-send-email-yt.shen@mediatek.com> References: <1468577274-6178-1-git-send-email-yt.shen@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160715_030857_051069_7A04B8AA X-CRM114-Status: GOOD ( 18.70 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , devicetree@vger.kernel.org, Russell King , srv_heupstream@mediatek.com, Pawel Moll , Ian Campbell , David Airlie , thierry.reding@gmail.com, emil.l.velikov@gmail.com, linux-kernel@vger.kernel.org, Mao Huang , YT Shen , CK Hu , Rob Herring , linux-mediatek@lists.infradead.org, Bibby Hsieh , Kumar Gala , Matthias Brugger , yingjoe.chen@mediatek.com, Sascha Hauer , linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP We need to acquire mutex before using the resources, and need to release it after finished. So we don't need to write registers in the blanking period. Signed-off-by: YT Shen --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 75 +++++++++++++++++++------------ drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 22 +++++++++ drivers/gpu/drm/mediatek/mtk_drm_ddp.h | 2 + drivers/gpu/drm/mediatek/mtk_drm_drv.h | 1 + 4 files changed, 71 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 24aa3ba..80d9641 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -315,6 +315,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc) pm_runtime_put(drm->dev); } +static void mtk_crtc_ddp_config(struct drm_crtc *crtc) +{ + struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); + struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state); + struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0]; + unsigned int i; + + /* + * TODO: instead of updating the registers here, we should prepare + * working registers in atomic_commit and let the hardware command + * queue update module registers on vblank. + */ + if (state->pending_config) { + mtk_ddp_comp_config(ovl, state->pending_width, + state->pending_height, + state->pending_vrefresh); + + state->pending_config = false; + } + + if (mtk_crtc->pending_planes) { + for (i = 0; i < OVL_LAYER_NR; i++) { + struct drm_plane *plane = &mtk_crtc->planes[i].base; + struct mtk_plane_state *plane_state; + + plane_state = to_mtk_plane_state(plane->state); + + if (plane_state->pending.config) { + mtk_ddp_comp_layer_config(ovl, i, plane_state); + plane_state->pending.config = false; + } + } + mtk_crtc->pending_planes = false; + } +} + static void mtk_drm_crtc_enable(struct drm_crtc *crtc) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); @@ -391,6 +427,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); + struct mtk_drm_private *priv = crtc->dev->dev_private; unsigned int pending_planes = 0; int i; @@ -409,6 +446,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc, } if (pending_planes) mtk_crtc->pending_planes = true; + + if (priv->data->shadow_register) { + mtk_disp_mutex_acquire(mtk_crtc->mutex); + mtk_crtc_ddp_config(crtc); + mtk_disp_mutex_release(mtk_crtc->mutex); + } } static const struct drm_crtc_funcs mtk_crtc_funcs = { @@ -453,36 +496,10 @@ err_cleanup_crtc: void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); - struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state); - unsigned int i; + struct mtk_drm_private *priv = crtc->dev->dev_private; - /* - * TODO: instead of updating the registers here, we should prepare - * working registers in atomic_commit and let the hardware command - * queue update module registers on vblank. - */ - if (state->pending_config) { - mtk_ddp_comp_config(ovl, state->pending_width, - state->pending_height, - state->pending_vrefresh); - - state->pending_config = false; - } - - if (mtk_crtc->pending_planes) { - for (i = 0; i < OVL_LAYER_NR; i++) { - struct drm_plane *plane = &mtk_crtc->planes[i].base; - struct mtk_plane_state *plane_state; - - plane_state = to_mtk_plane_state(plane->state); - - if (plane_state->pending.config) { - mtk_ddp_comp_layer_config(ovl, i, plane_state); - plane_state->pending.config = false; - } - } - mtk_crtc->pending_planes = false; - } + if (!priv->data->shadow_register) + mtk_crtc_ddp_config(crtc); mtk_drm_finish_page_flip(mtk_crtc); } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c index 8030769..fa53806 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -32,6 +33,7 @@ #define DISP_REG_CONFIG_MMSYS_CG_CON0 0x100 #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) +#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) #define DISP_REG_MUTEX_MOD(n) (0x2c + 0x20 * (n)) #define DISP_REG_MUTEX_SOF(n) (0x30 + 0x20 * (n)) @@ -300,6 +302,26 @@ void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex) writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); } +void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex) +{ + struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, + mutex[mutex->id]); + u32 tmp; + + writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); + writel(1, ddp->regs + DISP_REG_MUTEX(mutex->id)); + readl_poll_timeout_atomic(ddp->regs + DISP_REG_MUTEX(mutex->id), tmp, + tmp & 0x2, 1, 10000); +} + +void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex) +{ + struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, + mutex[mutex->id]); + + writel(0, ddp->regs + DISP_REG_MUTEX(mutex->id)); +} + static int mtk_ddp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h index 92c1175..f9a7991 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.h @@ -37,5 +37,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex, enum mtk_ddp_comp_id id); void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex); void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex); +void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex); +void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex); #endif /* MTK_DRM_DDP_H */ diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h index fa0b106..94f8b66 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h @@ -33,6 +33,7 @@ struct mtk_mmsys_driver_data { unsigned int main_len; const enum mtk_ddp_comp_id *ext_path; unsigned int ext_len; + bool shadow_register; }; struct mtk_drm_private {