#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;
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();
PDUMPSUSPEND();
+ pvr_dev_lock();
+
eError =
PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex,
PVRSRV_POWER_STATE_D0);
} else {
PVR_DPF(PVR_DBG_ERROR, "%s: can't power on device (%d)",
__func__, eError);
+ pvr_dev_unlock();
return eError;
}
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;
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);
#endif
u32 l;
+ pvr_dev_lock();
if (readl(&psSGXHostCtl->ui32PowerStatus) &
PVRSRV_USSE_EDM_POWMAN_NO_WORK) {
;
PDUMPCOMMENTWITHFLAGS(0, "Clean-up event on uKernel disabled");
#endif
- SGXScheduleProcessQueuesKM(psDeviceNode);
+ SGXScheduleProcessQueues(psDeviceNode);
#if !defined(NO_HARDWARE)
if (PollForValueKM(&psSGXHostCtl->ui32ResManFlags,
sizeof(u32), 0, hUniqueTag);
#endif
}
+ pvr_dev_unlock();
}
struct SGX_HW_RENDER_CONTEXT_CLEANUP {