diff options
author | Stuart Bennett <sb476@cam.ac.uk> | 2008-10-23 02:35:30 +0100 |
---|---|---|
committer | Stuart Bennett <sb476@cam.ac.uk> | 2008-10-24 01:28:57 +0100 |
commit | 48581da4d0e1663456ddcbf7a456029cf961d4cd (patch) | |
tree | b8989c7ad4ba2268e14ad5dd23a129b390452737 | |
parent | 1c7bee95610a47175064b17afd6aa2a45e311b1a (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.c | 29 | ||||
-rw-r--r-- | src/nv_driver.c | 1 | ||||
-rw-r--r-- | src/nv_hw.c | 25 | ||||
-rw-r--r-- | src/nv_setup.c | 7 | ||||
-rw-r--r-- | src/nv_type.h | 1 |
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; |