summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/media/video/msm-vidc.txt4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-vidc.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-vidc.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/sdm630.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi1
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c16
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c58
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c10
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_res_parse.c9
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_resources.h3
-rw-r--r--drivers/thermal/msm-tsens.c2
-rw-r--r--include/linux/sched/sysctl.h8
-rw-r--r--include/uapi/linux/v4l2-controls.h3
-rw-r--r--kernel/sched/hmp.c4
-rw-r--r--kernel/sched/sched.h4
-rw-r--r--kernel/sysctl.c5
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",