Mailinglist Archive: radeonhd (300 mails)

< Previous Next >
[radeonhd] Fix for VT restore issues on many laptop panels.
  • From: Luc Verhaegen <libv@xxxxxxxxx>
  • Date: Thu, 15 May 2008 16:09:55 +0200
  • Message-id: <20080515140955.GA8679@xxxxxxxxx>
Hi all,

Since fd.o is currently in a maintainance state and not accessible, and
since this fix is one for a bug that has been pestering many people, i
am sending this patch here directly.

It applies on top of a current git, i think it will also apply nicely
on top of a git tree all the way back to 30th of april (where i last
fixed an issue with plls for the rv620).

This patch fixes the issue we saw on mostly m56 and m54 laptops; where
attaching an external display meant that, upon vt restore, the internal
panel wouldn't come up anymore.

It might also help with the issue of colour cycling on m54 laptops, but
since i have no access to such hardware myself, this will have to be
tested still. So please get me some feedback ASAP :)

Once our git is back up again, i will push this fix and start working
the bugs for this.

Thanks,

Luc Verhaegen.
SUSE/Novell X Driver Developer.
From 31e76905940dd785edd91944851b91ef6aa3a79b Mon Sep 17 00:00:00 2001
From: Luc Verhaegen <libv@xxxxxxxxx>
Date: Thu, 15 May 2008 15:00:11 +0200
Subject: [PATCH] PLL: Fix pll to crtc mapping.

The multiplexer for this lives in the pll blocks and changes in pll to crtc
mapping only take effect when the relevant pll is actually enabled.

This fixes the long standing bug where attaching an external monitor to a
laptop meant that the panel wouldn't be properly reinitialised when returning
to VT.
---
src/rhd_crtc.c | 36 --------------------------------
src/rhd_crtc.h | 10 ++++----
src/rhd_driver.c | 2 -
src/rhd_pll.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/rhd_pll.h | 3 ++
src/rhd_randr.c | 1 -
6 files changed, 68 insertions(+), 44 deletions(-)

diff --git a/src/rhd_crtc.c b/src/rhd_crtc.c
index fbf2b53..0258801 100644
--- a/src/rhd_crtc.c
+++ b/src/rhd_crtc.c
@@ -97,7 +97,6 @@ struct rhdCrtcStore {

CARD32 CrtcBlackColor;
CARD32 CrtcBlankControl;
- CARD32 CrtcPCLKControl;
};

struct rhdFMTStore {
@@ -452,29 +451,6 @@ DxScaleSet(struct rhdCrtc *Crtc, CARD32
}
}
}
-/*
- *
- */
-static void
-D1PLLSelect(struct rhdCrtc *Crtc, struct rhdPLL *PLL)
-{
- RHDFUNC(Crtc);
-
- RHDRegMask(Crtc, PCLK_CRTC1_CNTL, PLL->Id << 16, 0x00010000);
- Crtc->PLL = PLL;
-}
-
-/*
- *
- */
-static void
-D2PLLSelect(struct rhdCrtc *Crtc, struct rhdPLL *PLL)
-{
- RHDFUNC(Crtc);
-
- RHDRegMask(Crtc, PCLK_CRTC2_CNTL, PLL->Id << 16, 0x00010000);
- Crtc->PLL = PLL;
-}

