#include "srvinit.h"
#include "pvr_ion_stats.h"
+#include "sysconfig.h"
#if defined(SUPPORT_DISPLAY_CLASS)
/* Display class interface */
return 0;
}
+int sPVRSRVDeviceSuspend(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ struct sf7110_cfg *sft = sys_get_privdata();
+
+ if (sft->runtime_suspend != NULL)
+ sft->runtime_suspend(NULL);
+
+ return 0;
+}
+
+int sPVRSRVDeviceResume(PVRSRV_DEVICE_NODE *psDeviceNode)
+{
+ struct sf7110_cfg *sft = sys_get_privdata();
+
+ if (sft->runtime_resume != NULL)
+ sft->runtime_resume(NULL);
+
+ return 0;
+}
+
/**************************************************************************/ /*!
@Function PVRSRVDeviceServicesOpen
@Description Services device open.
if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_INIT)
{
+ PVRSRVSetSystemPowerState(psDeviceNode->psDevConfig, PVRSRV_SYS_POWER_STATE_ON);
eError = PVRSRVCommonDeviceInitialise(psDeviceNode);
if (eError != PVRSRV_OK)
{
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/mutex.h>
+#include <linux/pm_runtime.h>
#include "module_common.h"
#include "pvr_drm.h"
return PVRSRVDeviceResume(priv->dev_node);
}
+static int pvr_pm_runtime_suspend(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct pvr_drm_private *priv = ddev->dev_private;
+
+ sPVRSRVDeviceSuspend(priv->dev_node);
+ return 0;
+}
+
+static int pvr_pm_runtime_resume(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct pvr_drm_private *priv = ddev->dev_private;
+
+ sPVRSRVDeviceResume(priv->dev_node);
+ return 0;
+}
+
const struct dev_pm_ops pvr_pm_ops = {
.suspend = pvr_pm_suspend,
.resume = pvr_pm_resume,
+ .runtime_suspend = pvr_pm_runtime_suspend,
+ .runtime_resume = pvr_pm_runtime_resume,
};
PVRSRVDeviceDeinit(priv->dev_node);
+ pm_runtime_disable(ddev->dev);
mutex_lock(&g_device_mutex);
PVRSRVCommonDeviceDestroy(priv->dev_node);
mutex_unlock(&g_device_mutex);
}
#endif
+static IMG_UINT32 sys_gpu_runtime_resume(IMG_HANDLE hd)
+{
+ starfive_pmu_hw_event_turn_off_mask(0);
+ clk_prepare_enable(sf_cfg_t.clk_axi);
+ u0_img_gpu_enable();
+
+ return 0;
+}
+
+static IMG_UINT32 sys_gpu_runtime_suspend(IMG_HANDLE hd)
+{
+ u0_img_gpu_disable();
+ starfive_pmu_hw_event_turn_off_mask((uint32_t)-1);
+
+ return 0;
+}
+
static int create_sf7110_cfg(struct device *dev)
{
struct sf7110_cfg *psf = &sf_cfg_t;
goto err_gpu_unmap;
}
+ psf->runtime_resume = sys_gpu_runtime_resume;
+ psf->runtime_suspend = sys_gpu_runtime_suspend;
+
return 0;
err_gpu_unmap:
iounmap(psf->gpu_reg_base);
clk_disable_unprepare(sf_cfg_t.clk_sys);
}
-
-
static int sys_gpu_enable(void)
{
int ret;
-
- pm_runtime_enable(sf_cfg_t.dev);
+
ret = pm_runtime_get_sync(sf_cfg_t.dev);
if (ret < 0) {
dev_err(sf_cfg_t.dev, "gpu: failed to get pm runtime: %d\n", ret);
return ret;
}
- starfive_pmu_hw_event_turn_off_mask(0);
- clk_prepare_enable(sf_cfg_t.clk_axi);
- u0_img_gpu_enable();
+
return 0;
}
static int sys_gpu_disable(void)
{
- u0_img_gpu_disable();
- starfive_pmu_hw_event_turn_off_mask((uint32_t)-1);
pm_runtime_put_sync(sf_cfg_t.dev);
//pm_runtime_disable(sf_cfg_t.dev);
return 0;
}
-
-
-
static PVRSRV_ERROR sfSysDevPrePowerState(
IMG_HANDLE hSysData,
PVRSRV_SYS_POWER_STATE eNewPowerState,
PVRSRV_SYS_POWER_STATE eCurrentPowerState,
- IMG_BOOL bForced)
+ PVRSRV_POWER_FLAGS ePwrFlags)
{
struct sf7110_cfg *psf = hSysData;
+ pr_debug("(%s()) state: current=%d, new=%d; flags: 0x%08x", __func__,
+ eCurrentPowerState, eNewPowerState, ePwrFlags);
+
mutex_lock(&psf->set_power_state);
if ((PVRSRV_SYS_POWER_STATE_OFF == eNewPowerState) &&
IMG_HANDLE hSysData,
PVRSRV_SYS_POWER_STATE eNewPowerState,
PVRSRV_SYS_POWER_STATE eCurrentPowerState,
- IMG_BOOL bForced)
+ PVRSRV_POWER_FLAGS ePwrFlags)
{
struct sf7110_cfg *psf = hSysData;
PVRSRV_ERROR ret;
+ pr_debug("(%s()) state: current=%d, new=%d; flags: 0x%08x", __func__,
+ eCurrentPowerState, eNewPowerState, ePwrFlags);
mutex_lock(&psf->set_power_state);
* Setup RGX specific timing data
*/
gsRGXTimingInfo.ui32CoreClockSpeed = RGX_STARFIVE_7100_CORE_CLOCK_SPEED;
- gsRGXTimingInfo.bEnableActivePM = IMG_FALSE;
+ gsRGXTimingInfo.bEnableActivePM = IMG_TRUE;
gsRGXTimingInfo.bEnableRDPowIsland = IMG_TRUE;
gsRGXTimingInfo.ui32ActivePMLatencyms = SYS_RGX_ACTIVE_POWER_LATENCY_MS;
}
gsDevices[0].hSysData = &sf_cfg_t;
+ pm_runtime_enable(sf_cfg_t.dev);
/* power management on HW system */
gsDevices[0].pfnPrePowerState = sfSysDevPrePowerState;
gsDevices[0].pfnPostPowerState = sfSysDevPostPowerState;
return PVRSRV_OK;
}
+struct sf7110_cfg *sys_get_privdata(void)
+{
+ return &sf_cfg_t;
+}
+
/******************************************************************************
End of file (sysconfig.c)
******************************************************************************/
#define STARFIVE_7110_GPU_SIZE 0x00100000
#define STARFIVE_7110_GPU_PBASE 0x18000000
+typedef IMG_UINT32 (*SYS_DEV_CLK_GET)(IMG_HANDLE hData);
+
struct sf7110_cfg {
void __iomem *gpu_reg_base;
resource_size_t gpu_reg_start;
/* for gpu device freq/volt update, to be fill later */
//struct clk **top_clk;
struct device *dev;
+ SYS_DEV_CLK_GET runtime_resume;
+ SYS_DEV_CLK_GET runtime_suspend;
};
#define mk_crg_offset(x) ((x) - (U0_SYS_CRG__SAIF_BD_APBS__BASE_ADDR))
extern void do_sifive_l2_flush64_range(unsigned long start, unsigned long len);
+void u0_img_gpu_enable(void);
+void u0_img_gpu_disable(void);
+struct sf7110_cfg *sys_get_privdata(void);
/*****************************************************************************
* system specific data structures
*****************************************************************************/