gpu: pvr: add support to set board specific max SGX functional clk rate
authorImre Deak <imre.deak@nokia.com>
Fri, 19 Mar 2010 22:08:32 +0000 (23:08 +0100)
committerGrazvydas Ignotas <notasas@gmail.com>
Sun, 20 May 2012 18:09:40 +0000 (21:09 +0300)
Signed-off-by: Imre Deak <imre.deak@nokia.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
include/linux/pvr.h [new file with mode: 0644]
pvr/module.c
pvr/syscommon.h
pvr/sysconfig.c
pvr/syslocal.h
pvr/sysutils.c

diff --git a/include/linux/pvr.h b/include/linux/pvr.h
new file mode 100644 (file)
index 0000000..49f64e0
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __PVR_H
+#define __PVR_H
+
+struct sgx_platform_data {
+       unsigned long fclock_max;
+};
+
+#endif
index 565e420..c630f4d 100644 (file)
@@ -162,7 +162,7 @@ static int __devinit pvr_probe(struct platform_device *pdev)
        PVR_TRACE("pvr_probe(pdev=%p)", pdev);
 
        if (SysAcquireData(&sysdata) != PVRSRV_OK &&
-           SysInitialise() != PVRSRV_OK) {
+           SysInitialise(pdev) != PVRSRV_OK) {
                ret = -ENODEV;
                goto err_exit;
        }
index 4d47e7f..a7ca338 100644 (file)
@@ -37,6 +37,9 @@
 #include "device.h"
 #include "buffer_manager.h"
 
+#include <linux/platform_device.h>
+#include <linux/pvr.h>
+
 #if defined(NO_HARDWARE) && defined(__KERNEL__)
 #include <linux/io.h>
 #endif
@@ -83,7 +86,7 @@ struct SYS_DATA {
 #endif
 };
 
-enum PVRSRV_ERROR SysInitialise(void);
+enum PVRSRV_ERROR SysInitialise(struct platform_device *spd);
 enum PVRSRV_ERROR SysFinalise(void);
 
 enum PVRSRV_ERROR SysDeinitialise(struct SYS_DATA *psSysData);
index 78466b7..44aa7ab 100644 (file)
@@ -24,6 +24,8 @@
  *
  ******************************************************************************/
 
+#include <linux/platform_device.h>
+
 #include "services_headers.h"
 #include "kerneldisplay.h"
 #include "oemfuncs.h"
@@ -138,6 +140,17 @@ u32 sgx_get_rev(void)
 
 unsigned long sgx_get_max_freq(void)
 {
+       struct SYS_SPECIFIC_DATA *sysd = gpsSysSpecificData;
+
+       BUG_ON(!sysd);
+
+       if (sysd->sgx_fck_max)
+               return sysd->sgx_fck_max;
+
+       /*
+        * In case there's no board specific setting for this, return
+        * some revision specific defaults.
+        */
        if (sgx_is_530()) {
                switch (sgx_get_rev()) {
                case EUR_CR_CORE_MAKE_REV(1, 2, 1):
@@ -238,12 +251,13 @@ void sgx_ocp_write_reg(u32 reg, u32 val)
        OSWriteHWReg(ocp_base, reg, val);
 }
 
-enum PVRSRV_ERROR SysInitialise(void)
+enum PVRSRV_ERROR SysInitialise(struct platform_device *pdev)
 {
        u32 i;
        enum PVRSRV_ERROR eError;
        struct PVRSRV_DEVICE_NODE *psDeviceNode;
        struct IMG_CPU_PHYADDR TimerRegPhysBase;
+       struct sgx_platform_data *spd;
 
        gpsSysData = &gsSysData;
 
@@ -251,6 +265,10 @@ enum PVRSRV_ERROR SysInitialise(void)
 
        gpsSysData->pvSysSpecificData = gpsSysSpecificData;
 
+       spd = pdev->dev.platform_data;
+       if (spd)
+               gpsSysSpecificData->sgx_fck_max = spd->fclock_max;
+
        eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData);
        if (eError != PVRSRV_OK) {
                PVR_DPF(PVR_DBG_ERROR,
index 03f39e6..de31046 100644 (file)
@@ -91,6 +91,8 @@ struct SYS_SPECIFIC_DATA {
        void __iomem *gpt_base;
 #endif
        struct constraint_handle *pVdd2Handle;
+
+       unsigned long sgx_fck_max;
 };
 
 extern struct SYS_SPECIFIC_DATA *gpsSysSpecificData;
index 79e1c87..5729b5a 100644 (file)
@@ -454,6 +454,7 @@ static enum PVRSRV_ERROR InitSgxClocks(struct SYS_DATA *psSysData)
        struct SYS_SPECIFIC_DATA *psSysSpecData = psSysData->pvSysSpecificData;
        struct clk *psCLK;
        struct clk *core_ck = NULL;
+       int r;
 
        psCLK = clk_get(NULL, "sgx_fck");
        if (IS_ERR(psCLK))
@@ -474,6 +475,18 @@ static enum PVRSRV_ERROR InitSgxClocks(struct SYS_DATA *psSysData)
        }
        clk_put(core_ck);
 
+       r = clk_set_rate(psSysSpecData->psSGX_FCK,
+                        sgx_get_max_freq());
+       if (r < 0) {
+               unsigned long rate;
+
+               rate = clk_get_rate(psSysSpecData->psSGX_FCK);
+               rate /= 1000000;
+               pr_warning("error %d when setting SGX fclk to %luMHz, "
+                          "falling back to %luMHz\n",
+                          r, sgx_get_max_freq() / 1000000, rate);
+       }
+
        RegisterConstraintNotifications(psSysSpecData);
        return PVRSRV_OK;