/*
*
@@ -765,11 +741,6 @@ DxSave(struct rhdCrtc *Crtc)
Crtc->Id,Store->CrtcCountControl);
Store->CrtcInterlaceControl = RHDRegRead(Crtc, RegOff +
D1CRTC_INTERLACE_CONTROL);

- if (Crtc->Id == RHD_CRTC_1)
- Store->CrtcPCLKControl = RHDRegRead(Crtc, PCLK_CRTC1_CNTL);
- else
- Store->CrtcPCLKControl = RHDRegRead(Crtc, PCLK_CRTC2_CNTL);
-
Crtc->Store = Store;
}

@@ -867,11 +838,6 @@ DxRestore(struct rhdCrtc *Crtc)
RHDRegWrite(Crtc, RegOff + D1CRTC_COUNT_CONTROL, Store->CrtcCountControl);
RHDRegWrite(Crtc, RegOff + D1CRTC_INTERLACE_CONTROL,
Store->CrtcInterlaceControl);

- if (Crtc->Id == RHD_CRTC_1)
- RHDRegWrite(Crtc, PCLK_CRTC1_CNTL, Store->CrtcPCLKControl);
- else
- RHDRegWrite(Crtc, PCLK_CRTC2_CNTL, Store->CrtcPCLKControl);
-
/* When VGA is enabled, it imposes its timing on us, so our CRTC SYNC
* timing can be set to 0. This doesn't always restore properly...
* Workaround is to set a valid sync length for a bit so VGA can
@@ -1009,7 +975,6 @@ RHDCrtcsInit(RHDPtr rhdPtr)
Crtc->ModeSet = DxModeSet;
Crtc->ScaleValid = DxScaleValid;
Crtc->ScaleSet = DxScaleSet;
- Crtc->PLLSelect = D1PLLSelect;
Crtc->LUTSelect = D1LUTSelect;
Crtc->FrameSet = D1ViewPortStart;

@@ -1040,7 +1005,6 @@ RHDCrtcsInit(RHDPtr rhdPtr)
Crtc->ModeSet = DxModeSet;
Crtc->ScaleValid = DxScaleValid;
Crtc->ScaleSet = DxScaleSet;
- Crtc->PLLSelect = D2PLLSelect;
Crtc->LUTSelect = D2LUTSelect;
Crtc->FrameSet = D2ViewPortStart;

diff --git a/src/rhd_crtc.h b/src/rhd_crtc.h
index c4e2a64..e1d330c 100644
--- a/src/rhd_crtc.h
+++ b/src/rhd_crtc.h
@@ -50,8 +50,8 @@ struct rhdCrtc {
int X, Y; /* Current frame */
int MinX, MinY, MaxX, MaxY; /* Panning Area: Max != 0 if used */

- struct rhdPLL *PLL; /* Currently attached PLL */
- struct rhdLUT *LUT; /* Currently attached LUT */
+ struct rhdPLL *PLL; /* Currently attached PLL: move to private */
+ struct rhdLUT *LUT; /* Currently attached LUT: move to private */
struct rhdCursor *Cursor; /* Fixed to the MODE engine */

