gpu: pvr: pdumpfs: add Kconfig and debugfs pdump mode handling
[sgx.git] / pvr / sgxutils.c
index aac6d51..860cbb6 100644 (file)
@@ -33,7 +33,7 @@
 #include "sgxinfo.h"
 #include "sgxinfokm.h"
 #include "sysconfig.h"
-#include "pdump_km.h"
+#include "pvr_pdump.h"
 #include "mmu.h"
 #include "pvr_bridge_km.h"
 #include "sgx_bridge_km.h"
 #include <linux/tty.h>
 #include <linux/io.h>
 
-static void SGXPostActivePowerEvent(struct PVRSRV_DEVICE_NODE *psDeviceNode,
-                                    u32 ui32CallerID)
+static void SGXPostActivePowerEvent(struct PVRSRV_DEVICE_NODE *psDeviceNode)
 {
        struct PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
        struct SGXMKIF_HOST_CTL __iomem *psSGXHostCtl =
                                             psDevInfo->psSGXHostCtl;
        u32 l;
 
+       /* To aid in calculating the next power down delay */
+       sgx_mark_power_down(psDeviceNode);
+
        l = readl(&psSGXHostCtl->ui32NumActivePowerEvents);
        l++;
        writel(l, &psSGXHostCtl->ui32NumActivePowerEvents);
 
        l = readl(&psSGXHostCtl->ui32PowerStatus);
-       if (l & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) {
-               if (ui32CallerID == ISR_ID)
-                       psDeviceNode->bReProcessDeviceCommandComplete =
-                           IMG_TRUE;
-               else
-                       SGXScheduleProcessQueuesKM(psDeviceNode);
-       }
+       if (l & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE)
+               SGXScheduleProcessQueues(psDeviceNode);
 }
 
-void SGXTestActivePowerEvent(struct PVRSRV_DEVICE_NODE *psDeviceNode,
-                                u32 ui32CallerID)
+void SGXTestActivePowerEvent(struct PVRSRV_DEVICE_NODE *psDeviceNode)
 {
        enum PVRSRV_ERROR eError = PVRSRV_OK;
        struct PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
        struct SGXMKIF_HOST_CTL __iomem *psSGXHostCtl = psDevInfo->psSGXHostCtl;
        u32 l;
 
+       if (isSGXPerfServerActive())
+               return;
+
        l = readl(&psSGXHostCtl->ui32InterruptFlags);
        if (!(l & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER))
                return;
@@ -89,18 +88,11 @@ void SGXTestActivePowerEvent(struct PVRSRV_DEVICE_NODE *psDeviceNode,
 
        PDUMPSUSPEND();
 
-       eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.
-                                       ui32DeviceIndex,
-                                       PVRSRV_POWER_STATE_D3,
-                                       ui32CallerID, IMG_FALSE);
+       eError = PVRSRVSetDevicePowerStateKM(
+                                       psDeviceNode->sDevId.ui32DeviceIndex,
+                                       PVRSRV_POWER_STATE_D3);
        if (eError == PVRSRV_OK)
-               SGXPostActivePowerEvent(psDeviceNode, ui32CallerID);
-       if (eError == PVRSRV_ERROR_RETRY) {
-               l = readl(&psSGXHostCtl->ui32InterruptClearFlags);
-               l &= ~PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER;
-               writel(l, &psSGXHostCtl->ui32InterruptClearFlags);
-               eError = PVRSRV_OK;
-       }
+               SGXPostActivePowerEvent(psDeviceNode);
 
        PDUMPRESUME();
 
@@ -183,7 +175,7 @@ enum PVRSRV_ERROR SGXScheduleCCBCommand(struct PVRSRV_SGXDEV_INFO *psDevInfo,
                PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo,
                            offsetof(struct PVRSRV_SGX_CCB_CTL, ui32ReadOffset),
                            (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff, 0xff,
-                           PDUMP_POLL_OPERATOR_NOTEQUAL, IMG_FALSE, IMG_FALSE,
+                           PDUMP_POLL_OPERATOR_NOTEQUAL,
                            MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo));
 
                PDUMPCOMMENTWITHFLAGS(0, "Kernel CCB command\r\n");
@@ -267,29 +259,20 @@ enum PVRSRV_ERROR SGXScheduleCCBCommandKM(
 
        PDUMPSUSPEND();
 
+       pvr_dev_lock();
+
        eError =
            PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
-                                       PVRSRV_POWER_STATE_D0, ui32CallerID,
-                                       IMG_TRUE);
+                                       PVRSRV_POWER_STATE_D0);
 
        PDUMPRESUME();
 
        if (eError == PVRSRV_OK) {
                psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE;
        } else {
-               if (eError == PVRSRV_ERROR_RETRY) {
-                       if (ui32CallerID == ISR_ID) {
-                               psDeviceNode->bReProcessDeviceCommandComplete =
-                                   IMG_TRUE;
-                               eError = PVRSRV_OK;
-                       } else {
-
-                       }
-               } else
-                       PVR_DPF(PVR_DBG_ERROR, "SGXScheduleCCBCommandKM "
-                                       "failed to acquire lock - "
-                                        "ui32CallerID:%ld eError:%lu",
-                                        ui32CallerID, eError);
+               PVR_DPF(PVR_DBG_ERROR, "%s: can't power on device (%d)",
+                                       __func__, eError);
+               pvr_dev_unlock();
                return eError;
        }
 
