From 076640ef959d715064823ea12ac2ad9eb72cd93e Mon Sep 17 00:00:00 2001 From: Ayoung Sim Date: Fri, 8 Jun 2018 11:23:55 +0900 Subject: [PATCH] [COMMON] media: mfc: DRV4.0: support performance boost mode This mode should be used only for test and user should set before MFC start(open). Change-Id: I752d77334227f49e485604d2979aa965c8463522 Signed-off-by: Ayoung Sim --- drivers/media/platform/exynos/mfc/s5p_mfc.c | 25 ++++- .../platform/exynos/mfc/s5p_mfc_data_struct.h | 18 ++- .../media/platform/exynos/mfc/s5p_mfc_debug.h | 1 + .../platform/exynos/mfc/s5p_mfc_debugfs.c | 10 ++ .../media/platform/exynos/mfc/s5p_mfc_qos.c | 105 ++++++++++++++---- .../media/platform/exynos/mfc/s5p_mfc_qos.h | 8 +- .../platform/exynos/mfc/s5p_mfc_watchdog.c | 2 + 7 files changed, 138 insertions(+), 31 deletions(-) diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc.c b/drivers/media/platform/exynos/mfc/s5p_mfc.c index e458dda19962..c34e0fc8f6aa 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc.c @@ -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 } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h index 1d238b533f41..89c78f1b84c1 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_data_struct.h @@ -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; diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h index 4d16ebcc330f..f6bd7f1e2e18 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debug.h @@ -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 { \ diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c b/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c index 5341b4995130..18d2c136ce98 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_debugfs.c @@ -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); } diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c index 66e907118568..df0c2466599f 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.c @@ -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"); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.h b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.h index b8e13660040f..9254657b7720 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_qos.h +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_qos.h @@ -36,11 +36,15 @@ #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); diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c b/drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c index 8bab5649ebfd..17a1e8782b57 100644 --- a/drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c +++ b/drivers/media/platform/exynos/mfc/s5p_mfc_watchdog.c @@ -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, -- 2.20.1