DisplayModePtr CurrentMode;
@@ -75,7 +75,8 @@ struct rhdCrtc {

void (*FrameSet) (struct rhdCrtc *Crtc, CARD16 X, CARD16 Y);

- void (*PLLSelect) (struct rhdCrtc *Crtc, struct rhdPLL *PLL);
+ /* callback for pll setting lives here */
+ /* callback for lut setting lives here */
void (*LUTSelect) (struct rhdCrtc *Crtc, struct rhdLUT *LUT);

void (*Power) (struct rhdCrtc *Crtc, int Power);
@@ -85,12 +86,11 @@ struct rhdCrtc {
void (*Save) (struct rhdCrtc *Crtc);
void (*Restore) (struct rhdCrtc *Crtc);

+ /* move to private */
struct rhdFMTStore *FMTStore;
void (*FMTModeSet)(struct rhdCrtc *Crtc, struct rhdFMTDither *FMTDither);
void (*FMTSave)(struct rhdCrtc *Crtc);
void (*FMTRestore)(struct rhdCrtc *Crtc);
-
- /* Gamma, scaling */
};

void RHDCrtcsInit(RHDPtr rhdPtr);
diff --git a/src/rhd_driver.c b/src/rhd_driver.c
index 7494ade..f7b92cb 100644
--- a/src/rhd_driver.c
+++ b/src/rhd_driver.c
@@ -1980,7 +1980,6 @@ rhdSetMode(ScrnInfoPtr pScrn, DisplayMod
if (Crtc->ScaleSet)
Crtc->ScaleSet(Crtc, RHD_CRTC_SCALE_TYPE_NONE, mode, NULL);
RHDPLLSet(Crtc->PLL, mode->Clock);
- Crtc->PLLSelect(Crtc, Crtc->PLL);
Crtc->LUTSelect(Crtc, Crtc->LUT);
RHDOutputsMode(rhdPtr, Crtc, mode);
}
@@ -1994,7 +1993,6 @@ rhdSetMode(ScrnInfoPtr pScrn, DisplayMod
if (Crtc->ScaleSet)
Crtc->ScaleSet(Crtc, RHD_CRTC_SCALE_TYPE_NONE, mode, NULL);
RHDPLLSet(Crtc->PLL, mode->Clock);
- Crtc->PLLSelect(Crtc, Crtc->PLL);
Crtc->LUTSelect(Crtc, Crtc->LUT);
RHDOutputsMode(rhdPtr, Crtc, mode);
}
diff --git a/src/rhd_pll.c b/src/rhd_pll.c
index 6a07b8c..eae6af4 100644
--- a/src/rhd_pll.c
+++ b/src/rhd_pll.c
@@ -37,6 +37,7 @@
#endif

#include "rhd.h"
+#include "rhd_crtc.h"
#include "rhd_pll.h"
#include "rhd_regs.h"
#include "rhd_atombios.h"
@@ -387,6 +388,12 @@ R500PLL1Set(struct rhdPLL *PLL, CARD16 R
RHDRegMask(PLL, P1PLL_INT_SS_CNTL, 0, 0x00000001);

R500PLL1SetLow(PLL, RefDiv, FBDiv, PostDiv, Control);
+
+ if (rhdPtr->Crtc[0]->PLL == PLL)
+ RHDRegMask(PLL, PCLK_CRTC1_CNTL, 0, 0x00010000);
+
+ if (rhdPtr->Crtc[1]->PLL == PLL)
+ RHDRegMask(PLL, PCLK_CRTC2_CNTL, 0, 0x00010000);
}

/*
@@ -426,6 +433,12 @@ R500PLL2Set(struct rhdPLL *PLL, CARD16 R
RHDRegMask(PLL, P2PLL_INT_SS_CNTL, 0, 0x00000001);

R500PLL2SetLow(PLL, RefDiv, FBDiv, PostDiv, Control);
+
+ if (rhdPtr->Crtc[0]->PLL == PLL)
+ RHDRegMask(PLL, PCLK_CRTC1_CNTL, 0x00010000, 0x00010000);
+
+ if (rhdPtr->Crtc[1]->PLL == PLL)
+ RHDRegMask(PLL, PCLK_CRTC2_CNTL, 0x00010000, 0x00010000);
}

/*
@@ -442,6 +455,8 @@ R500PLL1Save(struct rhdPLL *PLL)
PLL->StorePostDiv = RHDRegRead(PLL, EXT1_PPLL_POST_DIV);
PLL->StoreControl = RHDRegRead(PLL, EXT1_PPLL_CNTL);
PLL->StoreSpreadSpectrum = RHDRegRead(PLL, P1PLL_INT_SS_CNTL);
+ PLL->StoreCrtc1Owner = !(RHDRegRead(PLL, PCLK_CRTC1_CNTL) & 0x00010000);
+ PLL->StoreCrtc2Owner = !(RHDRegRead(PLL, PCLK_CRTC2_CNTL) & 0x00010000);

PLL->Stored = TRUE;
}
@@ -460,6 +475,8 @@ R500PLL2Save(struct rhdPLL *PLL)
PLL->StorePostDiv = RHDRegRead(PLL, EXT2_PPLL_POST_DIV);
PLL->StoreControl = RHDRegRead(PLL, EXT2_PPLL_CNTL);
PLL->StoreSpreadSpectrum = RHDRegRead(PLL, P2PLL_INT_SS_CNTL);
+ PLL->StoreCrtc1Owner = RHDRegRead(PLL, PCLK_CRTC1_CNTL) & 0x00010000;
+ PLL->StoreCrtc2Owner = RHDRegRead(PLL, PCLK_CRTC2_CNTL) & 0x00010000;

PLL->Stored = TRUE;
}
@@ -493,6 +510,11 @@ R500PLL1Restore(struct rhdPLL *PLL)
RHDRegWrite(PLL, EXT1_PPLL_CNTL, PLL->StoreControl);
RHDRegWrite(PLL, P1PLL_INT_SS_CNTL, PLL->StoreSpreadSpectrum);
}
+
+ if (PLL->StoreCrtc1Owner)
+ RHDRegMask(PLL, PCLK_CRTC1_CNTL, 0, 0x00010000);
+ if (PLL->StoreCrtc2Owner)
+ RHDRegMask(PLL, PCLK_CRTC2_CNTL, 0, 0x00010000);
}

/*
@@ -524,6 +546,11 @@ R500PLL2Restore(struct rhdPLL *PLL)
RHDRegWrite(PLL, EXT2_PPLL_CNTL, PLL->StoreControl);
RHDRegWrite(PLL, P2PLL_INT_SS_CNTL, PLL->StoreSpreadSpectrum);
}
+
+ if (PLL->StoreCrtc1Owner)
+ RHDRegMask(PLL, PCLK_CRTC1_CNTL, 0x00010000, 0x00010000);
+ if (PLL->StoreCrtc2Owner)
+ RHDRegMask(PLL, PCLK_CRTC2_CNTL, 0x00010000, 0x00010000);
}

/*
@@ -718,6 +745,7 @@ RV620PLL1SetLow(struct rhdPLL *PLL, CARD
CARD8 ScalerDiv, CARD8 SymPostDiv, CARD32 Control)
{
RHDFUNC(PLL);
+
/* switch to external */
RHDRegWrite(PLL, EXT1_PPLL_POST_DIV_SRC, 0);
RHDRegMask(PLL, P1PLL_DISP_CLK_CNTL, 0x00000200, 0x00000300);
@@ -766,6 +794,8 @@ static void
RV620PLL2SetLow(struct rhdPLL *PLL, CARD32 RefDiv, CARD32 FBDiv, CARD32
PostDiv,
CARD8 ScalerDiv, CARD8 SymPostDiv, CARD32 Control)
{
+ RHDFUNC(PLL);
+
/* switch to external */
RHDRegWrite(PLL, EXT2_PPLL_POST_DIV_SRC, 0);
RHDRegMask(PLL, P2PLL_DISP_CLK_CNTL, 0x00000200, 0x00000300);
@@ -814,6 +844,7 @@ static void
RV620PLL1Set(struct rhdPLL *PLL, CARD16 ReferenceDivider,
CARD16 FeedbackDivider, CARD8 PostDivider)
{
+ RHDPtr rhdPtr = RHDPTRI(PLL);
Bool HasDccg = RV620DCCGCLKAvailable(PLL);
CARD32 RefDiv, FBDiv, PostDiv, Control;
CARD8 ScalerDiv, SymPostDiv;
@@ -844,6 +875,12 @@ RV620PLL1Set(struct rhdPLL *PLL, CARD16
RV620PLL1SetLow(PLL, RefDiv, FBDiv, PostDiv, ScalerDiv, SymPostDiv,
Control);

+ if (rhdPtr->Crtc[0]->PLL == PLL)
+ RHDRegMask(PLL, PCLK_CRTC1_CNTL, 0, 0x00010000);
+
+ if (rhdPtr->Crtc[1]->PLL == PLL)
+ RHDRegMask(PLL, PCLK_CRTC2_CNTL, 0, 0x00010000);
+
if (HasDccg)
RV620DCCGCLKSet(PLL, RV620_DCCGCLK_GRAB);
}
@@ -855,6 +892,7 @@ static void
RV620PLL2Set(struct rhdPLL *PLL, CARD16 ReferenceDivider,
CARD16 FeedbackDivider, CARD8 PostDivider)
{
+ RHDPtr rhdPtr = RHDPTRI(PLL);
Bool HasDccg = RV620DCCGCLKAvailable(PLL);
CARD32 RefDiv, FBDiv, PostDiv, Control;
CARD8 ScalerDiv, SymPostDiv;
@@ -885,6 +923,12 @@ RV620PLL2Set(struct rhdPLL *PLL, CARD16
RV620PLL2SetLow(PLL, RefDiv, FBDiv, PostDiv, ScalerDiv, SymPostDiv,
Control);

+ if (rhdPtr->Crtc[0]->PLL == PLL)
+ RHDRegMask(PLL, PCLK_CRTC1_CNTL, 0x00010000, 0x00010000);
+
+ if (rhdPtr->Crtc[1]->PLL == PLL)
+ RHDRegMask(PLL, PCLK_CRTC2_CNTL, 0x00010000, 0x00010000);
+
if (HasDccg)
RV620DCCGCLKSet(PLL, RV620_DCCGCLK_GRAB);
}
@@ -910,6 +954,9 @@ RV620PLL1Save(struct rhdPLL *PLL)
PLL->StoreScalerPostDiv = RHDRegRead(PLL, P1PLL_DISP_CLK_CNTL) & 0x003F;
PLL->StoreSymPostDiv = RHDRegRead(PLL, EXT1_SYM_PPLL_POST_DIV) & 0x007F;

+ PLL->StoreCrtc1Owner = !(RHDRegRead(PLL, PCLK_CRTC1_CNTL) & 0x00010000);
+ PLL->StoreCrtc2Owner = !(RHDRegRead(PLL, PCLK_CRTC2_CNTL) & 0x00010000);
+
PLL->StoreDCCGCLKOwner = RV620DCCGCLKAvailable(PLL);
if (PLL->StoreDCCGCLKOwner)
PLL->StoreDCCGCLK = RHDRegRead(PLL, DCCG_DISP_CLK_SRCSEL);
@@ -940,6 +987,9 @@ RV620PLL2Save(struct rhdPLL *PLL)
PLL->StoreScalerPostDiv = RHDRegRead(PLL, P2PLL_DISP_CLK_CNTL) & 0x003F;
PLL->StoreSymPostDiv = RHDRegRead(PLL, EXT2_SYM_PPLL_POST_DIV) & 0x007F;

+ PLL->StoreCrtc1Owner = RHDRegRead(PLL, PCLK_CRTC1_CNTL) & 0x00010000;
+ PLL->StoreCrtc2Owner = RHDRegRead(PLL, PCLK_CRTC2_CNTL) & 0x00010000;
+
PLL->StoreDCCGCLKOwner = RV620DCCGCLKAvailable(PLL);
if (PLL->StoreDCCGCLKOwner)
PLL->StoreDCCGCLK = RHDRegRead(PLL, DCCG_DISP_CLK_SRCSEL);
@@ -994,6 +1044,11 @@ RV620PLL1Restore(struct rhdPLL *PLL)
RHDRegMask(PLL, P1PLL_CNTL, 0, 0x00002000);
}

+ if (PLL->StoreCrtc1Owner)
+ RHDRegMask(PLL, PCLK_CRTC1_CNTL, 0, 0x00010000);
+ if (PLL->StoreCrtc2Owner)
+ RHDRegMask(PLL, PCLK_CRTC2_CNTL, 0, 0x00010000);
+
if (PLL->StoreDCCGCLKOwner)
RHDRegWrite(PLL, DCCG_DISP_CLK_SRCSEL, PLL->StoreDCCGCLK);
}
@@ -1034,6 +1089,11 @@ RV620PLL2Restore(struct rhdPLL *PLL)
RHDRegMask(PLL, P2PLL_CNTL, 0, 0x00002000);
}

+ if (PLL->StoreCrtc1Owner)
+ RHDRegMask(PLL, PCLK_CRTC1_CNTL, 0x00010000, 0x00010000);
+ if (PLL->StoreCrtc2Owner)
+ RHDRegMask(PLL, PCLK_CRTC2_CNTL, 0x00010000, 0x00010000);
+
if (PLL->StoreDCCGCLKOwner)
RHDRegWrite(PLL, DCCG_DISP_CLK_SRCSEL, PLL->StoreDCCGCLK);
}
diff --git a/src/rhd_pll.h b/src/rhd_pll.h
index 0e6b2b6..c5ed0e0 100644
--- a/src/rhd_pll.h
+++ b/src/rhd_pll.h
@@ -58,7 +58,10 @@ struct rhdPLL {

/* For save/restore: Move to a Private */
Bool Stored;
+
Bool StoreActive;
+ Bool StoreCrtc1Owner;
+ Bool StoreCrtc2Owner;
CARD32 StoreRefDiv;
CARD32 StoreFBDiv;
CARD32 StorePostDiv;
diff --git a/src/rhd_randr.c b/src/rhd_randr.c
index 9bf2feb..fffc78a 100644
--- a/src/rhd_randr.c
+++ b/src/rhd_randr.c
@@ -364,7 +364,6 @@ rhdRRCrtcModeSet(xf86CrtcPtr crtc,
Crtc->FrameSet(Crtc, x, y);
rhdUpdateCrtcPos(Crtc, Crtc->Cursor->X, Crtc->Cursor->Y);
RHDPLLSet(Crtc->PLL, Mode->Clock); /* This also powers up PLL */
- Crtc->PLLSelect(Crtc, Crtc->PLL);
Crtc->LUTSelect(Crtc, Crtc->LUT);
}
static void
--
1.4.3.4

< Previous Next >
Follow Ups