summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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
6 files changed, 82 insertions, 16 deletions
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