Commit 463464eb authored by Ben Skeggs's avatar Ben Skeggs

drm/nv50/pm: fix thinko which lead to clocks being slightly off sometimes

read_pll_ref() needs to take into account the refclk src bits in 0xc040 on
some chipsets, it wasn't doing this.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 6805979f
...@@ -66,7 +66,7 @@ read_div(struct drm_device *dev) ...@@ -66,7 +66,7 @@ read_div(struct drm_device *dev)
} }
static u32 static u32
read_pll_ref(struct drm_device *dev, u32 base) read_pll_src(struct drm_device *dev, u32 base)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
u32 coef, ref = read_clk(dev, clk_src_crystal); u32 coef, ref = read_clk(dev, clk_src_crystal);
...@@ -137,21 +137,12 @@ read_pll_ref(struct drm_device *dev, u32 base) ...@@ -137,21 +137,12 @@ read_pll_ref(struct drm_device *dev, u32 base)
} }
static u32 static u32
read_pll(struct drm_device *dev, u32 base) read_pll_ref(struct drm_device *dev, u32 base)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; u32 src, mast = nv_rd32(dev, 0x00c040);
u32 mast = nv_rd32(dev, 0x00c040);
u32 src = 0, ref = 0, clk = 0;
u32 ctrl, coef;
int N1, N2, M1, M2;
switch (base) { switch (base) {
case 0x004028: case 0x004028:
if (mast & 0x00100000) {
/* wtf, appears to only disable post-divider on nva0 */
if (dev_priv->chipset != 0xa0)
return read_clk(dev, clk_src_dom6);
}
src = !!(mast & 0x00200000); src = !!(mast & 0x00200000);
break; break;
case 0x004020: case 0x004020:
...@@ -164,22 +155,33 @@ read_pll(struct drm_device *dev, u32 base) ...@@ -164,22 +155,33 @@ read_pll(struct drm_device *dev, u32 base)
src = !!(mast & 0x02000000); src = !!(mast & 0x02000000);
break; break;
case 0x00e810: case 0x00e810:
ref = read_clk(dev, clk_src_crystal); return read_clk(dev, clk_src_crystal);
break;
default: default:
NV_ERROR(dev, "bad pll 0x%06x\n", base); NV_ERROR(dev, "bad pll 0x%06x\n", base);
return 0; return 0;
} }
if (ref == 0) {
if (src) if (src)
ref = read_clk(dev, clk_src_href); return read_clk(dev, clk_src_href);
else return read_pll_src(dev, base);
ref = read_pll_ref(dev, base); }
}
static u32
read_pll(struct drm_device *dev, u32 base)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
u32 mast = nv_rd32(dev, 0x00c040);
u32 ctrl = nv_rd32(dev, base + 0);
u32 coef = nv_rd32(dev, base + 4);
u32 ref = read_pll_ref(dev, base);
u32 clk = 0;
int N1, N2, M1, M2;
ctrl = nv_rd32(dev, base + 0); if (base == 0x004028 && (mast & 0x00100000)) {
coef = nv_rd32(dev, base + 4); /* wtf, appears to only disable post-divider on nva0 */
if (dev_priv->chipset != 0xa0)
return read_clk(dev, clk_src_dom6);
}
N2 = (coef & 0xff000000) >> 24; N2 = (coef & 0xff000000) >> 24;
M2 = (coef & 0x00ff0000) >> 16; M2 = (coef & 0x00ff0000) >> 16;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment