From 255e5021d1e6ec50bafedbb7eae9cd5eb47ea6b2 Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Mon, 19 Jan 2004 21:31:05 +0000 Subject: [PATCH] we now have DUALHEAD! git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6150 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../private/graphics/nvidia/DriverInterface.h | 1 + headers/private/graphics/nvidia/nv_macros.h | 12 +- src/add-ons/accelerants/nvidia/Cursor.c | 129 +++++++++++------- .../accelerants/nvidia/InitAccelerant.c | 2 +- .../accelerants/nvidia/SetDisplayMode.c | 78 ++++------- .../accelerants/nvidia/engine/nv_crtc.c | 36 ++++- .../accelerants/nvidia/engine/nv_crtc2.c | 46 +++++-- .../accelerants/nvidia/engine/nv_dac.c | 11 -- .../accelerants/nvidia/engine/nv_dac2.c | 11 -- .../accelerants/nvidia/engine/nv_general.c | 51 +++++-- 10 files changed, 217 insertions(+), 160 deletions(-) diff --git a/headers/private/graphics/nvidia/DriverInterface.h b/headers/private/graphics/nvidia/DriverInterface.h index 63d947da3e..d92cb76772 100644 --- a/headers/private/graphics/nvidia/DriverInterface.h +++ b/headers/private/graphics/nvidia/DriverInterface.h @@ -137,6 +137,7 @@ typedef struct { uint16 width; /* Width and height of the cursor shape (always 16!) */ uint16 height; bool is_visible; /* Is the cursor currently displayed? */ + bool dh_right; /* Is cursor on right side of stretched screen? */ } cursor; /*colour lookup table*/ diff --git a/headers/private/graphics/nvidia/nv_macros.h b/headers/private/graphics/nvidia/nv_macros.h index 5c156e67ed..55bdb914e6 100644 --- a/headers/private/graphics/nvidia/nv_macros.h +++ b/headers/private/graphics/nvidia/nv_macros.h @@ -510,10 +510,10 @@ #define NV8_PALINDW 0x006813c8 #define NV8_PALDATA 0x006813c9 /* secondary head */ -#define NV8_PAL2MASK 0x006833c6//verify!!! -#define NV8_PAL2INDR 0x006833c7//verify!!! -#define NV8_PAL2INDW 0x006833c8//verify!!! -#define NV8_PAL2DATA 0x006833c9//verify!!! +#define NV8_PAL2MASK 0x006833c6 +#define NV8_PAL2INDR 0x006833c7 +#define NV8_PAL2INDW 0x006833c8 +#define NV8_PAL2DATA 0x006833c9 /* Nvidia PCI direct DAC registers (32bit) */ /* primary head */ @@ -524,8 +524,7 @@ /* secondary head */ #define NVDAC2_CURPOS 0x00682300 #define NVDAC2_PIXPLLC 0x00680520 -#define NVDAC2_PLLSEL 0x00680524//0x0068250c verify!!! -#define NVDAC2_GENCTRL 0x00680618//0x00682600 verify!!! +#define NVDAC2_GENCTRL 0x00682600 /* Nvidia CRTC indexed registers */ /* VGA standard registers: */ @@ -562,6 +561,7 @@ #define NVCRTCX_CURCTL0 0x31 #define NVCRTCX_INTERLACE 0x39 #define NVCRTCX_EXTRA 0x41 +#define NVCRTCX_OWNER 0x44 /* Nvidia ATTRIBUTE indexed registers */ /* VGA standard registers: */ diff --git a/src/add-ons/accelerants/nvidia/Cursor.c b/src/add-ons/accelerants/nvidia/Cursor.c index aa8bd7178e..3ebf8ffc98 100644 --- a/src/add-ons/accelerants/nvidia/Cursor.c +++ b/src/add-ons/accelerants/nvidia/Cursor.c @@ -55,44 +55,9 @@ void MOVE_CURSOR(uint16 x, uint16 y) si->cursor.x = x; si->cursor.y = y; - /*set up minimum amount to scroll*/ - if (si->dm.flags & DUALHEAD_BITS) - { -/* fixme???? Nvidia always does pixelprecise panning on sec head?? */ - switch(si->dm.space) - { - case B_RGB16_LITTLE: - h_adjust = 0x1f; - break; - case B_RGB32_LITTLE: - h_adjust = 0x0f; - break; - default: - h_adjust = 0x1f; - break; - } - } - else - { -/* switch(si->dm.space) - { - case B_CMAP8: - h_adjust = 0x07; - break; - case B_RGB15_LITTLE:case B_RGB16_LITTLE: - h_adjust = 0x03; - break; - case B_RGB32_LITTLE: - h_adjust = 0x01; - break; - default: - h_adjust = 0x07; - break; - } -*/ - /* Nvidia always does pixelprecise panning on primary head */ - h_adjust = 0x00; - } + /* setting up minimum amount to scroll not needed: + * Nvidia cards can always do pixelprecise panning on both heads */ + h_adjust = 0x00; /* adjust h/v_display_start to move cursor onto screen */ switch (si->dm.flags & DUALHEAD_BITS) @@ -141,14 +106,42 @@ void MOVE_CURSOR(uint16 x, uint16 y) if (y > (vds + si->cursor.hot_y)) y -= (vds + si->cursor.hot_y); else y = 0; - /* account for switched CRTC's */ -//fixme: we need new tweaking to get the cursors working together in dualhead modes... -// if (si->switched_crtcs) x -= si->dm.timing.h_display; - /* position the cursor on the display */ - nv_crtc_cursor_position(x,y); -// if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF) + switch (si->dm.flags & DUALHEAD_BITS) + { + case DUALHEAD_CLONE: + nv_crtc_cursor_position(x,y); nv_crtc2_cursor_position(x,y); + break; + case DUALHEAD_ON: + case DUALHEAD_SWITCH: + if (x < si->dm.timing.h_display) + { + if (si->cursor.dh_right) + { + LOG(4,("MOVE_CURSOR: now on left side\n")); + nv_crtc2_cursor_hide(); + nv_crtc_cursor_show(); + si->cursor.dh_right = false; + } + nv_crtc_cursor_position(x, y); + } + else + { + if (!si->cursor.dh_right) + { + LOG(4,("MOVE_CURSOR: now on right side\n")); + nv_crtc_cursor_hide(); + nv_crtc2_cursor_show(); + si->cursor.dh_right = true; + } + nv_crtc2_cursor_position((x - si->dm.timing.h_display), y); + } + break; + default: /* singlehead mode */ + nv_crtc_cursor_position(x,y); + break; + } } void SHOW_CURSOR(bool is_visible) @@ -156,16 +149,48 @@ void SHOW_CURSOR(bool is_visible) /* record for our info */ si->cursor.is_visible = is_visible; - if (is_visible) + switch (si->dm.flags & DUALHEAD_BITS) { - nv_crtc_cursor_show(); -// if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF) + case DUALHEAD_CLONE: + if (is_visible) + { + nv_crtc_cursor_show(); nv_crtc2_cursor_show(); - } - else - { - nv_crtc_cursor_hide(); -// if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF) + } + else + { + nv_crtc_cursor_hide(); nv_crtc2_cursor_hide(); + } + break; + case DUALHEAD_ON: + case DUALHEAD_SWITCH: + if (is_visible) + { + if (!si->cursor.dh_right) + { + nv_crtc_cursor_show(); + } + else + { + nv_crtc2_cursor_show(); + } + } + else + { + nv_crtc_cursor_hide(); + nv_crtc2_cursor_hide(); + } + break; + default: /* singlehead mode */ + if (is_visible) + { + nv_crtc_cursor_show(); + } + else + { + nv_crtc_cursor_hide(); + } + break; } } diff --git a/src/add-ons/accelerants/nvidia/InitAccelerant.c b/src/add-ons/accelerants/nvidia/InitAccelerant.c index 501fddc512..53ecd530e8 100644 --- a/src/add-ons/accelerants/nvidia/InitAccelerant.c +++ b/src/add-ons/accelerants/nvidia/InitAccelerant.c @@ -100,7 +100,6 @@ status_t INIT_ACCELERANT(int the_fd) { if (1) { time_t now = time (NULL); // LOG not available from here to next LOG: NULL si -// MSG(("INIT_ACCELERANT: booted since %f ms %s\n", system_time()/1000.0, real_time_clock())); MSG(("INIT_ACCELERANT: %s", ctime (&now))); } @@ -144,6 +143,7 @@ status_t INIT_ACCELERANT(int the_fd) { si->cursor.hot_y = 0; si->cursor.x = 0; si->cursor.y = 0; + si->cursor.dh_right = false; /* Put the frame buffer immediately following the cursor data. We store this diff --git a/src/add-ons/accelerants/nvidia/SetDisplayMode.c b/src/add-ons/accelerants/nvidia/SetDisplayMode.c index 9163905a49..1e9a10c255 100644 --- a/src/add-ons/accelerants/nvidia/SetDisplayMode.c +++ b/src/add-ons/accelerants/nvidia/SetDisplayMode.c @@ -167,6 +167,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) /* set the outputs */ switch (si->ps.card_type) { + //fixme.. case G550: switch (target.flags & DUALHEAD_BITS) { @@ -260,7 +261,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) //fixme: shut-off the videoPLL if it exists... } - + /* update driver's mode store */ si->dm = target; @@ -274,7 +275,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) /* set up overlay unit for this mode */ nv_bes_init(); - MSG(("SETMODE: booted since %f mS\n", system_time()/1000.0)); + LOG(1,("SETMODE: booted since %f mS\n", system_time()/1000.0)); /* enable interrupts using the kernel driver */ interrupt_enable(true); @@ -299,45 +300,27 @@ status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start) { LOG(4,("MOVE_DISPLAY: h %d, v %d\n", h_display_start, v_display_start)); - /* reset lower bits, don't return an error! */ -//fixme: not needed in dualhead on Nvidia??? (pixelprecise panning on sec. head??) - if (si->dm.flags & DUALHEAD_BITS) + /* nVidia cards support pixelprecise panning on both heads in all modes: + * No stepping granularity needed! */ + + /* determine bits used for the colordepth */ + switch(si->dm.space) { - switch(si->dm.space) - { - case B_RGB16_LITTLE: - colour_depth=16; - h_display_start &= ~0x1f; - break; - case B_RGB32_LITTLE: - colour_depth=32; - h_display_start &= ~0x0f; - break; - default: - LOG(8,("SET:Invalid DH colour depth 0x%08x, should never happen\n", si->dm.space)); - return B_ERROR; - } - } - else - { - /* Nvidia always does pixelprecise panning on primary head */ - switch(si->dm.space) - { - case B_CMAP8: - colour_depth=8; -// h_display_start &= ~0x07; - break; - case B_RGB15_LITTLE: case B_RGB16_LITTLE: - colour_depth=16; -// h_display_start &= ~0x03; - break; - case B_RGB32_LITTLE: - colour_depth=32; -// h_display_start &= ~0x01; - break; - default: - return B_ERROR; - } + case B_CMAP8: + colour_depth=8; + break; + case B_RGB15_LITTLE: + case B_RGB16_LITTLE: + colour_depth=16; + break; + case B_RGB24_LITTLE: + colour_depth=24; + break; + case B_RGB32_LITTLE: + colour_depth=32; + break; + default: + return B_ERROR; } /* do not run past end of display */ @@ -389,9 +372,7 @@ status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start) { return B_OK; } -/* - Set the indexed color palette. -*/ +/* Set the indexed color palette */ void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags) { int i; uint8 *r,*g,*b; @@ -412,17 +393,9 @@ void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags i++; } nv_dac_palette(r,g,b); + if (si->dm.flags & DUALHEAD_BITS) nv_dac2_palette(r,g,b); } - -/* masks for DPMS control bits */ -enum { - H_SYNC_OFF = 0x01, - V_SYNC_OFF = 0x02, - DISPLAY_OFF = 0x04, - BITSMASK = (H_SYNC_OFF | V_SYNC_OFF | DISPLAY_OFF) -}; - /* Put the display into one of the Display Power Management modes. */ status_t SET_DPMS_MODE(uint32 dpms_flags) { interrupt_enable(false); @@ -486,7 +459,6 @@ uint32 DPMS_CAPABILITIES(void) { return (B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF); } - /* Return the current DPMS mode */ uint32 DPMS_MODE(void) { bool display, h, v; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c index 17722caaf7..5405904dee 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c @@ -1,6 +1,6 @@ /* CTRC functionality */ /* Author: - Rudolf Cornelissen 11/2002-9/2003 + Rudolf Cornelissen 11/2002-1/2004 */ #define MODULE_BIT 0x00040000 @@ -124,6 +124,9 @@ status_t nv_crtc_set_timing(display_mode target) /* prevent memory adress counter from being reset (linecomp may not occur) */ linecomp = target.timing.v_display; + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + //fixme: flatpanel 'don't touch' update needed for 'Go' cards!?! if (true) { @@ -273,6 +276,9 @@ status_t nv_crtc_depth(int mode) genctrl = 0x00101130; break; } + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + CRTCW(PIXEL, ((CRTCR(PIXEL) & 0xfc) | viddelay)); DACW(GENCTRL, genctrl); @@ -285,7 +291,11 @@ status_t nv_crtc_dpms(bool display, bool h, bool v) LOG(4,("CRTC: setting DPMS: ")); + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + /* start synchronous reset: required before turning screen off! */ + //fixme: we need to seperate the reset condition from DPMS! SEQW(RESET, 0x01); /* turn screen off */ @@ -332,6 +342,9 @@ status_t nv_crtc_dpms(bool display, bool h, bool v) status_t nv_crtc_dpms_fetch(bool *display, bool *h, bool *v) { + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + *display = !(SEQR(CLKMODE) & 0x20); *h = !(CRTCR(REPAINT1) & 0x80); *v = !(CRTCR(REPAINT1) & 0x40); @@ -358,6 +371,9 @@ status_t nv_crtc_set_display_pitch() LOG(2,("CRTC: offset register set to: $%04x\n", offset)); + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + /*program the card!*/ CRTCW(PITCHL, (offset & 0x00ff)); CRTCW(REPAINT0, ((CRTCR(REPAINT0) & 0x1f) | ((offset & 0x0700) >> 3))); @@ -390,6 +406,9 @@ status_t nv_crtc_set_display_start(uint32 startadd,uint8 bpp) // } // } + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + if (si->ps.card_arch == NV04A) { /* upto 32Mb RAM adressing: must be used this way on pre-NV10! */ @@ -432,6 +451,9 @@ status_t nv_crtc_cursor_init() /* cursor bitmap will be stored at the start of the framebuffer */ const uint32 curadd = 0; + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + /* set cursor bitmap adress ... */ if ((si->ps.card_arch == NV04A) || (si->ps.laptop)) { @@ -469,13 +491,18 @@ status_t nv_crtc_cursor_init() NV_REG32(NV32_CURCONF) = 0x02000100; /* activate hardware cursor */ - CRTCW(CURCTL0, (CRTCR(CURCTL0) | 0x01)); + nv_crtc_cursor_show(); return B_OK; } status_t nv_crtc_cursor_show() { + LOG(4,("CRTC: enabling cursor\n")); + + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + /* b0 = 1 enables cursor */ CRTCW(CURCTL0, (CRTCR(CURCTL0) | 0x01)); @@ -484,6 +511,11 @@ status_t nv_crtc_cursor_show() status_t nv_crtc_cursor_hide() { + LOG(4,("CRTC: disabling cursor\n")); + + /* enable access to CRTC1 on dualhead cards */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + /* b0 = 0 disables cursor */ CRTCW(CURCTL0, (CRTCR(CURCTL0) & 0xfe)); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c index 2c7096e1a4..be1f437a47 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc2.c @@ -109,6 +109,9 @@ status_t nv_crtc2_set_timing(display_mode target) /* prevent memory adress counter from being reset (linecomp may not occur) */ linecomp = target.timing.v_display; + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + //fixme: flatpanel 'don't touch' update needed for 'Go' cards!?! if (true) { @@ -188,9 +191,7 @@ status_t nv_crtc2_set_timing(display_mode target) /* setup HSYNC & VSYNC polarity */ LOG(2,("CRTC2: sync polarity: ")); -//fixme: how is sync polarity programmed for CRTC2? -// temp = NV_REG8(NV8_MISCR); -temp = 0; + temp = NV_REG8(NV8_MISCR); if (target.timing.flags & B_POSITIVE_HSYNC) { LOG(2,("H:pos ")); @@ -211,13 +212,13 @@ temp = 0; LOG(2,("V:neg ")); temp |= 0x80; } -// NV_REG8(NV8_MISCW) = temp; + NV_REG8(NV8_MISCW) = temp; -// LOG(2,(", MISC reg readback: $%02x\n", NV_REG8(NV8_MISCR))); + LOG(2,(", MISC reg readback: $%02x\n", NV_REG8(NV8_MISCR))); } /* always disable interlaced operation */ - /* (interlace is only supported on upto and including NV15 except for NV11) */ + /* (interlace is supported on upto and including NV10, NV15, and NV30 and up) */ CRTC2W(INTERLACE, 0xff); return B_OK; @@ -257,8 +258,10 @@ status_t nv_crtc2_depth(int mode) genctrl = 0x00101130; break; } + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + CRTC2W(PIXEL, ((CRTC2R(PIXEL) & 0xfc) | viddelay)); -//fixme: check if this works... DAC2W(GENCTRL, genctrl); return B_OK; @@ -270,6 +273,9 @@ status_t nv_crtc2_dpms(bool display, bool h, bool v) LOG(4,("CRTC2: setting DPMS: ")); + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + /* start synchronous reset: required before turning screen off! */ //fixme: howto switch display on/off? // SEQW(RESET, 0x01); @@ -318,6 +324,9 @@ status_t nv_crtc2_dpms(bool display, bool h, bool v) status_t nv_crtc2_dpms_fetch(bool *display, bool *h, bool *v) { + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + //fixme: // *display = !(SEQR(CLKMODE) & 0x20); *display = true; @@ -346,6 +355,9 @@ status_t nv_crtc2_set_display_pitch() LOG(2,("CRTC2: offset register set to: $%04x\n", offset)); + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + /*program the card!*/ CRTC2W(PITCHL, (offset & 0x00ff)); CRTC2W(REPAINT0, ((CRTC2R(REPAINT0) & 0x1f) | ((offset & 0x0700) >> 3))); @@ -378,6 +390,9 @@ status_t nv_crtc2_set_display_start(uint32 startadd,uint8 bpp) // } // } + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + /* upto 4Gb RAM adressing: must be used on NV10 and later! */ /* NOTE: * While this register also exists on pre-NV10 cards, it will @@ -400,8 +415,11 @@ status_t nv_crtc2_cursor_init() /* cursor bitmap will be stored at the start of the framebuffer */ const uint32 curadd = 0; + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + /* set cursor bitmap adress ... */ - if ((si->ps.card_arch == NV04A) || (si->ps.laptop)) + if (si->ps.laptop) { /* must be used this way on pre-NV10 and on all 'Go' cards! */ @@ -437,13 +455,18 @@ status_t nv_crtc2_cursor_init() NV_REG32(NV32_2CURCONF) = 0x02000100; /* activate hardware cursor */ - CRTC2W(CURCTL0, (CRTC2R(CURCTL0) | 0x01)); + nv_crtc2_cursor_show(); return B_OK; } status_t nv_crtc2_cursor_show() { + LOG(4,("CRTC2: enabling cursor\n")); + + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + /* b0 = 1 enables cursor */ CRTC2W(CURCTL0, (CRTC2R(CURCTL0) | 0x01)); @@ -452,6 +475,11 @@ status_t nv_crtc2_cursor_show() status_t nv_crtc2_cursor_hide() { + LOG(4,("CRTC2: disabling cursor\n")); + + /* enable access to CRTC2 */ + CRTC2W(OWNER, 0x03); + /* b0 = 0 disables cursor */ CRTC2W(CURCTL0, (CRTC2R(CURCTL0) & 0xfe)); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac.c b/src/add-ons/accelerants/nvidia/engine/nv_dac.c index 134b0a2b1c..3c65881e79 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac.c @@ -35,10 +35,6 @@ status_t nv_dac_mode(int mode,float brightness) if (nv_dac_palette(r,g,b) != B_OK) return B_ERROR; - /*set the mode - also sets VCLK dividor*/ -// DXIW(MULCTRL, mode); -// LOG(2,("DAC: mulctrl 0x%02x\n", DXIR(MULCTRL))); - /* disable palette RAM adressing mask */ NV_REG8(NV8_PALMASK) = 0xff; LOG(2,("DAC: PAL pixrdmsk readback $%02x\n", NV_REG8(NV8_PALMASK))); @@ -89,10 +85,6 @@ if (1) } /*program the pixpll - frequency in kHz*/ -/*important notes: - * PIXPLLC is used - others should be kept as is - * BESCLK,CRTC2 are not touched - */ status_t nv_dac_set_pix_pll(display_mode target) { uint8 m=0,n=0,p=0; @@ -115,9 +107,6 @@ status_t nv_dac_set_pix_pll(display_mode target) // DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0F)|0x04); /*disable the PIXPLL*/ // DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0C)|0x01); /*select the PIXPLL*/ - /* select pixelPLL registerset C */ - DACW(PLLSEL, 0x10000700); - /* program new frequency */ DACW(PIXPLLC, ((p << 16) | (n << 8) | m)); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c index 2d88c99182..21cf27d3a0 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_dac2.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_dac2.c @@ -33,10 +33,6 @@ status_t nv_dac2_mode(int mode,float brightness) if (nv_dac2_palette(r,g,b) != B_OK) return B_ERROR; - /*set the mode - also sets VCLK dividor*/ -// DXIW(MULCTRL, mode); -// LOG(2,("DAC: mulctrl 0x%02x\n", DXIR(MULCTRL))); - /* disable palette RAM adressing mask */ NV_REG8(NV8_PAL2MASK) = 0xff; LOG(2,("DAC2: PAL pixrdmsk readback $%02x\n", NV_REG8(NV8_PAL2MASK))); @@ -87,10 +83,6 @@ if (1) } /*program the pixpll - frequency in kHz*/ -/*important notes: - * PIXPLLC is used - others should be kept as is - * BESCLK,CRTC2 are not touched - */ status_t nv_dac2_set_pix_pll(display_mode target) { uint8 m=0,n=0,p=0; @@ -113,9 +105,6 @@ status_t nv_dac2_set_pix_pll(display_mode target) // DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0F)|0x04); /*disable the PIXPLL*/ // DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0C)|0x01); /*select the PIXPLL*/ - /* select pixelPLL registerset C */ - DAC2W(PLLSEL, 0x10000700); - /* program new frequency */ DAC2W(PIXPLLC, ((p << 16) | (n << 8) | m)); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c index fb3366ed38..44667930d2 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_general.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c @@ -80,7 +80,7 @@ status_t nv_general_powerup() { status_t status; - LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.08-4 running.\n")); + LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.08-5 running.\n")); /* preset no laptop */ si->ps.laptop = false; @@ -895,19 +895,6 @@ status_t nv_general_bios_to_powergraphics() { LOG(2, ("INIT: Skipping card coldstart!\n")); - /* unlock card registers for R/W access */ - CRTCW(LOCK, 0x57); - CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); - if (si->ps.secondary_head) - { - CRTC2W(LOCK, 0x57); - CRTC2W(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); - } - - /* turn off both displays and the hardcursor (also disables transfers) */ - nv_crtc_dpms(false, false, false); - nv_crtc_cursor_hide(); - /* let acc engine make power off/power on cycle to start 'fresh' */ NV_REG32(NV32_PWRUPCTRL) = 0x13110011; snooze(1000); @@ -924,6 +911,26 @@ status_t nv_general_bios_to_powergraphics() * bit 0: TVOUT. (> NV04A) */ NV_REG32(NV32_PWRUPCTRL) = 0x13111111; + /* unlock card registers for R/W access */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); + CRTCW(LOCK, 0x57); + CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); + if (si->ps.secondary_head) + { + CRTC2W(OWNER, 0x03); + CRTC2W(LOCK, 0x57); + CRTC2W(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); + } + + /* turn off both displays and the hardcursors (also disables transfers) */ + nv_crtc_dpms(false, false, false); + nv_crtc_cursor_hide(); + if (si->ps.secondary_head) + { + nv_crtc2_dpms(false, false, false); + nv_crtc2_cursor_hide(); + } + if (si->ps.secondary_head) { /* switch overlay engine to head 1 */ @@ -963,9 +970,23 @@ status_t nv_general_bios_to_powergraphics() /* enable 'enhanced mode', enable Vsync & Hsync, * set DAC palette to 8-bit width, disable large screen */ + if (si->ps.secondary_head) CRTCW(OWNER, 0x00); CRTCW(REPAINT1, 0x04); + if (si->ps.secondary_head) + { + CRTC2W(OWNER, 0x03); + CRTC2W(REPAINT1, 0x04); + } - /* turn on display */ + /* enable palettes */ + DACW(GENCTRL, 0x00100100); + if (si->ps.secondary_head) DAC2W(GENCTRL, 0x00100100); + + /* enable programmable PLLs */ + DACW(PLLSEL, 0x10000700); + if (si->ps.secondary_head) DACW(PLLSEL, (DACR(PLLSEL) | 0x20000800)); + + /* turn screen one on */ nv_crtc_dpms(true, true, true); return B_OK;