From 4f68f6337d58b19765359d86745598850265cea9 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 1 Aug 2016 13:55:21 +0200 Subject: [PATCH] media: s5p-mfc: use clock gating only on mfc v5 hardware Software clock gating causes unpredicted behavior of newer MFC hardware, so use it only when working with v5 module. Signed-off-by: Marek Szyprowski Change-Id: I5a636b9c46b5e387da4d1c4f6dbb4adb583085e3 --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 1 + drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 2 ++ drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 23 ++++++++++++++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index a955eec..7af9facc 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1340,6 +1340,7 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = { .fw_name[0] = "s5p-mfc.fw", .clk_names = {"mfc", "sclk_mfc"}, .num_clocks = 2, + .use_clock_gating = true, }; static struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = { diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 9ef00c4..9a9d733 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -200,6 +200,7 @@ struct s5p_mfc_pm { const char **clk_names; struct clk *clocks[MFC_MAX_CLOCKS]; int num_clocks; + bool use_clock_gating; atomic_t power; struct device *device; @@ -239,6 +240,7 @@ struct s5p_mfc_variant { char *fw_name[MFC_FW_MAX_VERSIONS]; const char *clk_names[MFC_MAX_CLOCKS]; int num_clocks; + bool use_clock_gating; }; /** diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index d21055e..cdeed67 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -37,6 +37,7 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev) pm->num_clocks = dev->variant->num_clocks; pm->clk_names = dev->variant->clk_names; + pm->use_clock_gating = dev->variant->use_clock_gating; /* clock control */ for (i = 0; i < pm->num_clocks; i++) { @@ -73,6 +74,8 @@ int s5p_mfc_clock_on(void) atomic_inc(&clk_ref); mfc_debug(3, "+ %d\n", atomic_read(&clk_ref)); #endif + if (!pm->use_clock_gating) + return 0; for (i = 0; i < pm->num_clocks; i++) { ret = clk_enable(pm->clocks[i]); @@ -92,6 +95,9 @@ void s5p_mfc_clock_off(void) atomic_dec(&clk_ref); mfc_debug(3, "- %d\n", atomic_read(&clk_ref)); #endif + if (!pm->use_clock_gating) + return; + for (i = pm->num_clocks - 1; i >= 0; i--) clk_disable(pm->clocks[i]); } @@ -109,7 +115,11 @@ int s5p_mfc_power_on(void) #endif /* clock control */ for (i = 0; i < pm->num_clocks; i++) { - ret = clk_prepare(pm->clocks[i]); + if (pm->use_clock_gating) + ret = clk_prepare(pm->clocks[i]); + else + ret = clk_prepare_enable(pm->clocks[i]); + if (ret < 0) { mfc_err("clock prepare failed for clock: %s\n", pm->clk_names[i]); @@ -121,7 +131,10 @@ int s5p_mfc_power_on(void) return 0; err: while (--i > 0) - clk_unprepare(pm->clocks[i]); + if (pm->use_clock_gating) + clk_disable(pm->clocks[i]); + else + clk_disable_unprepare(pm->clocks[i]); pm_runtime_put(pm->device); return ret; } @@ -129,8 +142,12 @@ err: int s5p_mfc_power_off(void) { int i; + for (i = 0; i < pm->num_clocks; i++) - clk_unprepare(pm->clocks[i]); + if (pm->use_clock_gating) + clk_unprepare(pm->clocks[i]); + else + clk_disable_unprepare(pm->clocks[i]); #ifdef CONFIG_PM return pm_runtime_put_sync(pm->device); -- 2.7.4