From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marek Szyprowski Subject: [PATCH v6 04/25] drm/exynos: fimd: ensure proper hw state in fimd_clear_channel() Date: Mon, 04 May 2015 10:15:59 +0200 Message-ID: <1430727380-10912-5-git-send-email-m.szyprowski@samsung.com> References: <1430727380-10912-1-git-send-email-m.szyprowski@samsung.com> Return-path: Received: from mailout1.w1.samsung.com ([210.118.77.11]:38296 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751860AbbEDIRH (ORCPT ); Mon, 4 May 2015 04:17:07 -0400 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NNT008Y0GCGJD50@mailout1.w1.samsung.com> for linux-samsung-soc@vger.kernel.org; Mon, 04 May 2015 09:17:04 +0100 (BST) In-reply-to: <1430727380-10912-1-git-send-email-m.szyprowski@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org List-Id: linux-samsung-soc@vger.kernel.org To: iommu@lists.linux-foundation.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Marek Szyprowski , linaro-mm-sig@lists.linaro.org, Arnd Bergmann , Shaik Ameer Basha , Cho KyongHo , Joerg Roedel , Thierry Reding , Olof Johansson , Laurent Pinchart , Rob Herring , Will Deacon , David Wodhouse , Inki Dae , Kukjin Kim , Tomasz Figa , Kyungmin Park , Joonyoung Shim , Seung-Woo Kim , Javier Martinez Canillas One should not do any assumptions on the stare of the fimd hardware during driver initialization, so to properly reset fimd before enabling IOMMU, one should ensure that all power domains and clocks are really enabled. This patch adds calls to power on/off in the fimd_clear_channel() function to ensure that any access to fimd registers will be performed with clocks and power domains enabled. Signed-off-by: Marek Szyprowski --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 9819fa6a9e2a..cf64550df59d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -242,12 +242,20 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win, writel(val, ctx->regs + SHADOWCON); } -static void fimd_clear_channel(struct fimd_context *ctx) +static int fimd_poweron(struct fimd_context *ctx); +static int fimd_poweroff(struct fimd_context *ctx); + +static int fimd_clear_channel(struct fimd_context *ctx) { - int win, ch_enabled = 0; + int ret, win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); + /* Hardware is in unknown state, so ensure it get enabled properly */ + ret = fimd_poweron(ctx); + if (ret) + return ret; + /* Check if any channel is enabled. */ for (win = 0; win < WINDOWS_NR; win++) { u32 val = readl(ctx->regs + WINCON(win)); @@ -258,19 +266,15 @@ static void fimd_clear_channel(struct fimd_context *ctx) if (ctx->driver_data->has_shadowcon) fimd_enable_shadow_channel_path(ctx, win, false); - ch_enabled = 1; } } /* Wait for vsync, as disable channel takes effect at next vsync */ - if (ch_enabled) { - unsigned int state = ctx->suspended; - - ctx->suspended = 0; + if (ch_enabled) fimd_wait_for_vblank(ctx->crtc); - ctx->suspended = state; - } + + return fimd_poweroff(ctx); } static int fimd_iommu_attach_devices(struct fimd_context *ctx, @@ -285,7 +289,10 @@ static int fimd_iommu_attach_devices(struct fimd_context *ctx, * If any channel is already active, iommu will throw * a PAGE FAULT when enabled. So clear any channel if enabled. */ - fimd_clear_channel(ctx); + ret = fimd_clear_channel(ctx); + if (ret) + return ret; + ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev); if (ret) { DRM_ERROR("drm_iommu_attach failed.\n"); -- 1.9.2 From mboxrd@z Thu Jan 1 00:00:00 1970 From: m.szyprowski@samsung.com (Marek Szyprowski) Date: Mon, 04 May 2015 10:15:59 +0200 Subject: [PATCH v6 04/25] drm/exynos: fimd: ensure proper hw state in fimd_clear_channel() In-Reply-To: <1430727380-10912-1-git-send-email-m.szyprowski@samsung.com> References: <1430727380-10912-1-git-send-email-m.szyprowski@samsung.com> Message-ID: <1430727380-10912-5-git-send-email-m.szyprowski@samsung.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org One should not do any assumptions on the stare of the fimd hardware during driver initialization, so to properly reset fimd before enabling IOMMU, one should ensure that all power domains and clocks are really enabled. This patch adds calls to power on/off in the fimd_clear_channel() function to ensure that any access to fimd registers will be performed with clocks and power domains enabled. Signed-off-by: Marek Szyprowski --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 9819fa6a9e2a..cf64550df59d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -242,12 +242,20 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win, writel(val, ctx->regs + SHADOWCON); } -static void fimd_clear_channel(struct fimd_context *ctx) +static int fimd_poweron(struct fimd_context *ctx); +static int fimd_poweroff(struct fimd_context *ctx); + +static int fimd_clear_channel(struct fimd_context *ctx) { - int win, ch_enabled = 0; + int ret, win, ch_enabled = 0; DRM_DEBUG_KMS("%s\n", __FILE__); + /* Hardware is in unknown state, so ensure it get enabled properly */ + ret = fimd_poweron(ctx); + if (ret) + return ret; + /* Check if any channel is enabled. */ for (win = 0; win < WINDOWS_NR; win++) { u32 val = readl(ctx->regs + WINCON(win)); @@ -258,19 +266,15 @@ static void fimd_clear_channel(struct fimd_context *ctx) if (ctx->driver_data->has_shadowcon) fimd_enable_shadow_channel_path(ctx, win, false); - ch_enabled = 1; } } /* Wait for vsync, as disable channel takes effect at next vsync */ - if (ch_enabled) { - unsigned int state = ctx->suspended; - - ctx->suspended = 0; + if (ch_enabled) fimd_wait_for_vblank(ctx->crtc); - ctx->suspended = state; - } + + return fimd_poweroff(ctx); } static int fimd_iommu_attach_devices(struct fimd_context *ctx, @@ -285,7 +289,10 @@ static int fimd_iommu_attach_devices(struct fimd_context *ctx, * If any channel is already active, iommu will throw * a PAGE FAULT when enabled. So clear any channel if enabled. */ - fimd_clear_channel(ctx); + ret = fimd_clear_channel(ctx); + if (ret) + return ret; + ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev); if (ret) { DRM_ERROR("drm_iommu_attach failed.\n"); -- 1.9.2