drm/nva3/clk: minor improvements to fractional N calculation
authorBen Skeggs <bskeggs@redhat.com>
Thu, 24 Jan 2013 02:15:45 +0000 (12:15 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 1 Jul 2013 03:44:06 +0000 (13:44 +1000)
Helps us to get identical numbers to the binary driver for (at least)
Kepler memory PLLs, and fixes a rounding error.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c

index 4497378ba1e8ccc8a0c6b454ded279ae9d34a7e1..2fe1f712eefa977bd69bba0ea05e15f939dd7f16 100644 (file)
@@ -50,8 +50,15 @@ nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info,
                u32 tmp = freq * *P * M;
                N  = tmp / info->refclk;
                fN = tmp % info->refclk;
-               if (!pfN && fN >= info->refclk / 2)
-                       N++;
+
+               if (!pfN) {
+                       if (fN >= info->refclk / 2)
+                               N++;
+               } else {
+                       if (fN <  info->refclk / 2)
+                               N--;
+                       fN = tmp - (N * info->refclk);
+               }
 
                if (N < info->vco1.min_n)
                        continue;
@@ -66,7 +73,8 @@ nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info,
                }
 
                if (pfN) {
-                       *pfN = (((fN << 13) / info->refclk) - 4096) & 0xffff;
+                       *pfN = ((fN << 13) + info->refclk / 2) / info->refclk;
+                       *pfN = (*pfN - 4096) & 0xffff;
                        return freq;
                }
        }