MGS-3848-3 [#imx-854] correct command commit synchronization between pm and other...
authorXianzhong <xianzhong.li@nxp.com>
Wed, 25 Apr 2018 19:58:25 +0000 (03:58 +0800)
committerXianzhong <xianzhong.li@nxp.com>
Thu, 26 Apr 2018 15:39:22 +0000 (23:39 +0800)
When power ON to other mode with broadcast (SUSPEND_BROADCAST,
IDLE_BROADCAST, OFF_BROADCAST), command->powerSemaphore is acquired after check idle.
code sequence:
    check commit atom
    check idle
    >>> at this point, other thread may have new commits at this
    >>> point.
    Acquire command->powerSemaphore
    ... do clock off

This can cause unexpected interrupts after clock OFF or power
OFF.

To fix: try to acquire powerSemaphore before check commit atom,
abort when failure, because command commit is in progress.

fix bug #19216, #19230.

Signed-off-by: Xianzhong <xianzhong.li@nxp.com>
(cherry picked from commit 5228271314e8f575e4bbd9d3087c220b6a344b7d)

drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c

index be8ca1c..e67e2f5 100644 (file)
@@ -7863,6 +7863,29 @@ gckHARDWARE_SetPowerManagementState(
         /* Release the global semaphore again. */
         gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
         globalAcquired = gcvFALSE;
+
+        /* Try to acquire the semaphore to make sure commit is not in progress
+        ** Otherwise, we just abort. */
+        if (flag & gcvPOWER_FLAG_ACQUIRE)
+        {
+            /* ON -> Other, boardcast. */
+            /* Try to acquire the power management semaphore. */
+            status = gckOS_TryAcquireSemaphore(os, command->powerSemaphore);
+
+            if (status == gcvSTATUS_OK)
+            {
+                acquired = gcvTRUE;
+
+                /* avoid acquiring again. */
+                flag &= ~gcvPOWER_FLAG_ACQUIRE;
+            }
+            else
+            {
+                /* Not ready to swith. */
+                status = gcvSTATUS_CHIP_NOT_READY;
+                goto OnError;
+            }
+        }
     }
     else
     {