@@ -297,13 +280,15 @@ enum PVRSRV_ERROR SGXScheduleCCBCommandKM(
                                  ui32CallerID, ui32PDumpFlags);
 
        if (ui32CallerID != ISR_ID)
-               SGXTestActivePowerEvent(psDeviceNode, ui32CallerID);
+               SGXTestActivePowerEvent(psDeviceNode);
+
+       pvr_dev_unlock();
 
        return eError;
 }
 
-enum PVRSRV_ERROR SGXScheduleProcessQueuesKM(struct PVRSRV_DEVICE_NODE
-                                            *psDeviceNode)
+enum PVRSRV_ERROR SGXScheduleProcessQueues(struct PVRSRV_DEVICE_NODE
+                                          *psDeviceNode)
 {
        enum PVRSRV_ERROR eError;
        struct PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice;
@@ -316,20 +301,37 @@ enum PVRSRV_ERROR SGXScheduleProcessQueuesKM(struct PVRSRV_DEVICE_NODE
        if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0)
                return PVRSRV_OK;
 
-       sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD;
        eError =
-           SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_COMMAND_EDM_KICK,
-                                   &sCommand, ISR_ID, 0);
+           PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
+                                       PVRSRV_POWER_STATE_D0);
+       if (eError != PVRSRV_OK)
+               return eError;
+
+       sCommand.ui32Data[0] = PVRSRV_CCBFLAGS_PROCESS_QUEUESCMD;
+       eError = SGXScheduleCCBCommand(psDeviceNode->pvDevice,
+                                      SGXMKIF_COMMAND_EDM_KICK, &sCommand,
+                                      ISR_ID, 0);
        if (eError != PVRSRV_OK) {
-               PVR_DPF(PVR_DBG_ERROR, "SGXScheduleProcessQueuesKM failed "
-                                       "to schedule CCB command: %lu",
-                        eError);
+               PVR_DPF(PVR_DBG_ERROR, "%s failed to schedule CCB command: %lu",
+                        __func__, eError);
                return PVRSRV_ERROR_GENERIC;
        }
 
        return PVRSRV_OK;
 }
 
+enum PVRSRV_ERROR SGXScheduleProcessQueuesKM(struct PVRSRV_DEVICE_NODE
+                                          *psDeviceNode)
+{
+       enum PVRSRV_ERROR eError;
+
+       pvr_dev_lock();
+       eError = SGXScheduleProcessQueues(psDeviceNode);
+       pvr_dev_unlock();
+
+       return eError;
+}
+
 IMG_BOOL SGXIsDevicePowered(struct PVRSRV_DEVICE_NODE *psDeviceNode)
 {
        return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex);
@@ -371,6 +373,7 @@ void SGXCleanupRequest(struct PVRSRV_DEVICE_NODE *psDeviceNode,
 #endif
        u32 l;
 
+       pvr_dev_lock();
        if (readl(&psSGXHostCtl->ui32PowerStatus) &
             PVRSRV_USSE_EDM_POWMAN_NO_WORK) {
                ;
@@ -419,7 +422,7 @@ void SGXCleanupRequest(struct PVRSRV_DEVICE_NODE *psDeviceNode,
                PDUMPCOMMENTWITHFLAGS(0, "Clean-up event on uKernel disabled");
 #endif
 
-               SGXScheduleProcessQueuesKM(psDeviceNode);
+               SGXScheduleProcessQueues(psDeviceNode);
 
 #if !defined(NO_HARDWARE)
                if (PollForValueKM(&psSGXHostCtl->ui32ResManFlags,
@@ -441,8 +444,7 @@ void SGXCleanupRequest(struct PVRSRV_DEVICE_NODE *psDeviceNode,
                            offsetof(struct SGXMKIF_HOST_CTL, ui32ResManFlags),
                            PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE,
                            PVRSRV_USSE_EDM_RESMAN_CLEANUP_COMPLETE,
-                           PDUMP_POLL_OPERATOR_EQUAL, IMG_FALSE, IMG_FALSE,
-                           hUniqueTag);
+                           PDUMP_POLL_OPERATOR_EQUAL, hUniqueTag);
 #endif
 
                l = readl(&psSGXHostCtl->ui32ResManFlags);
@@ -459,6 +461,7 @@ void SGXCleanupRequest(struct PVRSRV_DEVICE_NODE *psDeviceNode,
                         sizeof(u32), 0, hUniqueTag);
 #endif
        }
+       pvr_dev_unlock();
 }
 
 struct SGX_HW_RENDER_CONTEXT_CLEANUP {