diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2016-08-01 13:55:21 +0200 |
---|---|---|
committer | Seung-Woo Kim <sw0312.kim@samsung.com> | 2016-12-14 13:52:06 +0900 |
commit | 4f68f6337d58b19765359d86745598850265cea9 (patch) | |
tree | d78700113a674b3c344725f6ffeaf17f71b755e7 /drivers/media | |
parent | 2b86f450c476d93f4083e8b05cd256f96c6fd586 (diff) |
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 <m.szyprowski@samsung.com>
Change-Id: I5a636b9c46b5e387da4d1c4f6dbb4adb583085e3
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc.c | 1 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 2 | ||||
-rw-r--r-- | 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 a955eec71548..7af9facc85d4 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 9ef00c485fb5..9a9d7332491e 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 d21055e19a71..cdeed6731784 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); |