drm/nva3/pm: parse/reclock vdec/41a0 clocks
authorBen Skeggs <bskeggs@redhat.com>
Fri, 17 Jun 2011 06:11:31 +0000 (16:11 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 20 Sep 2011 06:02:36 +0000 (16:02 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_perf.c
drivers/gpu/drm/nouveau/nva3_pm.c

index 7a88d9cb2ac111a9326f236f2c2bdf769d660f09..06867055181e324f4c0ed38e4968ef605b6115d1 100644 (file)
@@ -449,8 +449,10 @@ struct nouveau_pm_level {
        u32 core;
        u32 memory;
        u32 shader;
+       u32 vdec;
        u32 unk05;
        u32 unk0a;
+       u32 unka0;
 
        u32 volt_min; /* microvolts */
        u32 volt_max;
index b0e995fdcbadc7a059dfaa9a0009b54abb38066d..b00cf4b5046b656960fce8bdab2b261e529b5aa7 100644 (file)
@@ -291,6 +291,8 @@ nouveau_perf_init(struct drm_device *dev)
                                perflvl->core = ROM16(subent(0)) & 0xfff;
                                perflvl->shader = ROM16(subent(1)) & 0xfff;
                                perflvl->memory = ROM16(subent(2)) & 0xfff;
+                               perflvl->vdec   = ROM16(subent(3)) & 0xfff;
+                               perflvl->unka0  = ROM16(subent(4)) & 0xfff;
                        } else {
                                perflvl->shader = ROM16(subent(3)) & 0xfff;
                                perflvl->core   = perflvl->shader / 2;
@@ -302,6 +304,8 @@ nouveau_perf_init(struct drm_device *dev)
                        perflvl->shader *= 1000;
                        perflvl->memory *= 1000;
                        perflvl->unk0a *= 1000;
+                       perflvl->vdec *= 1000;
+                       perflvl->unka0 *= 1000;
                        break;
                }
 
index 562e781c4f539b81c5baeed0c32e078ea4286bdf..a9e3de4a9520d87a85c2e8323769be0805b15da6 100644 (file)
@@ -151,6 +151,8 @@ nva3_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
        perflvl->core   = read_pll(dev, 0x4200, 0);
        perflvl->shader = read_pll(dev, 0x4220, 1);
        perflvl->memory = read_pll(dev, 0x4000, 2);
+       perflvl->unka0  = read_clk(dev, 0x20, false);
+       perflvl->vdec   = read_clk(dev, 0x21, false);
        return 0;
 }
 
@@ -158,6 +160,8 @@ struct nva3_pm_state {
        struct creg nclk;
        struct creg sclk;
        struct creg mclk;
+       struct creg vdec;
+       struct creg unka0;
 };
 
 void *
@@ -182,6 +186,14 @@ nva3_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
        if (ret < 0)
                goto out;
 
+       ret = calc_clk(dev, 0x0000, 0x20, perflvl->unka0, &info->unka0);
+       if (ret < 0)
+               goto out;
+
+       ret = calc_clk(dev, 0x0000, 0x21, perflvl->vdec, &info->vdec);
+       if (ret < 0)
+               goto out;
+
 out:
        if (ret < 0) {
                kfree(info);
@@ -215,6 +227,12 @@ prog_pll(struct drm_device *dev, u32 pll, int clk, struct creg *reg)
        }
 }
 
+static void
+prog_clk(struct drm_device *dev, int clk, struct creg *reg)
+{
+       nv_mask(dev, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | reg->clk);
+}
+
 void
 nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
 {
@@ -222,6 +240,8 @@ nva3_pm_clocks_set(struct drm_device *dev, void *pre_state)
 
        prog_pll(dev, 0x004200, 0, &info->nclk);
        prog_pll(dev, 0x004220, 1, &info->sclk);
+       prog_clk(dev, 0x20, &info->unka0);
+       prog_clk(dev, 0x21, &info->vdec);
 
        nv_wr32(dev, 0x100210, 0);
        nv_wr32(dev, 0x1002dc, 1);