driver:gpu: add gpu runtime pm
authorshanlong.li <shanlong.li@starfivetech.com>
Wed, 26 Oct 2022 09:44:58 +0000 (02:44 -0700)
committermason.huo <mason.huo@starfivetech.com>
Thu, 27 Oct 2022 06:00:49 +0000 (14:00 +0800)
fix up system pm error and add runtime pm

Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
drivers/gpu/drm/img/img-rogue/services/server/common/power.c
drivers/gpu/drm/img/img-rogue/services/server/devices/rogue/rgxinit.c
drivers/gpu/drm/img/img-rogue/services/server/env/linux/module_common.c
drivers/gpu/drm/img/img-rogue/services/server/env/linux/module_common.h
drivers/gpu/drm/img/img-rogue/services/server/env/linux/pvr_drm.c
drivers/gpu/drm/img/img-rogue/services/system/rogue/sf_7110/sysconfig.c
drivers/gpu/drm/img/img-rogue/services/system/rogue/sf_7110/sysconfig.h

index 5ad6695..e1c3a3a 100644 (file)
@@ -277,6 +277,7 @@ static PVRSRV_ERROR _PVRSRVDeviceIdleRequestKM(PPVRSRV_DEVICE_NODE psDeviceNode,
        }
        else
        {
+               PVRSRVSetSystemPowerState(psDeviceNode->psDevConfig, PVRSRV_SYS_POWER_STATE_ON);
                return PVRSRV_OK;
        }
 
index ca92eff..dd572a5 100644 (file)
@@ -4863,7 +4863,6 @@ PVRSRV_ERROR RGXRegisterDevice(PVRSRV_DEVICE_NODE *psDeviceNode)
                psDeviceNode->pfnFwMMUInit = RGXMipsMMUInit_Register;
        }
 
-       PVRSRVSetSystemPowerState(psDeviceNode->psDevConfig, PVRSRV_SYS_POWER_STATE_ON);
        /* The device shared-virtual-memory heap address-space size is stored here for faster
           look-up without having to walk the device heap configuration structures during
           client device connection  (i.e. this size is relative to a zero-based offset) */
index 62aa58e..f7a956d 100644 (file)
@@ -79,6 +79,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "srvinit.h"
 
 #include "pvr_ion_stats.h"
+#include "sysconfig.h"
 
 #if defined(SUPPORT_DISPLAY_CLASS)
 /* Display class interface */
@@ -445,6 +446,26 @@ int PVRSRVDeviceResume(PVRSRV_DEVICE_NODE *psDeviceNode)
        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.
@@ -504,6 +525,7 @@ int PVRSRVDeviceServicesOpen(PVRSRV_DEVICE_NODE *psDeviceNode,
 
        if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_INIT)
        {
+               PVRSRVSetSystemPowerState(psDeviceNode->psDevConfig, PVRSRV_SYS_POWER_STATE_ON);
                eError = PVRSRVCommonDeviceInitialise(psDeviceNode);
                if (eError != PVRSRV_OK)
                {
index 7317a0a..c7d1ebd 100644 (file)
@@ -98,4 +98,7 @@ void PVRSRVDeviceRelease(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode,
 int drm_pvr_srvkm_init(struct drm_device *dev,
                        void *arg, struct drm_file *psDRMFile);
 
+int sPVRSRVDeviceSuspend(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
+
+int sPVRSRVDeviceResume(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode);
 #endif /* MODULE_COMMON_H */
index 65a8e51..2b3cd5c 100644 (file)
@@ -61,6 +61,7 @@
 #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"
@@ -102,9 +103,29 @@ static int pvr_pm_resume(struct device *dev)
        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,
 };
 
 
@@ -214,6 +235,7 @@ void pvr_drm_unload(struct drm_device *ddev)
 
        PVRSRVDeviceDeinit(priv->dev_node);
 
+       pm_runtime_disable(ddev->dev);
        mutex_lock(&g_device_mutex);
        PVRSRVCommonDeviceDestroy(priv->dev_node);
        mutex_unlock(&g_device_mutex);
index af93caa..ada8ff7 100644 (file)
@@ -222,6 +222,23 @@ void SysDevHost_Cache_Maintenance(IMG_HANDLE hSysData,
 }
 #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;
@@ -282,6 +299,9 @@ static int create_sf7110_cfg(struct device *dev)
                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);
@@ -312,44 +332,37 @@ void u0_img_gpu_disable(void)
        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) &&
@@ -364,11 +377,13 @@ static PVRSRV_ERROR sfSysDevPostPowerState(
                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);
 
@@ -423,7 +438,7 @@ PVRSRV_ERROR SysDevInit(void *pvOSDevice, PVRSRV_DEVICE_CONFIG **ppsDevConfig)
         * 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;
 
@@ -483,6 +498,7 @@ PVRSRV_ERROR SysDevInit(void *pvOSDevice, PVRSRV_DEVICE_CONFIG **ppsDevConfig)
        }
        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;
@@ -617,6 +633,11 @@ PVRSRV_ERROR SysDebugInfo(PVRSRV_DEVICE_CONFIG *psDevConfig,
        return PVRSRV_OK;
 }
 
+struct sf7110_cfg *sys_get_privdata(void)
+{
+       return &sf_cfg_t;
+}
+
 /******************************************************************************
  End of file (sysconfig.c)
 ******************************************************************************/
index f44edb3..435f637 100644 (file)
@@ -52,6 +52,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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;
@@ -72,6 +74,8 @@ struct sf7110_cfg {
        /* 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))
@@ -86,6 +90,9 @@ struct sf7110_cfg {
 
 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
  *****************************************************************************/