[COMMON] media: mfc: DRV4.0: support performance boost mode
authorAyoung Sim <a.sim@samsung.com>
Fri, 8 Jun 2018 02:23:55 +0000 (11:23 +0900)
committerSunyoung Kang <sy0816.kang@samsung.com>
Mon, 23 Jul 2018 06:12:18 +0000 (15:12 +0900)
This mode should be used only for test
and user should set before MFC start(open).

Change-Id: I752d77334227f49e485604d2979aa965c8463522
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
drivers/media/platform/exynos/mfc/s5p_mfc.c
drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h
drivers/media/platform/exynos/mfc/s5p_mfc_debug.h
drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c
drivers/media/platform/exynos/mfc/s5p_mfc_qos.c
drivers/media/platform/exynos/mfc/s5p_mfc_qos.h
drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c

index e458dda19962df91cdc7dc273bc3dfe52f3f9f97..c34e0fc8f6aacb17b33ab2f0248966de53183427 100644 (file)
@@ -566,6 +566,9 @@ static int s5p_mfc_open(struct file *file)
                ret = mfc_init_instance(dev, ctx);
                if (ret)
                        goto err_init_inst;
+
+               if (perf_boost_mode)
+                       s5p_mfc_perf_boost_enable(dev);
        }
 
 #ifdef CONFIG_VIDEO_EXYNOS_REPEATER
