Video: worked around the random CTS failures with AVC decoding.
Bug: 37283516, 62788295, 38138788, 32717946
BZ: IMINAN-51520, IMINAN-51500, IMINAN-51528
When running CTS cases testOtherH264ImageReader or DecodeAccuracyTest,
randomly some bytes of the decoded U/V couldn't be flushed into system
memory from SLC (system level cache). So worked around this issue by
disabling SLC for video decoder for the specific AVC clips/streams.
Need to check whether it's video decoder hardware issue or not.
Change-Id: If44d8c112a88652858b588c4e62fcd25b1ba3ce6
Signed-off-by: Austin Hu <austin.hu@intel.com>
diff --git a/drivers/staging/imgtec/intel/display/tng/drv/ospm/video_ospm.c b/drivers/staging/imgtec/intel/display/tng/drv/ospm/video_ospm.c
index 9c1aaae..4f3e23a 100644
--- a/drivers/staging/imgtec/intel/display/tng/drv/ospm/video_ospm.c
+++ b/drivers/staging/imgtec/intel/display/tng/drv/ospm/video_ospm.c
@@ -160,7 +160,8 @@
struct drm_psb_private *dev_priv = psb_priv(dev);
struct msvdx_private *msvdx_priv = dev_priv->msvdx_private;
- if (atomic_read(&msvdx_priv->vc1_workaround_ctx)) {
+ if (!(msvdx_priv->msvdx_ctx->ctx_type & VA_RT_FORMAT_PROTECTED) &&
+ atomic_read(&msvdx_priv->slc_workaround_ctx)) {
uint32_t reg, data;
/* soc.gfx_wrapper.gbypassenable_sw = 1 */
diff --git a/drivers/staging/imgtec/intel/video/common/psb_ttm_glue.c b/drivers/staging/imgtec/intel/video/common/psb_ttm_glue.c
index 576f270..5ee6d39 100644
--- a/drivers/staging/imgtec/intel/video/common/psb_ttm_glue.c
+++ b/drivers/staging/imgtec/intel/video/common/psb_ttm_glue.c
@@ -50,8 +50,15 @@
extern int sepapp_drm_playback(bool ied_status);
static int ied_enabled;
-static void ann_rm_workaround_ctx(struct drm_psb_private *dev_priv, uint64_t ctx_type);
-static void ann_add_workaround_ctx(struct drm_psb_private *dev_priv, uint64_t ctx_type);
+enum slc_setting {
+ enable_slc,
+ disable_slc,
+};
+
+static void ann_workaround_ctx_set_slc(struct drm_psb_private *dev_priv,
+ uint64_t ctx_type, enum slc_setting slc_set);
+
+#define MB_SIZE 16
#ifdef MERRIFIELD
struct psb_fpriv *psb_fpriv(struct drm_file *file_priv)
@@ -295,7 +302,8 @@
(found_ctx->ctx_type >> 8) & 0xff,
(found_ctx->ctx_type & 0xff));
if (IS_ANN(dev))
- ann_rm_workaround_ctx(dev_priv, found_ctx->ctx_type);
+ ann_workaround_ctx_set_slc(dev_priv, ctx_type,
+ enable_slc);
#ifndef CONFIG_DRM_VXD_BYT
/* if current ctx points to it, set to NULL */
if ((VAEntrypointEncSlice ==
@@ -459,7 +467,8 @@
video_ctx->ctx_type = ctx_type;
video_ctx->cur_sequence = 0xffffffff;
if (IS_ANN(dev))
- ann_add_workaround_ctx(dev_priv, ctx_type);
+ ann_workaround_ctx_set_slc(dev_priv, ctx_type,
+ disable_slc);
#ifdef CONFIG_SLICE_HEADER_PARSING
video_ctx->frame_end_seq = 0xffffffff;
if (ctx_type & VA_RT_FORMAT_PROTECTED) {
@@ -753,19 +762,22 @@
return 0;
}
-/* SLC bug: there is green corruption for vc1 decode if width is not 64 aligned
- * Recode the number of VC1 ctx whose width is not 64 aligned
+/*
+ * SLC bug: there is green corruption for VC1/VP8/H.264 decode if:
+ * 1. VC1/VP8 width is not 64 aligned. Recode the number of VC1 ctx whose width
+ * is not 64 aligned;
+ * 2. H.264 resolution <= 720p.
*/
-static void ann_add_workaround_ctx(struct drm_psb_private *dev_priv, uint64_t ctx_type)
+static void ann_workaround_ctx_set_slc(struct drm_psb_private *dev_priv,
+ uint64_t ctx_type, enum slc_setting slc_set)
{
struct msvdx_private *msvdx_priv;
int profile = (ctx_type >> 8) & 0xff;
-
- if (profile != VAProfileVC1Simple &&
- profile != VAProfileVC1Main &&
- profile != VAProfileVC1Advanced)
- return;
+ /* ctx_type >> 32 is width_in_mb */
+ uint64_t width = ((ctx_type >> 32) & 0xffff) * MB_SIZE;
+ /* ctx_type >> 48 is height_in_mb */
+ uint64_t height = ((ctx_type >> 48) & 0xffff) * MB_SIZE;
if (unlikely(!dev_priv))
return;
@@ -774,41 +786,32 @@
if (unlikely(!msvdx_priv))
return;
- PSB_DEBUG_GENERAL(
- "add vc1 ctx, ctx_type is 0x%llx\n",
- ctx_type);
+ switch (profile) {
+ case VAProfileVC1Simple:
+ case VAProfileVC1Main:
+ case VAProfileVC1Advanced:
+ case VAProfileVP8Version0_3:
+ if (width % 64) {
+ if (slc_set == disable_slc)
+ atomic_inc(&msvdx_priv->slc_workaround_ctx);
+ else
+ atomic_dec(&msvdx_priv->slc_workaround_ctx);
+ }
+ break;
- /* ctx_type >> 32 is width_in_mb */
- if ((ctx_type >> 32) % 4) {
- atomic_inc(&msvdx_priv->vc1_workaround_ctx);
- PSB_DEBUG_GENERAL("add workaround ctx %p in ctx\n", msvdx_priv);
- }
-}
+ case VAProfileH264Baseline:
+ case VAProfileH264Main:
+ case VAProfileH264High:
+ if (((height == 128) && (width > 112) && (width <= 128)) ||
+ ((width <= 1280) && (height <= 736))) {
+ if (slc_set == disable_slc)
+ atomic_inc(&msvdx_priv->slc_workaround_ctx);
+ else
+ atomic_dec(&msvdx_priv->slc_workaround_ctx);
+ }
+ break;
-static void ann_rm_workaround_ctx(struct drm_psb_private *dev_priv, uint64_t ctx_type)
-{
-
- struct msvdx_private *msvdx_priv;
- int profile = (ctx_type >> 8) & 0xff;
-
- if (profile != VAProfileVC1Simple &&
- profile != VAProfileVC1Main &&
- profile != VAProfileVC1Advanced)
- return;
-
- if (unlikely(!dev_priv))
- return;
-
- msvdx_priv = dev_priv->msvdx_private;
- if (unlikely(!msvdx_priv))
- return;
-
- PSB_DEBUG_GENERAL(
- "rm vc1 ctx, ctx_type is 0x%llx\n",
- ctx_type);
- /* ctx_type >> 32 is width_in_mb */
- if ((ctx_type >> 32) % 4) {
- atomic_dec(&msvdx_priv->vc1_workaround_ctx);
- PSB_DEBUG_GENERAL("dec workaround ctx %p in ctx\n", msvdx_priv);
+ default:
+ break;
}
}
diff --git a/drivers/staging/imgtec/intel/video/decode/psb_msvdx.h b/drivers/staging/imgtec/intel/video/decode/psb_msvdx.h
index 0dc8fed..6cb6376 100644
--- a/drivers/staging/imgtec/intel/video/decode/psb_msvdx.h
+++ b/drivers/staging/imgtec/intel/video/decode/psb_msvdx.h
@@ -276,7 +276,7 @@
uint32_t term_buf_addr;
#endif
- atomic_t vc1_workaround_ctx;
+ atomic_t slc_workaround_ctx;
#ifdef CONFIG_ION
struct list_head ion_buffers_list;