summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Bennett <sb476@cam.ac.uk>2008-10-23 02:35:30 +0100
committerStuart Bennett <sb476@cam.ac.uk>2008-10-24 01:28:57 +0100
commit48581da4d0e1663456ddcbf7a456029cf961d4cd (patch)
treeb8989c7ad4ba2268e14ad5dd23a129b390452737
parent1c7bee95610a47175064b17afd6aa2a45e311b1a (diff)
Attempt to make the usage of cr44 rational instead of cargoculted
and a couple of minor cleanups in nv_crtc
-rw-r--r--src/nv_crtc.c29
-rw-r--r--src/nv_driver.c1
-rw-r--r--src/nv_hw.c25
-rw-r--r--src/nv_setup.c7
-rw-r--r--src/nv_type.h1
5 files changed, 39 insertions, 24 deletions
diff --git a/src/nv_crtc.c b/src/nv_crtc.c
index 9c11997..1040aea 100644
--- a/src/nv_crtc.c
+++ b/src/nv_crtc.c
@@ -75,8 +75,6 @@ void NVCrtcLockUnlock(xf86CrtcPtr crtc, bool lock)
struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
NVPtr pNv = NVPTR(crtc->scrn);
- if (pNv->twoHeads)
- NVSetOwner(pNv, nv_crtc->head);
NVLockVgaCrtc(pNv, nv_crtc->head, lock);
}
@@ -927,9 +925,6 @@ nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output mode on CRTC %d:\n", nv_crtc->head);
xf86PrintModeline(pScrn->scrnIndex, adjusted_mode);
- if (pNv->twoHeads)
- NVSetOwner(pNv, nv_crtc->head);
-
nv_crtc_mode_set_vga(crtc, mode, adjusted_mode);
/* calculated in output_prepare, nv40 needs it written before calculating PLLs */
@@ -962,9 +957,11 @@ nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
static void nv_crtc_save(xf86CrtcPtr crtc)
{
- ScrnInfoPtr pScrn = crtc->scrn;
struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- NVPtr pNv = NVPTR(pScrn);
+ NVPtr pNv = NVPTR(crtc->scrn);
+
+ if (pNv->twoHeads)
+ NVSetOwner(pNv, nv_crtc->head);
/* We just came back from terminal, so unlock */
NVCrtcLockUnlock(crtc, false);
@@ -983,18 +980,15 @@ static void nv_crtc_save(xf86CrtcPtr crtc)
static void nv_crtc_restore(xf86CrtcPtr crtc)
{
- ScrnInfoPtr pScrn = crtc->scrn;
struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- NVPtr pNv = NVPTR(pScrn);
- RIVA_HW_STATE *state;
- NVCrtcRegPtr savep;
-
- state = &pNv->SavedReg;
- savep = &pNv->SavedReg.crtc_reg[nv_crtc->head];
+ NVPtr pNv = NVPTR(crtc->scrn);
/* Just to be safe */
NVCrtcLockUnlock(crtc, false);
+ if (pNv->twoHeads)
+ NVSetOwner(pNv, nv_crtc->head);
+
NVVgaProtect(pNv, nv_crtc->head, true);
nv_crtc_load_state_ramdac(crtc, &pNv->SavedReg);
nv_crtc_load_state_ext(crtc, &pNv->SavedReg);
@@ -1012,6 +1006,9 @@ static void nv_crtc_prepare(xf86CrtcPtr crtc)
NVPtr pNv = NVPTR(pScrn);
struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
+ if (pNv->twoHeads)
+ NVSetOwner(pNv, nv_crtc->head);
+
/* Just in case */
NVCrtcLockUnlock(crtc, 0);
@@ -1511,10 +1508,8 @@ static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
regp->unk850 = NVCrtcReadCRTC(crtc, NV_CRTC_0850);
regp->gpio_ext = NVCrtcReadCRTC(crtc, NV_CRTC_GPIO_EXT);
}
- if (pNv->twoHeads) {
+ if (pNv->twoHeads)
regp->head = NVCrtcReadCRTC(crtc, NV_CRTC_FSEL);
- regp->crtcOwner = NVReadVgaCrtc(pNv, nv_crtc->head, NV_CIO_CRE_44);
- }
regp->cursorConfig = NVCrtcReadCRTC(crtc, NV_CRTC_CURSOR_CONFIG);
}
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 4a563c7..251b42f 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1790,7 +1790,6 @@ NVRestore(ScrnInfoPtr pScrn)
}
if (pNv->twoHeads) {
- NVSetOwner(pNv, 0); /* move to head A to set owner */
NVLockVgaCrtc(pNv, 0, false);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Restoring CRTC_OWNER to %d.\n", pNv->vtOWNER);
NVSetOwner(pNv, pNv->vtOWNER);
diff --git a/src/nv_hw.c b/src/nv_hw.c
index 5318c61..5934c31 100644
--- a/src/nv_hw.c
+++ b/src/nv_hw.c
@@ -138,7 +138,8 @@ uint8_t NVReadVgaCrtc5758(NVPtr pNv, int head, uint8_t index)
uint8_t NVReadPRMVIO(NVPtr pNv, int head, uint32_t reg)
{
- /* Only NV4x have two pvio ranges */
+ /* Only NV4x have two pvio ranges; other twoHeads cards MUST call
+ * NVSetOwner for the relevant head to be programmed */
if (head && pNv->Architecture == NV_ARCH_40)
reg += NV_PRMVIO_SIZE;
@@ -148,7 +149,8 @@ uint8_t NVReadPRMVIO(NVPtr pNv, int head, uint32_t reg)
void NVWritePRMVIO(NVPtr pNv, int head, uint32_t reg, uint8_t value)
{
- /* Only NV4x have two pvio ranges */
+ /* Only NV4x have two pvio ranges; other twoHeads cards MUST call
+ * NVSetOwner for the relevant head to be programmed */
if (head && pNv->Architecture == NV_ARCH_40)
reg += NV_PRMVIO_SIZE;
@@ -238,7 +240,21 @@ void NVVgaProtect(NVPtr pNv, int head, bool protect)
NVSetEnablePalette(pNv, head, protect);
}
-/* owner parameter is slightly abused:
+/* CR44 takes values 0 (head A), 3 (head B) and 4 (heads tied)
+ * it affects only the 8 bit vga io regs, which we access using mmio at
+ * 0xc{0,2}3c*, 0x60{1,3}3*, and 0x68{1,3}3d*
+ * in general, the set value of cr44 does not matter: reg access works as
+ * expected and values can be set for the appropriate head by using a 0x2000
+ * offset as required
+ * however:
+ * a) pre nv40, the head B range of PRMVIO regs at 0xc23c* was not exposed and
+ * cr44 must be set to 0 or 3 for accessing values on the correct head
+ * through the common 0xc03c* addresses
+ * b) in tied mode (4) head B is programmed to the values set on head A, and
+ * access using the head B addresses can have strange results, ergo we leave
+ * tied mode in init once we know to what cr44 should be restored on exit
+ *
+ * the owner parameter is slightly abused:
* 0 and 1 are treated as head values and so the set value is (owner * 3)
* other values are treated as literal values to set
*/
@@ -1139,6 +1155,9 @@ void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save)
uint8_t misc, gr4, gr5, gr6, seq2, seq4;
int i;
+ if (pNv->twoHeads)
+ NVSetOwner(pNv, 0);
+
NVSetEnablePalette(pNv, 0, true);
graphicsmode = NVReadVgaAttr(pNv, 0, NV_CIO_AR_MODE_INDEX) & 1;
NVSetEnablePalette(pNv, 0, false);
diff --git a/src/nv_setup.c b/src/nv_setup.c
index 5d73afc..c2a8935 100644
--- a/src/nv_setup.c
+++ b/src/nv_setup.c
@@ -479,14 +479,12 @@ NVCommonSetup(ScrnInfoPtr pScrn)
else {
uint8_t slaved_on_A, slaved_on_B;
- NVSetOwner(pNv, 1);
NVLockVgaCrtc(pNv, 1, false);
slaved_on_B = NVReadVgaCrtc(pNv, 1, NV_CIO_CRE_PIXEL_INDEX) & 0x80;
if (slaved_on_B)
tvB = !(NVReadVgaCrtc(pNv, 1, NV_CIO_CRE_LCD__INDEX) & NV_CIO_CRE_LCD_LCD_SELECT);
- NVSetOwner(pNv, 0);
NVLockVgaCrtc(pNv, 0, false);
slaved_on_A = NVReadVgaCrtc(pNv, 0, NV_CIO_CRE_PIXEL_INDEX) & 0x80;
@@ -507,6 +505,11 @@ NVCommonSetup(ScrnInfoPtr pScrn)
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initial CRTC_OWNER is %d\n", pNv->vtOWNER);
+
+ /* we need to ensure the heads are not tied henceforth, or
+ * reading any 8 bit reg on head B will fail
+ * setting a single arbitrary head solves that */
+ NVSetOwner(pNv, 0);
}
/* Parse the bios to initialize the card */
diff --git a/src/nv_type.h b/src/nv_type.h
index 88377b1..41779e6 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -145,7 +145,6 @@ typedef struct _nv_crtc_reg
uint8_t Attribute[21];
unsigned char DAC[768]; /* Internal Colorlookuptable */
uint32_t cursorConfig;
- uint32_t crtcOwner;
uint32_t gpio;
uint32_t gpio_ext;
uint32_t unk830;