diff options
| -rw-r--r-- | Documentation/devicetree/bindings/media/video/msm-vidc.txt | 4 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm8996-vidc.dtsi | 3 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm8998-vidc.dtsi | 3 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/sdm630.dtsi | 3 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/sdm660.dtsi | 1 | ||||
| -rw-r--r-- | drivers/media/platform/msm/vidc/msm_vdec.c | 16 | ||||
| -rw-r--r-- | drivers/media/platform/msm/vidc/msm_venc.c | 58 | ||||
| -rw-r--r-- | drivers/media/platform/msm/vidc/msm_vidc.c | 10 | ||||
| -rw-r--r-- | drivers/media/platform/msm/vidc/msm_vidc_res_parse.c | 9 | ||||
| -rw-r--r-- | drivers/media/platform/msm/vidc/msm_vidc_resources.h | 3 | ||||
| -rw-r--r-- | drivers/thermal/msm-tsens.c | 2 | ||||
| -rw-r--r-- | include/linux/sched/sysctl.h | 8 | ||||
| -rw-r--r-- | include/uapi/linux/v4l2-controls.h | 3 | ||||
| -rw-r--r-- | kernel/sched/hmp.c | 4 | ||||
| -rw-r--r-- | kernel/sched/sched.h | 4 | ||||
| -rw-r--r-- | kernel/sysctl.c | 5 |
16 files changed, 111 insertions, 25 deletions
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt index 50b9b1ac8704..6ca0ac31a581 100644 --- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt +++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt @@ -132,6 +132,9 @@ value is typically max(latencies of every cluster at all power levels) + 1 memory, performance etc. - qcom,debug-timeout = A bool indicating that FW errors such as SYS_ERROR, SESSION_ERROR and timeouts will be treated as Fatal. +- qcom,power-conf = Indicates the value at which or beyond, a video session + is configured in low power mode to have power benefits. Value is defined + interms of HxW of the video session beyond which power benefit is desired. [Second level nodes] Context Banks @@ -226,6 +229,7 @@ Example: qcom,qdss-presets = <0xFC307000 0x1000>, <0xFC322000 0x1000>; qcom,max-hw-load = <1224450>; /* 4k @ 30 + 1080p @ 30*/ + qcom,power-conf = <8294400>; /* WxH - 3840*2160 */ qcom,never-unload-fw; clock-names = "foo_clk", "bar_clk", "baz_clk"; qcom,clock-configs = <0x3 0x1 0x0>; diff --git a/arch/arm/boot/dts/qcom/msm8996-vidc.dtsi b/arch/arm/boot/dts/qcom/msm8996-vidc.dtsi index 3ed55f9d8671..5ac31e3dd0cb 100644 --- a/arch/arm/boot/dts/qcom/msm8996-vidc.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-vidc.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -32,6 +32,7 @@ <0x0818C000 0x2000>, <0x0818E000 0x2000>; qcom,max-hw-load = <2563200>; /* Full 4k @ 60 + 1080p @ 60 */ + qcom,power-conf = <8294400>; /* WxH - 3840*2160 */ qcom,firmware-name = "venus"; qcom,imem-size = <524288>; /* 512 kB */ qcom,never-unload-fw; diff --git a/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi b/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi index e449d81a25e5..3e7cacac9d43 100644 --- a/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-vidc.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -39,6 +39,7 @@ qcom,imem-size = <524288>; /* 512 kB */ qcom,max-hw-load = <2563200>; /* Full 4k @ 60 + 1080p @ 60 */ + qcom,power-conf = <8294400>; /* WxH - 3840*2160 */ qcom,load-freq-tbl = /* Encoders */ <972000 465000000 0x55555555>, /* 4k UHD @ 30 */ diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi index 47b40dc713dc..38bb266bcf7d 100644 --- a/arch/arm/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630.dtsi @@ -483,6 +483,8 @@ reg-names = "tsens_physical"; interrupts = <0 184 0>, <0 430 0>; interrupt-names = "tsens-upper-lower", "tsens-critical"; + qcom,client-id = <0 1 2 3 4 5 6 7 8 9 10 11>; + qcom,sensor-id = <0 8 10 4 5 6 7 9 2 1 3 11>; qcom,sensors = <12>; }; @@ -935,6 +937,7 @@ qcom,use-ipa-tethering-bridge; qcom,modem-cfg-emb-pipe-flt; qcom,ipa-wdi2; + qcom,use-dma-zone; qcom,msm-bus,name = "ipa"; qcom,msm-bus,num-cases = <4>; qcom,msm-bus,num-paths = <2>; diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index 2a7ef9dcd4cd..f35619d2a21e 100644 --- a/arch/arm/boot/dts/qcom/sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660.dtsi @@ -1388,6 +1388,7 @@ qcom,use-ipa-tethering-bridge; qcom,modem-cfg-emb-pipe-flt; qcom,ipa-wdi2; + qcom,use-dma-zone; qcom,msm-bus,name = "ipa"; qcom,msm-bus,num-cases = <4>; qcom,msm-bus,num-paths = <2>; diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index f958cf13f1e3..a20252f08f44 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1782,6 +1782,7 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count) struct msm_vidc_inst *inst; int rc = 0; struct hfi_device *hdev; + struct vb2_buf_entry *temp, *next; if (!q || !q->drv_priv) { dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; @@ -1824,6 +1825,19 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count) } stream_start_failed: + if (rc) { + mutex_lock(&inst->pendingq.lock); + list_for_each_entry_safe(temp, next, &inst->pendingq.list, + list) { + if (temp->vb->type == q->type) { + vb2_buffer_done(temp->vb, + VB2_BUF_STATE_QUEUED); + list_del(&temp->list); + kfree(temp); + } + } + mutex_unlock(&inst->pendingq.lock); + } return rc; } diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index 6127c03df581..c909511db251 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1048,9 +1048,9 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE, .name = "Set Encoder performance mode", .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY, + .minimum = V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT, .maximum = V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE, - .default_value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY, + .default_value = V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT, .step = 1, .qmenu = NULL, }, @@ -1666,9 +1666,10 @@ static int msm_venc_toggle_hier_p(struct msm_vidc_inst *inst, int layers) static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst) { - u32 rc = 0; - u32 prop_id = 0, power_save_min = 0, power_save_max = 0, inst_load = 0; + u32 rc = 0, height = 0, width = 0; + u32 prop_id = 0, hq_max = 0, power_conf = 0, inst_load = 0; void *pdata = NULL; + bool set_by_client = false, enable_low_power = false; struct hfi_device *hdev = NULL; enum hal_perf_mode venc_mode; enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD | @@ -1679,20 +1680,38 @@ static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst) return -EINVAL; } + hdev = inst->core->device; inst_load = msm_comm_get_inst_load(inst, quirks); - power_save_min = inst->capability.mbs_per_sec_power_save.min; - power_save_max = inst->capability.mbs_per_sec_power_save.max; + hq_max = inst->capability.mbs_per_sec.max; + power_conf = inst->core->resources.power_conf; + height = inst->prop.height[CAPTURE_PORT]; + width = inst->prop.width[CAPTURE_PORT]; - if (!power_save_min || !power_save_max) - return rc; + switch (msm_comm_g_ctrl_for_id(inst, + V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE)) { + case V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY: + case V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE: + set_by_client = true; + break; + } - hdev = inst->core->device; - if (inst_load >= power_save_min && inst_load <= power_save_max) { + if (inst_load > hq_max) { + dprintk(VIDC_INFO, "Setting low power w.r.t core limitation\n"); + enable_low_power = true; + } else if (!set_by_client) { + if (power_conf && width * height >= power_conf) { + dprintk(VIDC_INFO, + "Setting low power w.r.t system power recommendation\n"); + enable_low_power = true; + } + } + + if (enable_low_power) { prop_id = HAL_CONFIG_VENC_PERF_MODE; venc_mode = HAL_PERF_MODE_POWER_SAVE; pdata = &venc_mode; rc = call_hfi_op(hdev, session_set_property, - (void *)inst->session, prop_id, pdata); + (void *)inst->session, prop_id, pdata); if (rc) { dprintk(VIDC_ERR, "%s: Failed to set power save mode for inst: %pK\n", @@ -1758,6 +1777,7 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count) { struct msm_vidc_inst *inst; int rc = 0; + struct vb2_buf_entry *temp, *next; if (!q || !q->drv_priv) { dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; @@ -1795,6 +1815,19 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count) } stream_start_failed: + if (rc) { + mutex_lock(&inst->pendingq.lock); + list_for_each_entry_safe(temp, next, &inst->pendingq.list, + list) { + if (temp->vb->type == q->type) { + vb2_buffer_done(temp->vb, + VB2_BUF_STATE_QUEUED); + list_del(&temp->list); + kfree(temp); + } + } + mutex_unlock(&inst->pendingq.lock); + } return rc; } @@ -3143,7 +3176,6 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; } pdata = &venc_mode; - break; case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS: if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC) { diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index b36e3739e43b..662dcf7c8303 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -720,6 +720,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type) struct buffer_info *bi, *dummy; struct v4l2_buffer buffer_info; struct v4l2_plane plane[VIDEO_MAX_PLANES]; + struct vb2_buf_entry *temp, *next; int i, rc = 0; if (!inst) @@ -807,6 +808,15 @@ free_and_unmap: } } mutex_unlock(&inst->registeredbufs.lock); + + mutex_lock(&inst->pendingq.lock); + list_for_each_entry_safe(temp, next, &inst->pendingq.list, list) { + if (temp->vb->type == buffer_type) { + list_del(&temp->list); + kfree(temp); + } + } + mutex_unlock(&inst->pendingq.lock); return rc; } EXPORT_SYMBOL(msm_vidc_release_buffers); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c index a3080be8cd7a..022c776a6096 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1084,6 +1084,13 @@ int read_platform_resources_from_dt( goto err_load_max_hw_load; } + rc = of_property_read_u32(pdev->dev.of_node, "qcom,power-conf", + &res->power_conf); + if (rc) { + dprintk(VIDC_DBG, + "Failed to read power configuration: %d\n", rc); + } + rc = msm_vidc_populate_legacy_context_bank(res); if (rc) { dprintk(VIDC_ERR, diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h index 734586a3f76c..03b31d7fd9d1 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_resources.h +++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -173,6 +173,7 @@ struct msm_vidc_platform_resources { uint32_t imem_size; enum imem_type imem_type; uint32_t max_load; + uint32_t power_conf; struct platform_device *pdev; struct regulator_set regulator_set; struct clock_set clock_set; diff --git a/drivers/thermal/msm-tsens.c b/drivers/thermal/msm-tsens.c index 82a8e4e200ba..d59b9736c570 100644 --- a/drivers/thermal/msm-tsens.c +++ b/drivers/thermal/msm-tsens.c @@ -364,6 +364,7 @@ static int32_t get_tsens_sensor_for_client_id(struct tsens_tm_device *tmdev, if (!strcmp(id->compatible, "qcom,msm8996-tsens") || (!strcmp(id->compatible, "qcom,msm8998-tsens")) || (!strcmp(id->compatible, "qcom,sdm660-tsens")) || + (!strcmp(id->compatible, "qcom,sdm630-tsens")) || (!strcmp(id->compatible, "qcom,msmhamster-tsens"))) { while (i < tmdev->tsens_num_sensor && !id_found) { if (tmdev->sensor[i].sensor_client_id == @@ -494,6 +495,7 @@ int tsens_get_hw_id_mapping(int thermal_sensor_num, int *sensor_client_id) if (!strcmp(id->compatible, "qcom,msm8996-tsens") || (!strcmp(id->compatible, "qcom,msm8998-tsens")) || (!strcmp(id->compatible, "qcom,sdm660-tsens")) || + (!strcmp(id->compatible, "qcom,sdm630-tsens")) || (!strcmp(id->compatible, "qcom,msmhamster-tsens"))) { /* Assign client id's that is used to get the * controller and hw_sensor details diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 418eb97110a3..ef8a092251aa 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -45,6 +45,14 @@ extern unsigned int sysctl_sched_initial_task_util; extern unsigned int sysctl_sched_cstate_aware; #ifdef CONFIG_SCHED_HMP + +enum freq_reporting_policy { + FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK, + FREQ_REPORT_CPU_LOAD, + FREQ_REPORT_TOP_TASK, + FREQ_REPORT_INVALID_POLICY +}; + extern int sysctl_sched_freq_inc_notify; extern int sysctl_sched_freq_dec_notify; extern unsigned int sysctl_sched_freq_reporting_policy; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 8fdf57504ab6..c8653a9f0e9e 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -1058,6 +1058,9 @@ enum vl42_mpeg_vidc_video_h264_svc_nal { (V4L2_CID_MPEG_MSM_VIDC_BASE + 68) enum v4l2_mpeg_vidc_video_perf_mode { +#define V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT \ + V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT + V4L2_MPEG_VIDC_VIDEO_PERF_UNINIT = 0, V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY = 1, V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE = 2 }; diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index 1c0defb34ae1..6379de764236 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -2787,7 +2787,7 @@ static u64 update_task_demand(struct task_struct *p, struct rq *rq, } static inline void -update_task_burst(struct task_struct *p, struct rq *rq, int event, int runtime) +update_task_burst(struct task_struct *p, struct rq *rq, int event, u64 runtime) { /* * update_task_demand() has checks for idle task and @@ -3108,7 +3108,7 @@ static inline u64 freq_policy_load(struct rq *rq, u64 load) case FREQ_REPORT_CPU_LOAD: break; default: - WARN_ON_ONCE(1); + break; } return load; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index a91f4cc1d8d3..360e298398fb 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1071,10 +1071,6 @@ enum sched_boost_policy { #define WINDOW_STATS_AVG 3 #define WINDOW_STATS_INVALID_POLICY 4 -#define FREQ_REPORT_MAX_CPU_LOAD_TOP_TASK 0 -#define FREQ_REPORT_CPU_LOAD 1 -#define FREQ_REPORT_TOP_TASK 2 - #define SCHED_UPMIGRATE_MIN_NICE 15 #define EXITING_TASK_MARKER 0xdeaddead diff --git a/kernel/sysctl.c b/kernel/sysctl.c index a2a87c3ad44e..7112dc54d88e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -133,6 +133,7 @@ static int ten_thousand = 10000; #endif #ifdef CONFIG_SCHED_HMP static int one_thousand = 1000; +static int max_freq_reporting_policy = FREQ_REPORT_INVALID_POLICY - 1; #endif /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */ @@ -297,6 +298,7 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = &zero, + .extra2 = &max_freq_reporting_policy, }, { .procname = "sched_freq_inc_notify", @@ -591,7 +593,8 @@ static struct ctl_table kern_table[] = { .data = &sysctl_sched_time_avg, .maxlen = sizeof(unsigned int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_dointvec_minmax, + .extra1 = &one, }, { .procname = "sched_shares_window_ns", |
