media: s5p-mfc: use clock gating only on mfc v5 hardware
authorMarek Szyprowski <m.szyprowski@samsung.com>
Mon, 1 Aug 2016 11:55:21 +0000 (13:55 +0200)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 14 Dec 2016 04:52:06 +0000 (13:52 +0900)
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

drivers/media/platform/s5p-mfc/s5p_mfc.c
drivers/media/platform/s5p-mfc/s5p_mfc_common.h
drivers/media/platform/s5p-mfc/s5p_mfc_pm.c

index a955eec..7af9fac 100644 (file)
@@ -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 = {
index 9ef00c4..9a9d733 100644 (file)
@@ -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;
 };
 
 /**
index d21055e..cdeed67 100644 (file)
@@ -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);