@@ -712,6 +715,10 @@ static int s5p_mfc_release(struct file *file)
 
        if (dev->num_inst == 0) {
                s5p_mfc_deinit_hw(dev);
+
+               if (perf_boost_mode)
+                       s5p_mfc_perf_boost_disable(dev);
+
                del_timer_sync(&dev->watchdog_timer);
 
                flush_workqueue(dev->butler_wq);
@@ -878,8 +885,6 @@ static int mfc_parse_mfc_qos_platdata(struct device_node *np, char *node_name,
        of_property_read_u32(np_qos, "freq_mfc", &qosdata->freq_mfc);
        of_property_read_u32(np_qos, "freq_int", &qosdata->freq_int);
        of_property_read_u32(np_qos, "freq_mif", &qosdata->freq_mif);
-       of_property_read_u32(np_qos, "freq_cpu", &qosdata->freq_cpu);
-       of_property_read_u32(np_qos, "freq_kfc", &qosdata->freq_kfc);
        of_property_read_u32(np_qos, "mo_value", &qosdata->mo_value);
        of_property_read_u32(np_qos, "mo_10bit_value", &qosdata->mo_10bit_value);
        of_property_read_u32(np_qos, "mo_uhd_enc60_value", &qosdata->mo_uhd_enc60_value);
@@ -945,6 +950,7 @@ static void mfc_parse_dt(struct device_node *np, struct s5p_mfc_dev *mfc)
 {
        struct s5p_mfc_platdata *pdata = mfc->pdata;
 #ifdef CONFIG_MFC_USE_BUS_DEVFREQ
+       struct device_node *np_qos;
        char node_name[50];
        int i;
 #endif
@@ -1000,6 +1006,21 @@ static void mfc_parse_dt(struct device_node *np, struct s5p_mfc_dev *mfc)
                snprintf(node_name, sizeof(node_name), "mfc_qos_variant_%d", i);
                mfc_parse_mfc_qos_platdata(np, node_name, &pdata->qos_table[i]);
        }
+
+       /* performance boost mode */
+       pdata->qos_boost_table = devm_kzalloc(mfc->device,
+                       sizeof(struct s5p_mfc_qos_boost), GFP_KERNEL);
+       np_qos = of_find_node_by_name(np, "mfc_perf_boost_table");
+       if (!np_qos) {
+               pr_err("%s: could not find mfc_perf_boost_table node\n", node_name);
+               return;
+       }
+       of_property_read_u32(np_qos, "num_cluster", &pdata->qos_boost_table->num_cluster);
+       of_property_read_u32(np_qos, "freq_mfc", &pdata->qos_boost_table->freq_mfc);
+       of_property_read_u32(np_qos, "freq_int", &pdata->qos_boost_table->freq_int);
+       of_property_read_u32(np_qos, "freq_mif", &pdata->qos_boost_table->freq_mif);
+       of_property_read_u32_array(np_qos, "freq_cluster", &pdata->qos_boost_table->freq_cluster[0],
+                       pdata->qos_boost_table->num_cluster);
 #endif
 }
 
index 1d238b533f419d246178af0eac01174ffb16629f..89c78f1b84c1c9b30a251bce4f8135d00f5ea919 100644 (file)
@@ -53,6 +53,7 @@
 
 #define MAX_NUM_IMAGES_IN_VB           8
 #define MAX_NUM_BUFCON_BUFS            32
+#define MAX_NUM_CLUSTER                        3
 
 /*
  *  MFC region id for smc
@@ -311,6 +312,7 @@ struct s5p_mfc_debugfs {
        struct dentry *sfr_dump;
        struct dentry *mmcache_dump;
        struct dentry *mmcache_disable;
+       struct dentry *perf_boost_mode;
 };
 
 /**
@@ -361,13 +363,19 @@ struct s5p_mfc_qos {
        unsigned int freq_mfc;
        unsigned int freq_int;
        unsigned int freq_mif;
-       unsigned int freq_cpu;
-       unsigned int freq_kfc;
        unsigned int mo_value;
        unsigned int mo_10bit_value;
        unsigned int mo_uhd_enc60_value;
        unsigned int time_fw;
 };
+
+struct s5p_mfc_qos_boost {
+       unsigned int num_cluster;
+       unsigned int freq_mfc;
+       unsigned int freq_int;
+       unsigned int freq_mif;
+       unsigned int freq_cluster[MAX_NUM_CLUSTER];
+};
 #endif
 
 struct s5p_mfc_feature {
@@ -407,6 +415,7 @@ struct s5p_mfc_platdata {
        unsigned int mo_control;
        unsigned int bw_control;
        struct s5p_mfc_qos *qos_table;
+       struct s5p_mfc_qos_boost *qos_boost_table;
 #endif
 };
 
@@ -754,10 +763,7 @@ struct s5p_mfc_dev {
        struct pm_qos_request qos_req_mfc;
        struct pm_qos_request qos_req_int;
        struct pm_qos_request qos_req_mif;
-#ifdef CONFIG_ARM_EXYNOS_MP_CPUFREQ
-       struct pm_qos_request qos_req_cluster1;
-       struct pm_qos_request qos_req_cluster0;
-#endif
+       struct pm_qos_request qos_req_cluster[MAX_NUM_CLUSTER];
        int qos_has_enc_ctx;
 #endif
        int id;
index 4d16ebcc330f0257b6c2d6caedc0db2d613d9df1..f6bd7f1e2e189fd38edec32704cb83307c949332 100644 (file)
@@ -27,6 +27,7 @@ extern unsigned int otf_dump;
 extern unsigned int sfr_dump;
 extern unsigned int mmcache_dump;
 extern unsigned int mmcache_disable;
+extern unsigned int perf_boost_mode;
 
 #define mfc_debug(level, fmt, args...)                         \
        do {                                                    \
index 5341b4995130c5e28be2f1a50e2c3bbce646d5b9..18d2c136ce988cfd4c5a3f2469eb90a5b637fab9 100644 (file)
@@ -31,6 +31,7 @@ unsigned int perf_measure_option;
 unsigned int sfr_dump;
 unsigned int mmcache_dump;
 unsigned int mmcache_disable;
+unsigned int perf_boost_mode;
 
 static int mfc_info_show(struct seq_file *s, void *unused)
 {
@@ -54,6 +55,7 @@ static int mfc_info_show(struct seq_file *s, void *unused)
        seq_printf(s, "[MMCACHE] %s(%s)\n",
                        dev->has_mmcache ? "supported" : "not supported",
                        dev->mmcache.is_on_status ? "enabled" : "disabled");
+       seq_printf(s, "[PERF BOOST] %s\n", perf_boost_mode ? "enabled" : "disabled");
        seq_printf(s, "[FEATURES] nal_q: %d(0x%x), skype: %d(0x%x), black_bar: %d(0x%x)\n",
                        dev->pdata->nal_q.support, dev->pdata->nal_q.version,
                        dev->pdata->skype.support, dev->pdata->skype.version,
@@ -107,6 +109,12 @@ static int mfc_debug_info_show(struct seq_file *s, void *unused)
        seq_puts(s, "64  (1 << 6): ERR interrupt\n");
        seq_puts(s, "128 (1 << 7): WARN interrupt\n");
 
+       seq_puts(s, "-----Performance boost options (bit setting)\n");
+       seq_puts(s, "ex) echo 7 > /d/mfc/perf_boost_mode (max freq)\n");
+       seq_puts(s, "1   (1 << 0): DVFS (INT/MFC/MIF)\n");
+       seq_puts(s, "2   (1 << 1): MO value\n");
+       seq_puts(s, "4   (1 << 2): CPU frequency\n");
+
        return 0;
 }
 
@@ -170,4 +178,6 @@ void s5p_mfc_init_debugfs(struct s5p_mfc_dev *dev)
                        0644, debugfs->root, &mmcache_dump);
        debugfs->mmcache_disable = debugfs_create_u32("mmcache_disable",
                        0644, debugfs->root, &mmcache_disable);
+       debugfs->perf_boost_mode = debugfs_create_u32("perf_boost_mode",
+                       0644, debugfs->root, &perf_boost_mode);
 }
index 66e9071185689c4e09dc583e65e08c0e5a2c6f3e..df0c2466599fcbfe8f4721d6c03cfb6bc96904a2 100644 (file)
@@ -25,6 +25,80 @@ enum {
        MFC_QOS_BW,
 };
 
+enum {
+       MFC_PERF_BOOST_DVFS     = (1 << 0),
+       MFC_PERF_BOOST_MO       = (1 << 1),
+       MFC_PERF_BOOST_CPU      = (1 << 2),
+};
+
+void s5p_mfc_perf_boost_enable(struct s5p_mfc_dev *dev)
+{
+       struct s5p_mfc_platdata *pdata = dev->pdata;
+       struct s5p_mfc_qos_boost *qos_boost_table = pdata->qos_boost_table;
+       int i;
+
+       if (perf_boost_mode & MFC_PERF_BOOST_DVFS) {
+               if (pdata->mfc_freq_control)
+                       pm_qos_add_request(&dev->qos_req_mfc, PM_QOS_MFC_THROUGHPUT,
+                                       qos_boost_table->freq_mfc);
+               pm_qos_add_request(&dev->qos_req_int, PM_QOS_DEVICE_THROUGHPUT,
+                               qos_boost_table->freq_int);
+               pm_qos_add_request(&dev->qos_req_mif, PM_QOS_BUS_THROUGHPUT,
+                               qos_boost_table->freq_mif);
+               mfc_debug(3, "[QoS][perf_boost] DVFS mfc: %d, int:%d, mif:%d\n",
+                               qos_boost_table->freq_mfc, qos_boost_table->freq_int,
+                               qos_boost_table->freq_mif);
+       }
+
+#ifdef CONFIG_EXYNOS_BTS
+       if (perf_boost_mode & MFC_PERF_BOOST_MO) {
+               if (pdata->mo_control) {
+                       bts_update_scen(BS_MFC_UHD_10BIT, 1);
+                       mfc_debug(3, "[QoS][perf_boost] BTS(MO): UHD_10BIT\n");
+               }
+       }
+#endif
+
+       if (perf_boost_mode & MFC_PERF_BOOST_CPU) {
+               for (i = 0; i < qos_boost_table->num_cluster; i++) {
+                       pm_qos_add_request(&dev->qos_req_cluster[i], PM_QOS_CLUSTER0_FREQ_MIN + (i * 2),
+                                       qos_boost_table->freq_cluster[i]);
+                       mfc_debug(3, "[QoS][perf_boost] CPU cluster[%d]: %d\n",
+                                       i, qos_boost_table->freq_cluster[i]);
+               }
+       }
+}
+
+void s5p_mfc_perf_boost_disable(struct s5p_mfc_dev *dev)
+{
+       struct s5p_mfc_platdata *pdata = dev->pdata;
+       int i;
+
+       if (perf_boost_mode & MFC_PERF_BOOST_DVFS) {
+               if (pdata->mfc_freq_control)
+                       pm_qos_remove_request(&dev->qos_req_mfc);
+               pm_qos_remove_request(&dev->qos_req_int);
+               pm_qos_remove_request(&dev->qos_req_mif);
+               mfc_debug(3, "[QoS][perf_boost] DVFS off\n");
+       }
+
+#ifdef CONFIG_EXYNOS_BTS
+       if (perf_boost_mode & MFC_PERF_BOOST_MO) {
+               if (pdata->mo_control) {
+                       bts_update_scen(BS_MFC_UHD_10BIT, 0);
+                       mfc_debug(3, "[QoS][perf_boost] BTS(MO) off\n");
+               }
+       }
+#endif
+
+       if (perf_boost_mode & MFC_PERF_BOOST_CPU) {
+               for (i = 0; i < pdata->qos_boost_table->num_cluster; i++) {
+                       pm_qos_remove_request(&dev->qos_req_cluster[i]);
+                       mfc_debug(3, "[QoS][perf_boost] CPU cluster[%d] off\n", i);
+               }
+       }
+}
+
 static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
 {
        struct s5p_mfc_dev *dev = ctx->dev;
@@ -44,15 +118,6 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
                                PM_QOS_BUS_THROUGHPUT,
                                qos_table[idx].freq_mif);
 
-#ifdef CONFIG_ARM_EXYNOS_MP_CPUFREQ
-               pm_qos_add_request(&dev->qos_req_cluster1,
-                               PM_QOS_CLUSTER1_FREQ_MIN,
-                               qos_table[idx].freq_cpu);
-               pm_qos_add_request(&dev->qos_req_cluster0,
-                               PM_QOS_CLUSTER0_FREQ_MIN,
-                               qos_table[idx].freq_kfc);
-#endif
-
 #ifdef CONFIG_EXYNOS_BTS
                if (pdata->mo_control) {
                        bts_update_scen(BS_MFC_UHD_ENC60, qos_table[idx].mo_uhd_enc60_value);
@@ -84,13 +149,6 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
                pm_qos_update_request(&dev->qos_req_mif,
                                qos_table[idx].freq_mif);
 
-#ifdef CONFIG_ARM_EXYNOS_MP_CPUFREQ
-               pm_qos_update_request(&dev->qos_req_cluster1,
-                               qos_table[idx].freq_cpu);
-               pm_qos_update_request(&dev->qos_req_cluster0,
-                               qos_table[idx].freq_kfc);
-#endif
-
 #ifdef CONFIG_EXYNOS_BTS
                if (pdata->mo_control) {
                        bts_update_scen(BS_MFC_UHD_ENC60, qos_table[idx].mo_uhd_enc60_value);
@@ -119,11 +177,6 @@ static void mfc_qos_operate(struct s5p_mfc_ctx *ctx, int opr_type, int idx)
                pm_qos_remove_request(&dev->qos_req_int);
                pm_qos_remove_request(&dev->qos_req_mif);
 
-#ifdef CONFIG_ARM_EXYNOS_MP_CPUFREQ
-               pm_qos_remove_request(&dev->qos_req_cluster1);
-               pm_qos_remove_request(&dev->qos_req_cluster0);
-#endif
-
 #ifdef CONFIG_EXYNOS_BTS
                if (pdata->mo_control) {
                        bts_update_scen(BS_MFC_UHD_ENC60, 0);
@@ -425,6 +478,11 @@ void s5p_mfc_qos_on(struct s5p_mfc_ctx *ctx)
        struct bts_bw mfc_bw, mfc_bw_ctx;
 #endif
 
+       if (perf_boost_mode) {
+               mfc_info_ctx("[QoS][perf_boost] skip control\n");
+               return;
+       }
+
        list_for_each_entry(qos_ctx, &dev->qos_queue, qos_list)
                if (qos_ctx == ctx)
                        found = 1;
@@ -494,6 +552,11 @@ void s5p_mfc_qos_off(struct s5p_mfc_ctx *ctx)
        struct bts_bw mfc_bw, mfc_bw_ctx;
 #endif
 
+       if (perf_boost_mode) {
+               mfc_info_ctx("[QoS][perf_boost] skip control\n");
+               return;
+       }
+
        if (list_empty(&dev->qos_queue)) {
                if (atomic_read(&dev->qos_req_cur) != 0) {
                        mfc_err_ctx("MFC request count is wrong!\n");
index b8e13660040f47b5c2b8c9c0da2d99d0196dbacb..9254657b7720431aa9022645d02964bd5aa3e07e 100644 (file)
 #define MFC_QOS_WEIGHT_NUM_OF_TILE     75
 
 #ifdef CONFIG_MFC_USE_BUS_DEVFREQ
+void s5p_mfc_perf_boost_enable(struct s5p_mfc_dev *dev);
+void s5p_mfc_perf_boost_disable(struct s5p_mfc_dev *dev);
 void s5p_mfc_qos_on(struct s5p_mfc_ctx *ctx);
 void s5p_mfc_qos_off(struct s5p_mfc_ctx *ctx);
 #else
-#define s5p_mfc_qos_on(ctx)    do {} while (0)
-#define s5p_mfc_qos_off(ctx)   do {} while (0)
+#define s5p_mfc_perf_boost_enable(dev) do {} while (0)
+#define s5p_mfc_perf_boost_disable(dev)        do {} while (0)
+#define s5p_mfc_qos_on(ctx)            do {} while (0)
+#define s5p_mfc_qos_off(ctx)           do {} while (0)
 #endif
 
 void s5p_mfc_qos_update_framerate(struct s5p_mfc_ctx *ctx);
index 8bab5649ebfd3177130cd4d65c5fb3d2843cb079..17a1e8782b57ca7b3753d09ad56f72eeaf616435 100644 (file)
@@ -156,6 +156,8 @@ static void mfc_display_state(struct s5p_mfc_dev *dev)
                        dev->hwlock.bits, dev->hwlock.dev,
                        dev->curr_ctx, dev->curr_ctx_is_drm,
                        dev->preempt_ctx, s5p_mfc_get_bits(&dev->work_bits));
+       pr_err("options debug_level:%d, debug_mode:%d, mmcache:%d, perf_boost:%d\n",
+                       debug_level, dev->pdata->debug_mode, dev->mmcache.is_on_status, perf_boost_mode);
        pr_err("NAL-Q state:%d, exception:%d, in_exe_cnt: %d, out_exe_cnt: %d\n",
                        nal_q_handle->nal_q_state, nal_q_handle->nal_q_exception,
                        nal_q_handle->nal_q_in_handle->in_exe_count,