From e03e90b8fa39ef6b2a23f6028a357c5ee35b85b7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 19 Mar 2010 23:08:32 +0100 Subject: [PATCH] gpu: pvr: add support to set board specific max SGX functional clk rate Signed-off-by: Imre Deak Signed-off-by: Tomi Valkeinen --- include/linux/pvr.h | 8 ++++++++ pvr/module.c | 2 +- pvr/syscommon.h | 5 ++++- pvr/sysconfig.c | 20 +++++++++++++++++++- pvr/syslocal.h | 2 ++ pvr/sysutils.c | 13 +++++++++++++ 6 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 include/linux/pvr.h diff --git a/include/linux/pvr.h b/include/linux/pvr.h new file mode 100644 index 0000000..49f64e0 --- /dev/null +++ b/include/linux/pvr.h @@ -0,0 +1,8 @@ +#ifndef __PVR_H +#define __PVR_H + +struct sgx_platform_data { + unsigned long fclock_max; +}; + +#endif diff --git a/pvr/module.c b/pvr/module.c index 565e420..c630f4d 100644 --- a/pvr/module.c +++ b/pvr/module.c @@ -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; } diff --git a/pvr/syscommon.h b/pvr/syscommon.h index 4d47e7f..a7ca338 100644 --- a/pvr/syscommon.h +++ b/pvr/syscommon.h @@ -37,6 +37,9 @@ #include "device.h" #include "buffer_manager.h" +#include +#include + #if defined(NO_HARDWARE) && defined(__KERNEL__) #include #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); diff --git a/pvr/sysconfig.c b/pvr/sysconfig.c index 78466b7..44aa7ab 100644 --- a/pvr/sysconfig.c +++ b/pvr/sysconfig.c @@ -24,6 +24,8 @@ * ******************************************************************************/ +#include + #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, diff --git a/pvr/syslocal.h b/pvr/syslocal.h index 03f39e6..de31046 100644 --- a/pvr/syslocal.h +++ b/pvr/syslocal.h @@ -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; diff --git a/pvr/sysutils.c b/pvr/sysutils.c index 79e1c87..5729b5a 100644 --- a/pvr/sysutils.c +++ b/pvr/sysutils.c @@ -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; -- 2.39.5