From 9eaaf46fba0f935399fd1823a5e892e7e81af4af Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Tue, 6 Apr 2004 09:25:31 +0000 Subject: [PATCH] various fixes tested on NM2070 (works now) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7170 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../accelerants/neomagic/SetDisplayMode.c | 5 +- .../accelerants/neomagic/engine/nm_crtc.c | 56 +++++++++++++++++-- .../accelerants/neomagic/engine/nm_general.c | 36 ++++++++++-- .../accelerants/neomagic/engine/nm_proto.h | 1 + 4 files changed, 86 insertions(+), 12 deletions(-) diff --git a/src/add-ons/accelerants/neomagic/SetDisplayMode.c b/src/add-ons/accelerants/neomagic/SetDisplayMode.c index 2577ec9061..1e3625372a 100644 --- a/src/add-ons/accelerants/neomagic/SetDisplayMode.c +++ b/src/add-ons/accelerants/neomagic/SetDisplayMode.c @@ -3,7 +3,7 @@ This file may be used under the terms of the Be Sample Code License. Other authors: - Rudolf Cornelissen 4/2003-3/2004 + Rudolf Cornelissen 4/2003-4/2004 */ #define MODULE_BIT 0x00200000 @@ -73,6 +73,9 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) /* disable interrupts using the kernel driver */ interrupt_enable(false); + /* make sure the card's registers are unlocked (KB output select may lock!) */ + nm_unlock(); + /* find current DPMS state, then turn off screen(s) */ nm_crtc_dpms_fetch(&display, &h, &v); nm_crtc_dpms(false, false, false); diff --git a/src/add-ons/accelerants/neomagic/engine/nm_crtc.c b/src/add-ons/accelerants/neomagic/engine/nm_crtc.c index 4ad7d9b3a0..6496a658b8 100644 --- a/src/add-ons/accelerants/neomagic/engine/nm_crtc.c +++ b/src/add-ons/accelerants/neomagic/engine/nm_crtc.c @@ -1,6 +1,6 @@ /* CTRC functionality */ /* Author: - Rudolf Cornelissen 4/2003-3/2004 + Rudolf Cornelissen 4/2003-4/2004 */ #define MODULE_BIT 0x00040000 @@ -179,7 +179,7 @@ status_t nm_crtc_set_timing(display_mode target, bool crt_only) ISACRTCW(VDISPE, (vdisp_e & 0xff)); ISACRTCW(VBLANKS, (vblnk_s & 0xff)); ISACRTCW(VBLANKE, (vblnk_e & 0xff)); -//linux: +//linux: (BIOSmode) // regp->CRTC[23] = 0xC3; ISACRTCW(LINECOMP, (linecomp & 0xff)); @@ -262,7 +262,7 @@ status_t nm_crtc_set_timing(display_mode target, bool crt_only) ISACRTCW(MAXSCLIN, (temp | ((linecomp & 0x200) >> (9 - 6)))); ISACRTCW(VDISPE, (vdisp_e & 0xff)); -//linux: +//linux:(BIOSmode) // regp->CRTC[23] = 0xC3; ISACRTCW(LINECOMP, (linecomp & 0xff)); @@ -286,6 +286,48 @@ status_t nm_crtc_set_timing(display_mode target, bool crt_only) } } + /* program 'fixed' mode if needed */ + if (si->ps.card_type != NM2070) + { + uint8 width; + + temp = ISAGRPHR(PANELCTRL1); + /* we need to wait a bit or the card will mess-up it's register values.. */ + snooze(10); + + switch (target.timing.h_display) + { + case 1280: + width = (3 << 5); + break; + case 1024: + width = (2 << 5); + break; + case 800: + width = (1 << 5); + break; + case 640: + default: //fixme: non-std modes should be in between above modes?!? + width = (0 << 5); + break; + } + + switch (si->ps.card_type) + { + case NM2090: + case NM2093: + case NM2097: + case NM2160: + //fixme: checkout b6???? + ISAGRPHW(PANELCTRL1, ((temp & ~0x20) | (width & 0x20))); + break; + default: + /* NM2200 and later */ + ISAGRPHW(PANELCTRL1, ((temp & ~0x60) | (width & 0x60))); + break; + } + } + return B_OK; } @@ -409,7 +451,8 @@ status_t nm_crtc_set_display_pitch() //fixme: test for max supported pitch if possible, //not all bits below will be implemented. //NM2160: confirmed b0 and b1 in register below to exist and work. - ISAGRPHW(CRTC_PITCHE, ((offset & 0xff00) >> 8)); + if (si->ps.card_type != NM2070) + ISAGRPHW(CRTC_PITCHE, ((offset & 0xff00) >> 8)); return B_OK; } @@ -460,6 +503,9 @@ status_t nm_crtc_set_display_start(uint32 startadd,uint8 bpp) /* setup centering mode for current internal or simultaneous flatpanel mode */ status_t nm_crtc_center(display_mode target) { + /* note: + * NM2070 apparantly doesn't support horizontal centering this way... */ + uint8 vcent1, vcent2, vcent3, vcent4, vcent5; uint8 hcent1, hcent2, hcent3, hcent4, hcent5; uint8 ctrl2, ctrl3; @@ -478,7 +524,6 @@ status_t nm_crtc_center(display_mode target) /* adjust for register contraints: * horizontal center granularity is 16 pixels */ hoffset = ((hoffset >> 4) - 1); -//fixme: what does this do? /* turn on horizontal centering? */ ctrl3 = 0x10; } @@ -489,7 +534,6 @@ status_t nm_crtc_center(display_mode target) /* adjust for register contraints: * vertical center granularity is 2 pixels */ voffset = ((voffset >> 1) - 2); -//fixme: what does this do? /* turn on vertical centering? */ ctrl2 = 0x01; } diff --git a/src/add-ons/accelerants/neomagic/engine/nm_general.c b/src/add-ons/accelerants/neomagic/engine/nm_general.c index 16e585d769..641b16e221 100644 --- a/src/add-ons/accelerants/neomagic/engine/nm_general.c +++ b/src/add-ons/accelerants/neomagic/engine/nm_general.c @@ -1,5 +1,5 @@ /* Author: - Rudolf Cornelissen 4/2003-3/2004 + Rudolf Cornelissen 4/2003-4/2004 */ #define MODULE_BIT 0x00008000 @@ -47,7 +47,7 @@ status_t nm_general_powerup() { status_t status; - LOG(1,("POWERUP: Neomagic (open)BeOS Accelerant 0.06-7 running.\n")); + LOG(1,("POWERUP: Neomagic (open)BeOS Accelerant 0.06-8 running.\n")); /* detect card type and power it up */ switch(CFGR(DEVID)) @@ -151,6 +151,12 @@ status_t nm_set_cas_latency() return B_ERROR; } +void nm_unlock() +{ + /* unlock cards GRAPHICS registers (any other value than 0x26 should lock it again) */ + ISAGRPHW(GRPHXLOCK, 0x26); +} + static status_t nmxxxx_general_powerup() { uint8 temp; @@ -178,7 +184,7 @@ static status_t nmxxxx_general_powerup() dump_specs(); /* activate PCI access: b7 = framebuffer, b6 = registers */ - ISAGRPHW(IFACECTRL, 0xc0); + ISAGRPHW(IFACECTRL2, 0xc0); /* disable VGA-mode cursor (just to be sure) */ ISACRTCW(VGACURCTRL, 0x00); @@ -310,6 +316,8 @@ uint8 nm_general_output_read() static status_t nm_general_bios_to_powergraphics() { + uint8 temp; + LOG(2, ("INIT: Skipping card coldstart!\n")); /* turn off display */ @@ -322,7 +330,9 @@ status_t nm_general_bios_to_powergraphics() * switch to graphics mode ... */ ISASEQW(MEMMODE, 0x0e); /* ... disable bitplane tweaking ... */ - ISAGRPHW(ENSETRESET, 0x00); + /* note: + * NeoMagic cards have custom b4-b7 use in this register! */ + ISAGRPHW(ENSETRESET, 0x80); /* ... no logical function tweaking with display data, no data rotation ... */ ISAGRPHW(DATAROTATE, 0x00); /* ... reset read map select to plane 0 ... */ @@ -342,8 +352,14 @@ status_t nm_general_bios_to_powergraphics() ISAATBW(COLPLANE_EN, 0x0f); /* ... reset horizontal pixelpanning ... */ ISAATBW(HORPIXPAN, 0x00); - /* ... and reset colorpalette groupselect bits. */ + /* ... reset colorpalette groupselect bits ... */ ISAATBW(COLSEL, 0x00); + /* ... do unknown standard VGA register ... */ + /* note: + * NeoMagic cards have custom b6 use in this register! */ + ISAATBW(0x16, 0x01); + /* ... and enable all four byteplanes. */ + ISASEQW(MAPMASK, 0x0f); /* setup sequencer clocking mode */ ISASEQW(CLKMODE, 0x21); @@ -351,6 +367,16 @@ status_t nm_general_bios_to_powergraphics() /* enable memory above 256Kb: set b4 (disables adress wraparound at 256Kb boundary) */ ISAGRPHW(FBSTADDE, 0x10); + /* this register has influence on the CRTC framebuffer offset, so reset! */ + //fixme: investigate further... + ISAGRPHW(0x15, 0x00); + + /* enable fast PCI write bursts (b4-5) */ + temp = ((ISAGRPHR(IFACECTRL1) & 0x0f) | 0x30); + /* we need to wait a bit or the card will mess-up it's register values.. */ + snooze(10); + ISAGRPHW(IFACECTRL1, temp); + /* this speeds up RAM writes according to XFree driver */ // fixme: don't touch until more is known: part of RAM or CORE PLL??? // ISAGRPHW(SPEED, 0xc0); diff --git a/src/add-ons/accelerants/neomagic/engine/nm_proto.h b/src/add-ons/accelerants/neomagic/engine/nm_proto.h index 376dff1e5b..95054996ee 100644 --- a/src/add-ons/accelerants/neomagic/engine/nm_proto.h +++ b/src/add-ons/accelerants/neomagic/engine/nm_proto.h @@ -1,6 +1,7 @@ /*general card functions*/ status_t nm_general_powerup(void); status_t nm_set_cas_latency(void); +void nm_unlock(void); status_t nm_general_output_select(void); uint8 nm_general_output_read(void); status_t nm_general_dac_select(int);