summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
diff options
context:
space:
mode:
authorBen Skeggs2012-07-10 09:26:46 +0200
committerBen Skeggs2012-10-03 05:12:47 +0200
commit70790f4f819875e8f390871fd15bbbf823f28e1b (patch)
tree47949ac5a0af23a9fe1ace1ac5fd8b8823b8e055 /drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
parentdrm/nouveau/clk: implement stub clock subdev (diff)
downloadkernel-qcow2-linux-70790f4f819875e8f390871fd15bbbf823f28e1b.tar.gz
kernel-qcow2-linux-70790f4f819875e8f390871fd15bbbf823f28e1b.tar.xz
kernel-qcow2-linux-70790f4f819875e8f390871fd15bbbf823f28e1b.zip
drm/nouveau/clock: pull in the implementation from all over the place
Still missing the main bits we use to change performance levels, I'll get to it after all the hard yakka has been finished. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
index 876ec46e2b41..cc8d7d162d7c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -23,17 +23,47 @@
*/
#include <subdev/clock.h>
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+
+#include "pll.h"
struct nva3_clock_priv {
struct nouveau_clock base;
};
-static void
+static int
nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
{
struct nva3_clock_priv *priv = (void *)clk;
+ struct nouveau_bios *bios = nouveau_bios(priv);
+ struct nvbios_pll info;
+ int N, fN, M, P;
+ int ret;
+
+ ret = nvbios_pll_parse(bios, type, &info);
+ if (ret)
+ return ret;
+
+ ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
+ if (ret < 0)
+ return ret;
+
+ switch (info.type) {
+ case PLL_VPLL0:
+ case PLL_VPLL1:
+ nv_wr32(priv, info.reg + 0, 0x50000610);
+ nv_mask(priv, info.reg + 4, 0x003fffff,
+ (P << 16) | (M << 8) | N);
+ nv_wr32(priv, info.reg + 8, fN);
+ break;
+ default:
+ nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
+ ret = -EINVAL;
+ break;
+ }
- nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
+ return ret;
}
static int