summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhding3 <haitao.ding@intel.com>2015-08-24 18:47:45 -0700
committerhding3 <haitao.ding@intel.com>2015-08-25 13:57:36 +0800
commitca71cf6ceda8b86c2d31996a224414df4b10d4b0 (patch)
treea64f649ad1e3f050101088fca3aea524382013da
parentc80a1e42fdee40827631616e21a5b9ef0c90b2f9 (diff)
downloadx86_64-android-x86_64-fugu-3.10-marshmallow.tar.gz
BUG: 22602467 Replace the legacy ospm_apm_power_down_vsp with the new framework/power_island_put Add recovery logic when VSP hang Change-Id: I03bafc9d9db315aae7ad53638ebd643b1830f4d5 Signed-off-by: hding3 <haitao.ding@intel.com>
-rwxr-xr-xdrivers/external_drivers/intel_media/display/tng/drv/ospm/pwr_mgmt.c13
-rw-r--r--drivers/external_drivers/intel_media/video/common/psb_cmdbuf.c4
-rwxr-xr-xdrivers/external_drivers/intel_media/video/vsp/vsp.c97
-rw-r--r--drivers/external_drivers/intel_media/video/vsp/vsp_fw.h5
4 files changed, 87 insertions, 32 deletions
diff --git a/drivers/external_drivers/intel_media/display/tng/drv/ospm/pwr_mgmt.c b/drivers/external_drivers/intel_media/display/tng/drv/ospm/pwr_mgmt.c
index ad4c0803457d..2b124cb8e3c7 100755
--- a/drivers/external_drivers/intel_media/display/tng/drv/ospm/pwr_mgmt.c
+++ b/drivers/external_drivers/intel_media/display/tng/drv/ospm/pwr_mgmt.c
@@ -811,6 +811,7 @@ void ospm_apm_power_down_vsp(struct drm_device *dev)
struct ospm_power_island *p_island;
struct drm_psb_private *dev_priv = dev->dev_private;
struct vsp_private *vsp_priv = dev_priv->vsp_private;
+ int island_ref;
PSB_DEBUG_PM("Power down VPP...\n");
p_island = get_island_ptr(OSPM_VIDEO_VPP_ISLAND);
@@ -825,9 +826,10 @@ void ospm_apm_power_down_vsp(struct drm_device *dev)
if (!ospm_power_is_hw_on(OSPM_VIDEO_VPP_ISLAND))
goto out;
- if (atomic_read(&p_island->ref_count))
+ island_ref = atomic_read(&p_island->ref_count);
+ if (island_ref)
PSB_DEBUG_PM("VPP ref_count has been set(%d), bypass\n",
- atomic_read(&p_island->ref_count));
+ island_ref);
if (vsp_priv->vsp_cmd_num > 0) {
VSP_DEBUG("command in VSP, by pass\n");
@@ -847,11 +849,16 @@ void ospm_apm_power_down_vsp(struct drm_device *dev)
/* handle the dependency */
if (p_island->p_dependency) {
/* Power down dependent island */
- power_down_island(p_island->p_dependency);
+ do {
+ power_down_island(p_island->p_dependency);
+ island_ref--;
+ } while (island_ref);
}
if (!any_island_on()) {
PSB_DEBUG_PM("Suspending PCI\n");
+ pm_qos_add_request(&dev_priv->s0ix_qos,
+ PM_QOS_CPU_DMA_LATENCY, CSTATE_EXIT_LATENCY_S0i1 - 1);
pm_runtime_put(&g_ospm_data->dev->pdev->dev);
wake_unlock(&dev_priv->ospm_wake_lock);
}
diff --git a/drivers/external_drivers/intel_media/video/common/psb_cmdbuf.c b/drivers/external_drivers/intel_media/video/common/psb_cmdbuf.c
index 65579de79beb..3943c845168c 100644
--- a/drivers/external_drivers/intel_media/video/common/psb_cmdbuf.c
+++ b/drivers/external_drivers/intel_media/video/common/psb_cmdbuf.c
@@ -836,8 +836,10 @@ static int psb_handle_copyback(struct drm_device *dev,
}
if (__copy_to_user(vbuf->user_val_arg,
- &arg, sizeof(arg)))
+ &arg, sizeof(arg))) {
err = -EFAULT;
+ DRM_ERROR("call __copy_to_user() function error!\n");
+ }
if (arg.ret)
break;
diff --git a/drivers/external_drivers/intel_media/video/vsp/vsp.c b/drivers/external_drivers/intel_media/video/vsp/vsp.c
index 3a00fc9bc173..15b54043baac 100755
--- a/drivers/external_drivers/intel_media/video/vsp/vsp.c
+++ b/drivers/external_drivers/intel_media/video/vsp/vsp.c
@@ -73,6 +73,43 @@ static inline void psb_clflush(void *addr)
__asm__ __volatile__("wbinvd ");
}
+
+static inline void force_power_down_vsp(void)
+{
+ int count = 0;
+ VSP_DEBUG("Force to power down VSP\n");
+ while (is_island_on(OSPM_VIDEO_VPP_ISLAND) && (count < 255)) {
+ count++;
+ VSP_DEBUG("The VSP is on, power down it, tries %d\n", count);
+ power_island_put(OSPM_VIDEO_VPP_ISLAND);
+ }
+ VSP_DEBUG("The VSP is off now (tried %d times)\n", count);
+}
+
+static inline void power_down_vsp(void)
+{
+ VSP_DEBUG("Try to power down VSP\n");
+
+ if (is_island_on(OSPM_VIDEO_VPP_ISLAND)) {
+ VSP_DEBUG("The VSP is on, power down it\n");
+ power_island_put(OSPM_VIDEO_VPP_ISLAND);
+ } else
+ VSP_DEBUG("The VSP is already off\n");
+}
+
+static inline void power_up_vsp(void)
+{
+ VSP_DEBUG("Try to power up VSP\n");
+
+ if (is_island_on(OSPM_VIDEO_VPP_ISLAND))
+ VSP_DEBUG("The VSP is alraedy on\n");
+ else {
+ VSP_DEBUG("The VSP is off, power up it\n");
+ power_island_get(OSPM_VIDEO_VPP_ISLAND);
+ }
+}
+
+
int vsp_handle_response(struct drm_psb_private *dev_priv)
{
struct vsp_private *vsp_priv = dev_priv->vsp_private;
@@ -311,8 +348,13 @@ int vsp_cmdbuf_vpp(struct drm_file *priv,
/* If VSP timeout, don't send cmd to hardware anymore */
if (vsp_priv->vsp_state == VSP_STATE_HANG) {
- DRM_ERROR("The VSP is hang abnormally!");
- return -EFAULT;
+ DRM_ERROR("The VSP is hang abnormally, try to reset vsp hardware!\n");
+
+ VSP_DEBUG("Force state to DOWN to force power down\n");
+ vsp_priv->ctrl->entry_kind = vsp_exit;
+ vsp_priv->vsp_state = VSP_STATE_DOWN;
+ force_power_down_vsp();
+ //return -EFAULT;
}
memset(&cmd_kmap, 0, sizeof(cmd_kmap));
@@ -358,8 +400,9 @@ int vsp_cmdbuf_vpp(struct drm_file *priv,
if (drm_vsp_vpp_batch_cmd == 0)
vsp_priv->force_flush_cmd = 1;
- if (vsp_priv->vsp_state == VSP_STATE_IDLE)
- ospm_apm_power_down_vsp(dev);
+ if ((drm_vsp_pmpolicy != PSB_PMPOLICY_NOPM) &&
+ (vsp_priv->vsp_state == VSP_STATE_IDLE))
+ power_down_vsp();
if (vsp_priv->acc_num_cmd >= 1 || vsp_priv->force_flush_cmd != 0
|| vsp_priv->delayed_burst_cnt > 0) {
@@ -1108,7 +1151,7 @@ int vsp_new_context(struct drm_device *dev, struct file *filp, int ctx_type)
mutex_unlock(&vsp_priv->vsp_mutex);
VSP_DEBUG("context_vp8_num %d, context_vpp_num %d\n",
- vsp_priv->context_vp8_num, vsp_priv->context_vpp_num);
+ vsp_priv->context_vp8_num, vsp_priv->context_vpp_num);
return ret;
}
@@ -1116,7 +1159,6 @@ void vsp_rm_context(struct drm_device *dev, struct file *filp, int ctx_type)
{
struct drm_psb_private *dev_priv = dev->dev_private;
struct vsp_private *vsp_priv = dev_priv->vsp_private;
- bool ret = true;
int count = 0;
struct vss_command_t *cur_cmd;
bool tmp = true;
@@ -1153,11 +1195,10 @@ void vsp_rm_context(struct drm_device *dev, struct file *filp, int ctx_type)
VSP_DEBUG("ctx_type=%d\n", ctx_type);
+ /* power on the VSP hardware to write registers */
+ power_up_vsp();
+
if (VAEntrypointEncSlice == ctx_type && filp != vsp_priv->vp8_filp[3]) {
- /* power on again to send VssGenDestroyContext to firmware */
- if (power_island_get(OSPM_VIDEO_VPP_ISLAND) == false) {
- tmp = -EBUSY;
- }
if (vsp_priv->vsp_state == VSP_STATE_SUSPEND) {
tmp = vsp_resume_function(dev_priv);
VSP_DEBUG("The VSP is on suspend, send resume!\n");
@@ -1217,26 +1258,26 @@ void vsp_rm_context(struct drm_device *dev, struct file *filp, int ctx_type)
if (vsp_priv->context_vp8_num > 0 || vsp_priv->context_vpp_num > 0) {
VSP_DEBUG("context_vp8_num %d, context_vpp_num %d\n",
vsp_priv->context_vp8_num, vsp_priv->context_vpp_num);
+
+ power_down_vsp();
mutex_unlock(&vsp_priv->vsp_mutex);
return;
}
vsp_priv->ctrl->entry_kind = vsp_exit;
- mutex_unlock(&vsp_priv->vsp_mutex);
- VSP_DEBUG("After mutex_unlock, start to power off VSP!\n");
+ VSP_DEBUG("No context now, set state to DOWN to force power down\n");
+ PSB_UDELAY(800);
+
/* in case of power mode 0, HW always active,
* * in case got no response from FW, vsp_state=hang but could not be powered off,
* * force state to down */
vsp_priv->vsp_state = VSP_STATE_DOWN;
- ospm_apm_power_down_vsp(dev);
+ force_power_down_vsp();
vsp_priv->vsp_state = VSP_STATE_DOWN;
- if (ret == false)
- PSB_DEBUG_PM("Couldn't power down VSP!");
- else
- PSB_DEBUG_PM("VSP: OK. Power down the HW!\n");
-
+ mutex_unlock(&vsp_priv->vsp_mutex);
+ VSP_DEBUG("vsp_rm_context is successful\n");
/* FIXME: frequency should change */
VSP_PERF("the total time spend on VSP is %llu ms\n",
div_u64(vsp_priv->vss_cc_acc, 200 * 1000));
@@ -1376,15 +1417,17 @@ void vsp_irq_task(struct work_struct *work)
sequence, vsp_priv->current_sequence);
}
- if (vsp_priv->vsp_state == VSP_STATE_IDLE) {
- if (vsp_priv->ctrl->cmd_rd == vsp_priv->ctrl->cmd_wr)
- ospm_apm_power_down_vsp(dev);
- else {
- while (ospm_power_is_hw_on(OSPM_VIDEO_VPP_ISLAND))
- ospm_apm_power_down_vsp(dev);
- VSP_DEBUG("successfully power down VSP\n");
- power_island_get(OSPM_VIDEO_VPP_ISLAND);
- vsp_resume_function(dev_priv);
+ if (drm_vsp_pmpolicy != PSB_PMPOLICY_NOPM){
+ if (vsp_priv->vsp_state == VSP_STATE_IDLE) {
+ if (vsp_priv->ctrl->cmd_rd == vsp_priv->ctrl->cmd_wr)
+ power_down_vsp();
+ else {
+ force_power_down_vsp();
+
+ VSP_DEBUG("Now power up VSP again to resume\n");
+ power_up_vsp();
+ vsp_resume_function(dev_priv);
+ }
}
}
mutex_unlock(&vsp_priv->vsp_mutex);
diff --git a/drivers/external_drivers/intel_media/video/vsp/vsp_fw.h b/drivers/external_drivers/intel_media/video/vsp/vsp_fw.h
index 064a0531dc65..89b888929deb 100644
--- a/drivers/external_drivers/intel_media/video/vsp/vsp_fw.h
+++ b/drivers/external_drivers/intel_media/video/vsp/vsp_fw.h
@@ -578,6 +578,8 @@ struct VssVp8encSequenceParameterBuffer {
uint32_t cyclic_intra_refresh;
uint32_t concatenate_partitions;
uint32_t recon_buffer_mode;
+ uint32_t generate_skip_frames;
+ uint32_t max_num_dropped_frames;
uint32_t ts_number_layers;
uint32_t ts_target_bitrate[3];
uint32_t ts_rate_decimator[3];
@@ -596,8 +598,9 @@ struct VssVp8encEncodedFrame {
uint32_t quantizer[4];
uint32_t frame_flags;
uint32_t partition_id;
- uint32_t buffer_level;
+ uint32_t buffer_level[3];
uint32_t quality;
+ uint32_t overflow_bytes;
uint32_t surfaceId_of_ref_frame[4];
uint32_t reserved[15];
uint32_t coded_data[1];