Add check reset function for msvdx firmware
authorDaniel Charles <daniel.charles@intel.com>
Fri, 16 Mar 2012 15:39:37 +0000 (08:39 -0700)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 3 Jul 2012 09:30:35 +0000 (12:30 +0300)
When fence lockup is triggered by the msvdx firmware, it reaches an
unrecoverable state that requires a firmware reload so that it can
continue operating without resetting the device.

This scenario is seen when playing some corrupted media clips which
cause the media stack to fail.

Once the firmware is reloaded it will continue decoding when possible
and next attempts to play will be successful

Issue: ANDROID-2031
Reviewed-by: Sean V Kelley <sean.v.kelley@intel.com>
Signed-off-by: Daniel Charles <daniel.charles@intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
drivers/staging/mrst/drv/psb_sgx.c
drivers/staging/mrst/imgv/psb_msvdx.c
drivers/staging/mrst/imgv/psb_msvdx.h

index d801ea5..fe54258 100644 (file)
@@ -746,6 +746,7 @@ int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
                return ret;
 
        if (arg->engine == PSB_ENGINE_VIDEO) {
+               psb_msvdx_check_reset_fw(dev);
                if (!ospm_power_using_hw_begin(OSPM_VIDEO_DEC_ISLAND, true))
                        return -EBUSY;
        } else if (arg->engine == LNC_ENGINE_ENCODE) {
index c21969c..dd5536a 100644 (file)
@@ -1436,3 +1436,23 @@ int psb_msvdx_restore_context(struct drm_device *dev)
 {
        return 0;
 }
+
+int psb_msvdx_check_reset_fw(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
+       unsigned long irq_flags;
+
+       spin_lock_irqsave(&msvdx_priv->msvdx_lock, irq_flags);
+
+       /* handling fw upload here if required */
+       /* power off first, then hw_begin will power up/upload FW correctly */
+       if (msvdx_priv->msvdx_needs_reset & MSVDX_RESET_NEEDS_REUPLOAD_FW) {
+               msvdx_priv->msvdx_needs_reset &= ~MSVDX_RESET_NEEDS_REUPLOAD_FW;
+               ospm_power_island_down(OSPM_VIDEO_DEC_ISLAND);
+       }
+
+       spin_unlock_irqrestore(&msvdx_priv->msvdx_lock, irq_flags);
+
+       return 0;
+}
index 45fee69..b7c1002 100644 (file)
@@ -99,6 +99,7 @@ int psb_cmdbuf_video(struct drm_file *priv,
                     struct psb_ttm_fence_rep *fence_arg);
 int psb_msvdx_save_context(struct drm_device *dev);
 int psb_msvdx_restore_context(struct drm_device *dev);
+int psb_msvdx_check_reset_fw(struct drm_device *dev);
 
 bool
 psb_host_second_pass(struct drm_device *dev,