From a3b9d2120fd3cc7ccb6a98dc2f079fd2be009bd2 Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Thu, 15 Jan 2004 21:17:01 +0000 Subject: [PATCH] secondary head updates, cardrecognition updates (fx5950, fx5700) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6099 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../private/graphics/nvidia/DriverInterface.h | 2 + headers/private/graphics/nvidia/nv_macros.h | 8 +- .../accelerants/nvidia/SetDisplayMode.c | 23 +- .../accelerants/nvidia/engine/nv_crtc.c | 2 +- .../accelerants/nvidia/engine/nv_general.c | 132 ++++++- .../accelerants/nvidia/engine/nv_maven.c | 337 ++++++++++-------- .../accelerants/nvidia/engine/nv_proto.h | 17 +- 7 files changed, 325 insertions(+), 196 deletions(-) diff --git a/headers/private/graphics/nvidia/DriverInterface.h b/headers/private/graphics/nvidia/DriverInterface.h index d97279ffc2..40c41771ed 100644 --- a/headers/private/graphics/nvidia/DriverInterface.h +++ b/headers/private/graphics/nvidia/DriverInterface.h @@ -182,6 +182,8 @@ typedef struct { NV31, NV34, NV35, + NV36, + NV38, G550//remove later on }; enum diff --git a/headers/private/graphics/nvidia/nv_macros.h b/headers/private/graphics/nvidia/nv_macros.h index 88ad8acebb..81ce4c875b 100644 --- a/headers/private/graphics/nvidia/nv_macros.h +++ b/headers/private/graphics/nvidia/nv_macros.h @@ -522,10 +522,10 @@ #define NVDAC_PLLSEL 0x0068050c #define NVDAC_GENCTRL 0x00680600 /* secondary head */ -#define NVDAC2_CURPOS 0x00682300//confirmed NV34: 0x00680b00 does not work here -#define NVDAC2_PIXPLLC 0x00680d20//verify!!! -#define NVDAC2_PLLSEL 0x00680d0c//verify!!! -#define NVDAC2_GENCTRL 0x00680e00//verify!!! +#define NVDAC2_CURPOS 0x00682300 +#define NVDAC2_PIXPLLC 0x00680520 +#define NVDAC2_PLLSEL 0x00680524//0x0068250c verify!!! +#define NVDAC2_GENCTRL 0x00680618//0x00682600 verify!!! /* Nvidia CRTC indexed registers */ /* VGA standard registers: */ diff --git a/src/add-ons/accelerants/nvidia/SetDisplayMode.c b/src/add-ons/accelerants/nvidia/SetDisplayMode.c index 4ea9201cab..6527252e0e 100644 --- a/src/add-ons/accelerants/nvidia/SetDisplayMode.c +++ b/src/add-ons/accelerants/nvidia/SetDisplayMode.c @@ -121,8 +121,8 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) if (!(target2.flags & TV_BITS)) { LOG(8,("SETMODE: target2 clock %dkHz\n",target2.timing.pixel_clock)); - if (nv_maven_set_vid_pll(target2) == B_ERROR) - LOG(8,("SETMODE: error setting pixel clock (MAVEN)\n")); + if (nv_dac2_set_pix_pll(target2) == B_ERROR) + LOG(8,("SETMODE: error setting pixel clock (DAC2)\n")); } /*set the colour depth for CRTC1 and the DAC */ @@ -139,17 +139,17 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) nv_crtc_depth(BPP32); break; } - /*set the colour depth for CRTC2 and the MAVEN */ + /*set the colour depth for CRTC2 and DAC2 */ switch(target2.space) { case B_RGB16_LITTLE: colour_depth2 = 16; - nv_maven_mode(BPP16, 1.0); + nv_dac2_mode(BPP16, 1.0); nv_crtc2_depth(BPP16); break; case B_RGB32_LITTLE: colour_depth2 = 32; - nv_maven_mode(BPP32DIR, 1.0); + nv_dac2_mode(BPP32DIR, 1.0); nv_crtc2_depth(BPP32DIR); break; } @@ -168,13 +168,6 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) /*work out where the "right" screen starts*/ startadd_right=startadd+(target.timing.h_display * (colour_depth1 >> 3)); - /* calculate needed MAVEN-CRTC delay: formula valid for straight-through CRTC's */ - si->crtc_delay = 44 + 0 * (colour_depth2 == 16); - - /* setup vertical timing adjust for crtc1 and crtc2 for straight-through CRTC's */ - /* (extra "blanking" line for MAVEN) */ - target2.timing.v_display++; - /* set the outputs */ switch (si->ps.card_type) { @@ -202,12 +195,6 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) LOG(4,("SETMODE: no secondary TV-adapter detected, switching CRTCs\n")); nv_general_dac_select(DS_CRTC1MAVEN_CRTC2DAC); si->switched_crtcs = false; - /* re-calculate MAVEN-CRTC delay: formula valid for crossed CRTC's */ - si->crtc_delay = 17 + 4 * (colour_depth1 == 16); - /* re-setup vertical timing adjust for crtc1 and crtc2 for crossed CRTC's */ - /* (extra "blanking" line for MAVEN) */ - target.timing.v_display++; - target2.timing.v_display--; } break; } diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c index 6afb374c5f..17722caaf7 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c @@ -233,7 +233,7 @@ status_t nv_crtc_set_timing(display_mode target) } /* 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) */ CRTCW(INTERLACE, 0xff); return B_OK; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c index 64c53843bc..0f964f4846 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_general.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c @@ -190,7 +190,7 @@ status_t nv_general_powerup() case 0x017510de: /* Nvidia GeForce4 420 Go */ case 0x017610de: /* Nvidia GeForce4 420 Go 32M */ case 0x017710de: /* Nvidia GeForce4 460 Go */ - case 0x017910de: /* Nvidia GeForce4 440 Go 64M */ + case 0x017910de: /* Nvidia GeForce4 440 Go 64M (on PPC GeForce4 MX) */ si->ps.card_type = NV17; si->ps.card_arch = NV10A; si->ps.laptop = true; @@ -211,16 +211,16 @@ status_t nv_general_powerup() LOG(4,("POWERUP: Detected Nvidia Quadro4 500 GoGL (NV17)\n")); status = nvxx_general_powerup(); break; - case 0x017d10de: /* Nvidia unknown 4 Go */ + case 0x017d10de: /* Nvidia GeForce4 410 Go 16M*/ si->ps.card_type = NV17; si->ps.card_arch = NV10A; si->ps.laptop = true; - LOG(4,("POWERUP: Detected Nvidia unknown 4 Go (NV17)\n")); + LOG(4,("POWERUP: Detected Nvidia GeForce4 410 Go (NV17)\n")); status = nvxx_general_powerup(); break; - case 0x018010de: /* Nvidia GeForce4 MX 440 AGP8X */ - case 0x018110de: /* Nvidia GeForce4 MX 440SE AGP8X */ - case 0x018210de: /* Nvidia GeForce4 MX 420 AGP8X */ + case 0x018110de: /* Nvidia GeForce4 MX 440 AGP8X */ + case 0x018210de: /* Nvidia GeForce4 MX 440SE AGP8X */ + case 0x018310de: /* Nvidia GeForce4 MX 420 AGP8X */ si->ps.card_type = NV18; si->ps.card_arch = NV10A; LOG(4,("POWERUP: Detected Nvidia GeForce4 MX AGP8X (NV18)\n")); @@ -235,6 +235,17 @@ status_t nv_general_powerup() status = nvxx_general_powerup(); break; case 0x018810de: /* Nvidia Quadro4 580 XGL */ + si->ps.card_type = NV18; + si->ps.card_arch = NV10A; + LOG(4,("POWERUP: Detected Nvidia Quadro4 (NV18)\n")); + status = nvxx_general_powerup(); + break; + case 0x018910de: /* Nvidia GeForce4 MX AGP8X */ + si->ps.card_type = NV18; + si->ps.card_arch = NV10A; + LOG(4,("POWERUP: Detected Nvidia GeForce4 MX AGP8X (NV18)\n")); + status = nvxx_general_powerup(); + break; case 0x018a10de: /* Nvidia Quadro4 280 NVS */ case 0x018b10de: /* Nvidia Quadro4 380 XGL */ si->ps.card_type = NV18; @@ -285,7 +296,7 @@ status_t nv_general_powerup() LOG(4,("POWERUP: Detected Nvidia Quadro4 XGL (NV25)\n")); status = nvxx_general_powerup(); break; - case 0x028010de: /* Nvidia GeForce4 Ti 4600 AGP8X */ + case 0x028010de: /* Nvidia GeForce4 Ti 4600 AGP8X (4800?) */ case 0x028110de: /* Nvidia GeForce4 Ti 4200 AGP8X */ si->ps.card_type = NV28; si->ps.card_arch = NV20A; @@ -312,11 +323,11 @@ status_t nv_general_powerup() LOG(4,("POWERUP: Detected Nvidia Quadro4 XGL (NV28)\n")); status = nvxx_general_powerup(); break; - case 0x028c10de: /* Nvidia unknown 4 Go */ + case 0x028c10de: /* Nvidia Quadro4 700 GoGL */ si->ps.card_type = NV28; si->ps.card_arch = NV20A; si->ps.laptop = true; - LOG(4,("POWERUP: Detected Nvidia unknown 4 Go (NV28)\n")); + LOG(4,("POWERUP: Detected Nvidia Quadro4 700 GoGL (NV28)\n")); status = nvxx_general_powerup(); break; case 0x02a010de: /* Nvidia GeForce3 Integrated GPU */ @@ -346,6 +357,18 @@ status_t nv_general_powerup() LOG(4,("POWERUP: Detected Nvidia GeForce FX 5600 (NV31)\n")); status = nvxx_general_powerup(); break; + case 0x031310de: /* Nvidia unknown FX */ + si->ps.card_type = NV31; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia unknown FX (NV31)\n")); + status = nvxx_general_powerup(); + break; + case 0x031410de: /* Nvidia GeForce FX 5600SE */ + si->ps.card_type = NV31; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia GeForce FX 5600SE (NV31)\n")); + status = nvxx_general_powerup(); + break; case 0x031610de: /* Nvidia unknown FX Go */ case 0x031710de: /* Nvidia unknown FX Go */ si->ps.card_type = NV31; @@ -361,8 +384,20 @@ status_t nv_general_powerup() LOG(4,("POWERUP: Detected Nvidia GeForce FX 5600 Go (NV31)\n")); status = nvxx_general_powerup(); break; - case 0x031b10de: /* Nvidia unknown FX Go */ - case 0x031c10de: /* Nvidia unknown FX Go */ + case 0x031b10de: /* Nvidia GeForce FX 5650 Go */ + si->ps.card_type = NV31; + si->ps.card_arch = NV30A; + si->ps.laptop = true; + LOG(4,("POWERUP: Detected Nvidia GeForce FX 5650 Go (NV31)\n")); + status = nvxx_general_powerup(); + break; + case 0x031c10de: /* Nvidia Quadro FX 700 Go */ + si->ps.card_type = NV31; + si->ps.card_arch = NV30A; + si->ps.laptop = true; + LOG(4,("POWERUP: Detected Nvidia Quadro FX 700 Go (NV31)\n")); + status = nvxx_general_powerup(); + break; case 0x031d10de: /* Nvidia unknown FX Go */ case 0x031e10de: /* Nvidia unknown FX Go */ case 0x031f10de: /* Nvidia unknown FX Go */ @@ -374,6 +409,7 @@ status_t nv_general_powerup() break; case 0x032110de: /* Nvidia GeForce FX 5200 Ultra */ case 0x032210de: /* Nvidia GeForce FX 5200 */ + case 0x032310de: /* Nvidia GeForce FX 5200SE */ si->ps.card_type = NV34; si->ps.card_arch = NV30A; LOG(4,("POWERUP: Detected Nvidia GeForce FX 5200 (NV34)\n")); @@ -386,6 +422,13 @@ status_t nv_general_powerup() LOG(4,("POWERUP: Detected Nvidia GeForce FX 5200 Go (NV34)\n")); status = nvxx_general_powerup(); break; + case 0x032510de: /* Nvidia GeForce FX 5250 Go */ + si->ps.card_type = NV34; + si->ps.card_arch = NV30A; + si->ps.laptop = true; + LOG(4,("POWERUP: Detected Nvidia GeForce FX 5250 Go (NV34)\n")); + status = nvxx_general_powerup(); + break; case 0x032610de: /* Nvidia unknown FX Go */ si->ps.card_type = NV34; si->ps.card_arch = NV30A; @@ -393,13 +436,41 @@ status_t nv_general_powerup() LOG(4,("POWERUP: Detected Nvidia unknown FX Go (NV34)\n")); status = nvxx_general_powerup(); break; + case 0x032810de: /* Nvidia GeForce FX 5200 Go */ + si->ps.card_type = NV34; + si->ps.card_arch = NV30A; + si->ps.laptop = true; + LOG(4,("POWERUP: Detected Nvidia GeForce FX 5200 Go (NV34)\n")); + status = nvxx_general_powerup(); + break; + case 0x032910de: /* Nvidia GeForce FX 5200 (PPC) */ + si->ps.card_type = NV34; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia GeForce FX 5200 (NV34)\n")); + status = nvxx_general_powerup(); + break; + case 0x032a10de: /* Nvidia Quadro NVS 280 PCI */ + si->ps.card_type = NV34; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia Quadro NVS 280 PCI (NV34)\n")); + status = nvxx_general_powerup(); + break; case 0x032b10de: /* Nvidia Quadro FX 500 */ si->ps.card_type = NV34; si->ps.card_arch = NV30A; LOG(4,("POWERUP: Detected Nvidia Quadro FX 500 (NV34)\n")); status = nvxx_general_powerup(); break; + case 0x032c10de: /* Nvidia GeForce FX 5300 Go */ + case 0x032d10de: /* Nvidia GeForce FX 5100 Go */ + si->ps.card_type = NV34; + si->ps.card_arch = NV30A; + si->ps.laptop = true; + LOG(4,("POWERUP: Detected Nvidia GeForce FX Go (NV34)\n")); + status = nvxx_general_powerup(); + break; case 0x032e10de: /* Nvidia unknown FX Go */ + case 0x032f10de: /* Nvidia unknown FX Go */ si->ps.card_type = NV34; si->ps.card_arch = NV30A; si->ps.laptop = true; @@ -413,12 +484,50 @@ status_t nv_general_powerup() LOG(4,("POWERUP: Detected Nvidia GeForce FX 5900 (NV35)\n")); status = nvxx_general_powerup(); break; + case 0x033210de: /* Nvidia GeForce FX 5900 XT */ + si->ps.card_type = NV35; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia GeForce FX 5900 XT (NV35)\n")); + status = nvxx_general_powerup(); + break; + case 0x033310de: /* Nvidia GeForce FX 5950 Ultra */ + si->ps.card_type = NV38; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia GeForce FX 5950 Ultra (NV38)\n")); + status = nvxx_general_powerup(); + break; + case 0x033410de: /* Nvidia unknown FX Go(?) */ + si->ps.card_type = NV38; + si->ps.card_arch = NV30A; + si->ps.laptop = true; + LOG(4,("POWERUP: Detected Nvidia unknown FX Go(?) (NV38(?))\n")); + status = nvxx_general_powerup(); + break; case 0x033810de: /* Nvidia Quadro FX 3000 */ si->ps.card_type = NV35; si->ps.card_arch = NV30A; LOG(4,("POWERUP: Detected Nvidia Quadro FX 3000 (NV35)\n")); status = nvxx_general_powerup(); break; + case 0x034110de: /* Nvidia GeForce FX 5700 Ultra */ + case 0x034210de: /* Nvidia GeForce FX 5700 */ + si->ps.card_type = NV36; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia GeForce FX 5700 (NV36)\n")); + status = nvxx_general_powerup(); + break; + case 0x034e10de: /* Nvidia Quadro FX 1100 */ + si->ps.card_type = NV36; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia Quadro FX 1100 (NV36)\n")); + status = nvxx_general_powerup(); + break; + case 0x034f10de: /* Nvidia unknown FX */ + si->ps.card_type = NV36; + si->ps.card_arch = NV30A; + LOG(4,("POWERUP: Detected Nvidia unknown FX (NV36(?))\n")); + status = nvxx_general_powerup(); + break; /* Vendor Elsa GmbH */ case 0x0c601048: /* Elsa Gladiac Geforce2 MX */ si->ps.card_type = NV11; @@ -789,7 +898,6 @@ status_t nv_general_bios_to_powergraphics() /* unlock card registers for R/W access */ CRTCW(LOCK, 0x57); CRTCW(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); -//fixme: verify if this works.. if (si->ps.secondary_head) { CRTC2W(LOCK, 0x57); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_maven.c b/src/add-ons/accelerants/nvidia/engine/nv_maven.c index fd8a150fab..2d88c99182 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_maven.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_maven.c @@ -1,179 +1,200 @@ -/* program the MAVEN in monitor mode */ - -/* Authors: - Mark Watson 6/2000, - Rudolf Cornelissen 1/2003-4/2003 - - Thanx to Petr Vandrovec for writing matroxfb. +/* program the secondary DAC */ +/* Author: + Rudolf Cornelissen 12/2003-1/2004 */ #define MODULE_BIT 0x00001000 #include "nv_std.h" -status_t g450_g550_maven_set_vid_pll(display_mode target); -status_t g100_g400max_maven_set_vid_pll(display_mode target); - -status_t nv_maven_dpms(uint8 display,uint8 h,uint8 v) -{ - /* this function is nolonger needed on G450/G550 cards */ - if (si->ps.card_type > G550) return B_OK; - - if (display & h & v) - { - /* turn on screen */ - if (!(si->dm.flags & TV_BITS)) - { - /* monitor mode */ - MAVW(MONEN, 0xb2); - MAVW(MONSET, 0x20); /* must be set to this in monitor mode */ - MAVW(OUTMODE, 0x03); /* output: monitor mode */ - MAVW(STABLE, 0x22); /* makes picture stable? */ - MAVW(TEST, 0x00); /* turn off test signal */ - } - else - { - /* TVout mode */ - MAVW(MONEN, 0xb3); - MAVW(MONSET, 0x20); - MAVW(OUTMODE, 0x08); /* output: SVideo/Composite */ - MAVW(STABLE, 0x02); /* makes picture stable? */ - //fixme? linux uses 0x14... - MAVW(TEST, (MAVR(TEST) & 0x10)); - } - } - else - { - /* turn off screen using a few methods! */ - MAVW(STABLE, 0x6a); -// MAVW(TEST, 0x03); - MAVW(OUTMODE, 0x00); - } - - return B_OK; -} - -/*set a mode line - inputs are in pixels/scanlines*/ -status_t nv_maven_set_timing(display_mode target) -{ - /* this function is nolonger needed on G450/G550 cards */ - if (si->ps.card_type > G550) return B_OK; - - LOG(4,("MAVEN: setting timing\n")); - - /*check horizontal timing parameters are to nearest 8 pixels*/ - if ((target.timing.h_display & 0x07) | - (target.timing.h_sync_start & 0x07) | - (target.timing.h_sync_end & 0x07) | - (target.timing.h_total & 0x07)) - { - LOG(8,("MAVEN: Horizontal timing is not multiples of 8 pixels\n")); - return B_ERROR; - } - - /*program the MAVEN*/ - MAVWW(LASTLINEL, target.timing.h_total); - MAVWW(HSYNCLENL, (target.timing.h_sync_end - target.timing.h_sync_start)); - MAVWW(HSYNCSTRL, (target.timing.h_total - target.timing.h_sync_start)); - MAVWW(HDISPLAYL, ((target.timing.h_total - target.timing.h_sync_start) + - target.timing.h_display)); - MAVWW(HTOTALL, (target.timing.h_total + 1)); - - MAVWW(VSYNCLENL, (target.timing.v_sync_end - target.timing.v_sync_start - 1)); - MAVWW(VSYNCSTRL, (target.timing.v_total - target.timing.v_sync_start)); - MAVWW(VDISPLAYL, (target.timing.v_total - 1)); - MAVWW(VTOTALL, (target.timing.v_total - 1)); - - MAVWW(HVIDRSTL, (target.timing.h_total - si->crtc_delay)); - MAVWW(VVIDRSTL, (target.timing.v_total - 2)); - - return B_OK; -} +static status_t nv10_nv20_dac2_pix_pll_find( + display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test); /*set the mode, brightness is a value from 0->2 (where 1 is equivalent to direct)*/ -status_t nv_maven_mode(int mode,float brightness) +status_t nv_dac2_mode(int mode,float brightness) { - uint8 luma; + uint8 *r,*g,*b; + int i, ri; - /* this function is nolonger needed on G450/G550 cards */ - if (si->ps.card_type > G550) return B_OK; + /*set colour arrays to point to space reserved in shared info*/ + r = si->color_data; + g = r + 256; + b = g + 256; - /*set luma to a suitable value for brightness*/ - /*assuming 1A is a sensible value*/ - luma = (uint8)(0x1a * brightness); - MAVW(LUMA,luma); - LOG(4,("MAVEN: LUMA setting - %x\n",luma)); + LOG(4,("DAC2: Setting screen mode %d brightness %f\n", mode, brightness)); + /* init the palette for brightness specified */ + /* (Nvidia cards always use MSbits from screenbuffer as index for PAL) */ + for (i = 0; i < 256; i++) + { + ri = i * brightness; + if (ri > 255) ri = 255; + b[i] = g[i] = r[i] = ri; + } + + 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))); return B_OK; } -status_t nv_maven_set_vid_pll(display_mode target) +/*program the DAC palette using the given r,g,b values*/ +status_t nv_dac2_palette(uint8 r[256],uint8 g[256],uint8 b[256]) { - switch (si->ps.card_type) + int i; + + LOG(4,("DAC2: setting palette\n")); + + /* select first PAL adress before starting programming */ + NV_REG8(NV8_PAL2INDW) = 0x00; + + /* loop through all 256 to program DAC */ + for (i = 0; i < 256; i++) { - default: - return g100_g400max_maven_set_vid_pll(target); - break; + /* the 6 implemented bits are on b0-b5 of the bus */ + NV_REG8(NV8_PAL2DATA) = r[i]; + NV_REG8(NV8_PAL2DATA) = g[i]; + NV_REG8(NV8_PAL2DATA) = b[i]; } - return B_ERROR; + if (NV_REG8(NV8_PAL2INDW) != 0x00) + { + LOG(8,("DAC2: PAL write index incorrect after programming\n")); + return B_ERROR; + } +if (1) + {//reread LUT + uint8 R, G, B; + + /* select first PAL adress to read (modulo 3 counter) */ + NV_REG8(NV8_PAL2INDR) = 0x00; + for (i = 0; i < 256; i++) + { + R = NV_REG8(NV8_PAL2DATA); + G = NV_REG8(NV8_PAL2DATA); + B = NV_REG8(NV8_PAL2DATA); + if ((r[i] != R) || (g[i] != G) || (b[i] != B)) + LOG(1,("DAC2 palette %d: w %x %x %x, r %x %x %x\n", i, r[i], g[i], b[i], R, G, B)); // apsed + } + } + + return B_OK; } - -/* program the video PLL in the MAVEN */ -status_t g100_g400max_maven_set_vid_pll(display_mode target) + +/*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; +// uint time = 0; float pix_setting, req_pclk; status_t result; req_pclk = (target.timing.pixel_clock)/1000.0; - LOG(4,("MAVEN: Setting VID PLL for pixelclock %f\n", req_pclk)); + LOG(4,("DAC2: Setting PIX PLL for pixelclock %f\n", req_pclk)); - result = g100_g400max_maven_vid_pll_find(target,&pix_setting,&m,&n,&p); + /* signal that we actually want to set the mode */ + result = nv_dac2_pix_pll_find(target,&pix_setting,&m,&n,&p, 1); if (result != B_OK) { return result; } + + /*reprogram (disable,select,wait for stability,enable)*/ +// DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0F)|0x04); /*disable the PIXPLL*/ +// DXIW(PIXCLKCTRL,(DXIR(PIXCLKCTRL)&0x0C)|0x01); /*select the PIXPLL*/ - /*reprogram (select,wait for stability)*/ - MAVW(PIXPLLM,(m)); /* set m value */ - MAVW(PIXPLLN,(n)); /* set n value */ - MAVW(PIXPLLP,(p | 0x80)); /* set p value enabling PLL */ + /* select pixelPLL registerset C */ + DAC2W(PLLSEL, 0x10000700); - /* Wait for the VIDPLL frequency to lock: detection is not possible it seems */ - snooze(2000); + /* program new frequency */ + DAC2W(PIXPLLC, ((p << 16) | (n << 8) | m)); - LOG(2,("MAVEN: VID PLL frequency should be locked now...\n")); + /* Wait for the PIXPLL frequency to lock until timeout occurs */ +//fixme: do NV cards have a LOCK indication bit?? +/* while((!(DXIR(PIXPLLSTAT)&0x40)) & (time <= 2000)) + { + time++; + snooze(1); + } + + if (time > 2000) + LOG(2,("DAC: PIX PLL frequency not locked!\n")); + else + LOG(2,("DAC: PIX PLL frequency locked\n")); + DXIW(PIXCLKCTRL,DXIR(PIXCLKCTRL)&0x0B); //enable the PIXPLL +*/ + +//for now: + /* Give the PIXPLL frequency some time to lock... */ + snooze(1000); + LOG(2,("DAC2: PIX PLL frequency should be locked now...\n")); return B_OK; } -/* find nearest valid video PLL setting */ -status_t g100_g400max_maven_vid_pll_find( - display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result) +/* find nearest valid pix pll */ +status_t nv_dac2_pix_pll_find + (display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test) { - int m = 0, n = 0, p = 0, m_max; + switch (si->ps.card_type) { + default: return nv10_nv20_dac2_pix_pll_find(target, calc_pclk, m_result, n_result, p_result, test); + } + return B_ERROR; +} + +/* find nearest valid pixel PLL setting */ +static status_t nv10_nv20_dac2_pix_pll_find( + display_mode target,float * calc_pclk,uint8 * m_result,uint8 * n_result,uint8 * p_result, uint8 test) +{ + int m = 0, n = 0, p = 0/*, m_max*/; float error, error_best = 999999999; int best[3]; float f_vco, max_pclk; float req_pclk = target.timing.pixel_clock/1000.0; - /* determine the max. reference-frequency postscaler setting for the current card */ - //fixme: check G100 and G200 m_max if possible... - switch(si->ps.card_type) + /* determine the max. reference-frequency postscaler setting for the + * current card (see G100, G200 and G400 specs). */ +/* switch(si->ps.card_type) { + case G100: + LOG(4,("DAC: G100 restrictions apply\n")); + m_max = 7; + break; + case G200: + LOG(4,("DAC: G200 restrictions apply\n")); + m_max = 7; + break; default: - LOG(4,("MAVEN: G400/G400MAX restrictions apply\n")); + LOG(4,("DAC: G400/G400MAX restrictions apply\n")); m_max = 32; break; } +*/ + LOG(4,("DAC2: NV10/NV20 restrictions apply\n")); /* determine the max. pixelclock for the current videomode */ switch (target.space) { + case B_CMAP8: + max_pclk = si->ps.max_dac2_clock_8; + break; + case B_RGB15_LITTLE: case B_RGB16_LITTLE: max_pclk = si->ps.max_dac2_clock_16; break; + case B_RGB24_LITTLE: + max_pclk = si->ps.max_dac2_clock_24; + break; case B_RGB32_LITTLE: max_pclk = si->ps.max_dac2_clock_32; break; @@ -187,23 +208,23 @@ status_t g100_g400max_maven_vid_pll_find( max_pclk = si->ps.max_dac2_clock_32dh; /* Make sure the requested pixelclock is within the PLL's operational limits */ - /* lower limit is min_video_vco divided by highest postscaler-factor */ - if (req_pclk < (si->ps.min_video_vco / 8.0)) + /* lower limit is min_pixel_vco divided by highest postscaler-factor */ + if (req_pclk < (si->ps.min_video_vco / 16.0)) { - LOG(4,("MAVEN: clamping vidclock: requested %fMHz, set to %fMHz\n", - req_pclk, (float)(si->ps.min_video_vco / 8.0))); - req_pclk = (si->ps.min_video_vco / 8.0); + LOG(4,("DAC2: clamping pixclock: requested %fMHz, set to %fMHz\n", + req_pclk, (float)(si->ps.min_video_vco / 16.0))); + req_pclk = (si->ps.min_video_vco / 16.0); } /* upper limit is given by pins in combination with current active mode */ if (req_pclk > max_pclk) { - LOG(4,("MAVEN: clamping vidclock: requested %fMHz, set to %fMHz\n", + LOG(4,("DAC2: clamping pixclock: requested %fMHz, set to %fMHz\n", req_pclk, (float)max_pclk)); req_pclk = max_pclk; } /* iterate through all valid PLL postscaler settings */ - for (p=0x01; p < 0x10; p = p<<1) + for (p=0x01; p < 0x20; p = p<<1) { /* calculate the needed VCO frequency for this postscaler setting */ f_vco = req_pclk * p; @@ -211,16 +232,24 @@ status_t g100_g400max_maven_vid_pll_find( /* check if this is within range of the VCO specs */ if ((f_vco >= si->ps.min_video_vco) && (f_vco <= si->ps.max_video_vco)) { + /* NV31 (FX5600) tweak (missing register for 2nd VCO postscaler) */ + f_vco /= si->pixpll_vco_div2; + /* iterate trough all valid reference-frequency postscaler settings */ - for (m = 2; m <= m_max; m++) + for (m = 7; m <= 14; m++) { + /* check if phase-discriminator will be within operational limits */ + if (((si->ps.f_ref / m) < 1.0) || ((si->ps.f_ref / m) > 2.0)) continue; + /* calculate VCO postscaler setting for current setup.. */ n = (int)(((f_vco * m) / si->ps.f_ref) + 0.5); /* ..and check for validity */ - if ((n < 8) || (n > 128)) continue; + if ((n < 1) || (n > 255)) continue; /* find error in frequency this setting gives */ - error = fabs(req_pclk - (((si->ps.f_ref / m) * n) / p)); + /* si->pixpll_vco_div2 below is NV31 (FX5600) tweak (missing register) */ + error = + fabs((req_pclk / si->pixpll_vco_div2) - (((si->ps.f_ref / m) * n) / p)); /* note the setting if best yet */ if (error < error_best) @@ -235,35 +264,43 @@ status_t g100_g400max_maven_vid_pll_find( } /* setup the scalers programming values for found optimum setting */ - m=best[0] - 1; - n=best[1] - 1; - p=best[2] - 1; + m = best[0]; + n = best[1]; + p = best[2]; - /* calc the needed PLL loopbackfilter setting belonging to current VCO speed */ - f_vco = (si->ps.f_ref / (m + 1)) * (n + 1); - LOG(2,("MAVEN: vid VCO frequency found %fMhz\n", f_vco)); + /* log the VCO frequency found */ + f_vco = ((si->ps.f_ref / m) * n); + /* NV31 (FX5600) tweak (missing register for 2nd VCO postscaler) */ + f_vco *= si->pixpll_vco_div2; - switch(si->ps.card_type) - { - default: - for(;;) - { - if (f_vco >= 240) {p |= (0x03 << 3); break;}; - if (f_vco >= 170) {p |= (0x02 << 3); break;}; - if (f_vco >= 110) {p |= (0x01 << 3); break;}; - break; - } - break; - } + LOG(2,("DAC2: pix VCO frequency found %fMhz\n", f_vco)); /* return the results */ - *calc_pclk = f_vco / ((p & 0x07) + 1); + *calc_pclk = (f_vco / p); *m_result = m; *n_result = n; + switch(p) + { + case 1: + p = 0x00; + break; + case 2: + p = 0x01; + break; + case 4: + p = 0x02; + break; + case 8: + p = 0x03; + break; + case 16: + p = 0x04; + break; + } *p_result = p; /* display the found pixelclock values */ - LOG(2,("MAVEN: vid PLL check: req. %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", + LOG(2,("DAC2: pix PLL check: requested %fMHz got %fMHz, mnp 0x%02x 0x%02x 0x%02x\n", req_pclk, *calc_pclk, *m_result, *n_result, *p_result)); return B_OK; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_proto.h b/src/add-ons/accelerants/nvidia/engine/nv_proto.h index 52a0bc657b..f2d70cf4af 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_proto.h +++ b/src/add-ons/accelerants/nvidia/engine/nv_proto.h @@ -31,23 +31,18 @@ status_t parse_pins(void); void fake_pins(void); void dump_pins(void); -/*DAC functions*/ +/* DAC functions */ status_t nv_dac_mode(int,float); status_t nv_dac_palette(uint8*,uint8*,uint8*); - status_t nv_dac_pix_pll_find(display_mode target,float * result,uint8 *,uint8 *,uint8 *, uint8); status_t nv_dac_set_pix_pll(display_mode target); - status_t g400_dac_set_sys_pll(void); -/*MAVEN functions*/ -status_t nv_maven_dpms(uint8, uint8, uint8); -status_t nv_maven_set_timing(display_mode target); -status_t nv_maven_mode(int,float); - -status_t g100_g400max_maven_vid_pll_find(display_mode target,float * calc_pclk, - uint8 * m_result,uint8 * n_result,uint8 * p_result); -status_t nv_maven_set_vid_pll(display_mode target); +/* DAC2 functions */ +status_t nv_dac2_mode(int,float); +status_t nv_dac2_palette(uint8*,uint8*,uint8*); +status_t nv_dac2_pix_pll_find(display_mode target,float * result,uint8 *,uint8 *,uint8 *, uint8); +status_t nv_dac2_set_pix_pll(display_mode target); /*MAVENTV functions*/ status_t g100_g400max_maventv_vid_pll_find(