From c915f2cb7dc6810ffd8c4fe725772cf31e119d8b Mon Sep 17 00:00:00 2001 From: Sunyoung Kang Date: Tue, 20 Nov 2018 14:10:58 +0900 Subject: [PATCH] [RAMEN9610-10029][COMMON] media: mfc: fix the clock on sequence When the clock on with drm instance, the sequence is changed as following: cache flush (cmd 12) -> clock off -> set DRM base address -> IP protection enable -> clock on The base addr and protection control should be applied before clock enable because the MFC core can run immediately when the clock enable. Change-Id: Ib371a7b3079eb76515a38e977c76b78cc37f4c78 Signed-off-by: Sunyoung Kang --- drivers/media/platform/exynos/mfc/mfc_pm.c | 47 ++++++++++++++-------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/media/platform/exynos/mfc/mfc_pm.c b/drivers/media/platform/exynos/mfc/mfc_pm.c index efa109dc7583..fcf4cd2682d0 100644 --- a/drivers/media/platform/exynos/mfc/mfc_pm.c +++ b/drivers/media/platform/exynos/mfc/mfc_pm.c @@ -43,16 +43,18 @@ int mfc_pm_clock_on(struct mfc_dev *dev) dev->pm.clock_on_steps = 1; state = atomic_read(&dev->clk_ref); - MFC_TRACE_DEV("** clock_on start: ref state(%d)\n", state); - ret = clk_enable(dev->pm.clock); - if (ret < 0) { - mfc_err_dev("clk_enable failed (%d)\n", ret); - call_dop(dev, dump_and_stop_debug_mode, dev); - return ret; - } - dev->pm.clock_on_steps |= 0x1 << 1; + /* + * When the clock is enabled, the MFC core can run immediately. + * So the base addr and protection should be applied before clock enable. + * The MFC and TZPC SFR are in APB clock domain and it is accessible + * through Q-CH even if clock off. + * The sequence for switching normal to drm is following + * cache flush (cmd 12) -> clock off -> set DRM base addr + * -> IP Protection enable -> clock on + */ + dev->pm.clock_on_steps |= 0x1 << 1; if (dev->pm.base_type != MFCBUF_INVALID) mfc_set_risc_base_addr(dev, dev->pm.base_type); @@ -70,14 +72,22 @@ int mfc_pm_clock_on(struct mfc_dev *dev) mfc_err_dev("Protection Enable failed! ret(%u)\n", ret); call_dop(dev, dump_and_stop_debug_mode, dev); spin_unlock_irqrestore(&dev->pm.clklock, flags); - clk_disable(dev->pm.clock); return -EACCES; } mfc_debug(3, "End: enable protection\n"); spin_unlock_irqrestore(&dev->pm.clklock, flags); } #endif + dev->pm.clock_on_steps |= 0x1 << 4; + ret = clk_enable(dev->pm.clock); + if (ret < 0) { + mfc_err_dev("clk_enable failed (%d)\n", ret); + call_dop(dev, dump_and_stop_debug_mode, dev); + return ret; + } + + dev->pm.clock_on_steps |= 0x1 << 5; atomic_inc_return(&dev->clk_ref); dev->pm.clock_on_steps |= 0x1 << 6; @@ -114,34 +124,39 @@ void mfc_pm_clock_off(struct mfc_dev *dev) mfc_err_dev("Clock state is wrong(%d)\n", state); atomic_set(&dev->clk_ref, 0); dev->pm.clock_off_steps |= 0x1 << 2; + MFC_TRACE_DEV("** clock_off wrong: ref state(%d)\n", atomic_read(&dev->clk_ref)); } else { + dev->pm.clock_off_steps |= 0x1 << 3; + clk_disable(dev->pm.clock); + + dev->pm.clock_off_steps |= 0x1 << 4; #ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION if (dev->curr_ctx_is_drm) { unsigned long flags; int ret = 0; - + /* + * After clock off the protection disable should be + * because the MFC core can continuously run during clock on + */ mfc_debug(3, "Begin: disable protection\n"); spin_lock_irqsave(&dev->pm.clklock, flags); - dev->pm.clock_off_steps |= 0x1 << 3; + dev->pm.clock_off_steps |= 0x1 << 5; ret = exynos_smc(SMC_PROTECTION_SET, 0, dev->id, SMC_PROTECTION_DISABLE); if (ret != DRMDRV_OK) { mfc_err_dev("Protection Disable failed! ret(%u)\n", ret); call_dop(dev, dump_and_stop_debug_mode, dev); spin_unlock_irqrestore(&dev->pm.clklock, flags); - clk_disable(dev->pm.clock); return; } mfc_debug(3, "End: disable protection\n"); - dev->pm.clock_off_steps |= 0x1 << 4; + dev->pm.clock_off_steps |= 0x1 << 6; spin_unlock_irqrestore(&dev->pm.clklock, flags); } #endif - dev->pm.clock_off_steps |= 0x1 << 5; - clk_disable(dev->pm.clock); } - dev->pm.clock_off_steps |= 0x1 << 6; + dev->pm.clock_off_steps |= 0x1 << 7; state = atomic_read(&dev->clk_ref); mfc_debug(2, "- %d\n", state); MFC_TRACE_DEV("** clock_off end: ref state(%d)\n", state); -- 2.20.1