removed all pre-NV20 refs, removed all TVout stuff except clearing some flags, re-enabled force_ws option, force_ws is now default true, pgm_panel is now default false.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25929 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rudolf Cornelissen
2008-06-11 18:14:15 +00:00
parent bc8b563b74
commit 730ebb158c
15 changed files with 229 additions and 3216 deletions
@@ -73,18 +73,6 @@ enum {
/* card_type in order of date of NV chip design */
enum {
NV04 = 0,
NV05,
NV05M64,
NV06,
NV10,
NV11,
NV11M,
NV15,
NV17,
NV17M,
NV18,
NV18M,
NV20,
NV25,
NV28,
@@ -118,27 +106,6 @@ enum {
NV50A
};
/* card info - information gathered from PINS (and other sources) */
enum
{ // tv_encoder_type in order of capability (more or less)
NONE = 0,
CH7003,
CH7004,
CH7005,
CH7006,
CH7007,
CH7008,
SAA7102,
SAA7103,
SAA7104,
SAA7105,
BT868,
BT869,
CX25870,
CX25871,
NVIDIA
};
/* handles to pre-defined engine commands */
#define NV_ROP5_SOLID 0x00000000 /* 2D */
#define NV_IMAGE_BLACK_RECTANGLE 0x00000001 /* 2D/3D */
@@ -214,12 +181,10 @@ typedef struct { // apsed, see comments in nv.settings
// for accelerant
uint32 logmask;
uint32 memory;
uint32 tv_output;
bool usebios;
bool hardcursor;
bool switchhead;
bool pgm_panel;
bool vga_on_tv;
bool force_sync;
bool force_ws;
uint32 gpu_clk;
@@ -287,7 +252,6 @@ typedef struct {
display_mode dm; /* current display mode configuration: head1 */
uint32 dpms_flags; /* current DPMS mode */
bool acc_mode; /* signals (non)accelerated mode */
bool interlaced_tv_mode;/* signals interlaced CRTC TV output mode */
bool crtc_switch_mode; /* signals dualhead switch mode if panels are used */
/*frame buffer config - for BDirectScreen*/
@@ -343,13 +307,6 @@ typedef struct {
bool i2c_bus1; /* we have a wired I2C bus 1 on board */
bool i2c_bus2; /* we have a wired I2C bus 2 on board */
bool i2c_bus3; /* we have a wired I2C bus 3 on board */
struct
{
uint32 type; /* see tvchip_type enum above */
uint8 version; /* chip silicon version */
uint8 bus; /* I2C bus on which TVout chip resides */
uint8 adress; /* I2C adress on which TVout chip resides */
} tv_encoder;
uint8 monitors; /* output devices connection matrix */
bool int_assigned; /* card has a useable INT assigned to it */
status_t pins_status; /* B_OK if read correctly, B_ERROR if faked */
@@ -378,7 +335,6 @@ typedef struct {
uint32 max_dac2_clock_32;
uint32 max_dac2_clock_32dh;
bool secondary_head; /* presence of functions */
bool tvout;
bool primary_dvi;
bool secondary_dvi;
uint32 memory_size; /* memory (in bytes) */
@@ -40,8 +40,8 @@ static status_t init_common(int the_fd) {
// LOG is now available, si !NULL
LOG(4,("init_common: logmask 0x%08x, memory %dMB, hardcursor %d, usebios %d, switchhead %d\n",
si->settings.logmask, si->settings.memory, si->settings.hardcursor, si->settings.usebios, si->settings.switchhead));
LOG(4,("init_common: dumprom %d, pgm_panel %d, tv_output %d, vga_on_tv %d\n",
si->settings.dumprom, si->settings.pgm_panel, si->settings.tv_output, si->settings.vga_on_tv));
LOG(4,("init_common: dumprom %d, pgm_panel %d\n",
si->settings.dumprom, si->settings.pgm_panel));
LOG(4,("init_common: force_sync %d, gpu_clk %dMhz, ram_clk %dMhz, force_ws %d\n",
si->settings.force_sync, si->settings.gpu_clk, si->settings.ram_clk, si->settings.force_ws));
@@ -202,11 +202,6 @@ status_t INIT_ACCELERANT(int the_fd)
/* ensure DPMS state */
si->dpms_flags = B_DPMS_ON;
/* ensure TVout state:
* TVencoder is on head to be assigned primary, no dualhead switch mode active. */
//fixme: actually check on what CRTC TVout was active during boot (if any)...
si->dm.flags = TV_PRIMARY;
/* make sure a possible 3D add-on will block rendering and re-initialize itself.
* note: update in _this_ order only */
/* SET_DISPLAY_MODE will reset this flag when it's done. */
@@ -4,7 +4,7 @@
Other authors for NV driver:
Mark Watson,
Rudolf Cornelissen 9/2002-4/2006
Rudolf Cornelissen 9/2002-6/2008
*/
#define MODULE_BIT 0x00400000
@@ -188,69 +188,60 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
return result;
}
/* disable aspect checks for a requested TVout mode when mode is TVout capable */
if (!si->ps.tvout
|| !(BT_check_tvmode(*target) && (target->flags & TV_BITS))) {
/* check if all connected output devices can display the requested mode's aspect: */
/* calculate display mode aspect */
target_aspect = (target->timing.h_display / ((float)target->timing.v_display));
/* NOTE:
* allow 0.10 difference so 5:4 aspect panels will be able to use 4:3 aspect modes! */
switch (si->ps.monitors) {
case 0x01: /* digital panel on head 1, nothing on head 2 */
if (si->ps.panel1_aspect < (target_aspect - 0.10)) {
LOG(4, ("PROPOSEMODE: connected panel1 is not widescreen type, aborted.\n"));
return B_ERROR;
}
break;
case 0x10: /* nothing on head 1, digital panel on head 2 */
if (si->ps.panel2_aspect < (target_aspect - 0.10)) {
LOG(4, ("PROPOSEMODE: connected panel2 is not widescreen type, aborted.\n"));
return B_ERROR;
}
break;
case 0x11: /* digital panels on both heads */
if ((si->ps.panel1_aspect < (target_aspect - 0.10))
|| (si->ps.panel2_aspect < (target_aspect - 0.10))) {
LOG(4, ("PROPOSEMODE: not all connected panels are widescreen type, aborted.\n"));
return B_ERROR;
}
break;
default:
#if 0
/* at least one analog monitor is connected, or nothing detected at all */
/* (if forcing widescreen type was requested don't block mode) */
if (target_aspect > 1.34 && !si->settings.force_ws) {
LOG(4, ("PROPOSEMODE: not all output devices can display widescreen modes, aborted.\n"));
return B_ERROR;
}
#endif
break;
}
// Wide screen modes are pretty common these days... - better use EDID!
#if 0
/* only export widescreen panel-TV modes when an exact resolution match exists,
* to prevent the modelist from becoming too crowded */
if (target_aspect > 1.61 && !si->settings.force_ws) {
status_t panel_TV_stat = B_ERROR;
if (si->ps.tmds1_active) {
if (target->timing.h_display == si->ps.p1_timing.h_display
&& target->timing.v_display == si->ps.p1_timing.v_display)
panel_TV_stat = B_OK;
}
if (si->ps.tmds2_active) {
if (target->timing.h_display == si->ps.p2_timing.h_display
&& target->timing.v_display == si->ps.p2_timing.v_display)
panel_TV_stat = B_OK;
}
if (panel_TV_stat != B_OK) {
LOG(4, ("PROPOSEMODE: WS panel_TV mode requested but no such TV here, aborted.\n"));
/* check if all connected output devices can display the requested mode's aspect: */
/* calculate display mode aspect */
target_aspect = (target->timing.h_display / ((float)target->timing.v_display));
/* NOTE:
* allow 0.10 difference so 5:4 aspect panels will be able to use 4:3 aspect modes! */
switch (si->ps.monitors) {
case 0x01: /* digital panel on head 1, nothing on head 2 */
if (si->ps.panel1_aspect < (target_aspect - 0.10)) {
LOG(4, ("PROPOSEMODE: connected panel1 is not widescreen type, aborted.\n"));
return B_ERROR;
}
break;
case 0x10: /* nothing on head 1, digital panel on head 2 */
if (si->ps.panel2_aspect < (target_aspect - 0.10)) {
LOG(4, ("PROPOSEMODE: connected panel2 is not widescreen type, aborted.\n"));
return B_ERROR;
}
break;
case 0x11: /* digital panels on both heads */
if ((si->ps.panel1_aspect < (target_aspect - 0.10))
|| (si->ps.panel2_aspect < (target_aspect - 0.10))) {
LOG(4, ("PROPOSEMODE: not all connected panels are widescreen type, aborted.\n"));
return B_ERROR;
}
break;
default:
/* at least one analog monitor is connected, or nothing detected at all */
/* (if forcing widescreen type was requested don't block mode) */
if (target_aspect > 1.34 && !si->settings.force_ws) {
LOG(4, ("PROPOSEMODE: not all output devices can display widescreen modes, aborted.\n"));
return B_ERROR;
}
break;
}
/* only export widescreen panel-TV modes when an exact resolution match exists,
* to prevent the modelist from becoming too crowded */
if (target_aspect > 1.61 && !si->settings.force_ws) {
status_t panel_TV_stat = B_ERROR;
if (si->ps.tmds1_active) {
if (target->timing.h_display == si->ps.p1_timing.h_display
&& target->timing.v_display == si->ps.p1_timing.v_display)
panel_TV_stat = B_OK;
}
if (si->ps.tmds2_active) {
if (target->timing.h_display == si->ps.p2_timing.h_display
&& target->timing.v_display == si->ps.p2_timing.v_display)
panel_TV_stat = B_OK;
}
if (panel_TV_stat != B_OK) {
LOG(4, ("PROPOSEMODE: WS panel_TV mode requested but no such TV here, aborted.\n"));
return B_ERROR;
}
#endif
}
/* check if panel(s) can display the requested resolution (if connected) */
@@ -444,23 +435,10 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
if (!(target->flags & DUALHEAD_CAPABLE))
target->flags &= ~DUALHEAD_BITS;
/* set TV_CAPABLE if suitable: pixelclock is not important (defined by TVstandard) */
if (si->ps.tvout && BT_check_tvmode(*target))
target->flags |= TV_CAPABLE;
/* if not TVout capable card clear TVout flags */
if (!(target->flags & TV_CAPABLE))
target->flags &= ~TV_BITS;
/* make sure TV head assignment is sane */
if (target->flags & TV_BITS) {
if (!si->ps.secondary_head)
target->flags |= TV_PRIMARY;
else if ((target->flags & DUALHEAD_BITS) == DUALHEAD_OFF)
target->flags |= TV_PRIMARY;
} else
target->flags &= ~TV_PRIMARY;
/* set HARDWARE_CURSOR mode if suitable */
if (si->settings.hardcursor)
target->flags |= B_HARDWARE_CURSOR;
@@ -62,13 +62,9 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
// head1_interrupt_enable(false);
// if (si->ps.secondary_head) head2_interrupt_enable(false);
/* disable TVout if supported */
// if (si->ps.tvout) BT_stop_tvout();
/* turn off screen(s) _after_ TVout is disabled (if applicable) */
/* turn off screen(s) */
// head1_dpms(false, false, false, true);
// if (si->ps.secondary_head) head2_dpms(false, false, false, true);
// if (si->ps.tvout) BT_dpms(false);
/*where in framebuffer the screen is (should this be dependant on previous MOVEDISPLAY?)*/
startadd = (uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer;
@@ -86,15 +82,6 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
LOG(1,("SETMODE: setting DUALHEAD mode\n"));
/* validate flags for secondary TVout */
//fixme: remove or block on autodetect fail. (is now shutoff)
if ((0) && (target2.flags & TV_BITS))
{
target.flags &= ~TV_BITS;//still needed for some routines...
target2.flags &= ~TV_BITS;
LOG(1,("SETMODE: blocking TVout: no TVout cable connected!\n"));
}
/* detect which connectors have a CRT connected */
//fixme: 'hot-plugging' for analog monitors removed: remove code as well;
//or make it work with digital panels connected as well.
@@ -180,10 +167,6 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
break;
}
/* check if we are doing interlaced TVout mode */
//fixme: we don't support interlaced mode?
si->interlaced_tv_mode = false;
/*set the display(s) pitches*/
// head1_set_display_pitch ();
//fixme: seperate for real dualhead modes:
@@ -210,9 +193,6 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
/* set the timing */
// head1_set_timing(target);
// head2_set_timing(target2);
/* TVout support: program TVout encoder and modify CRTC timing */
// if (si->ps.tvout && (target2.flags & TV_BITS)) BT_setmode(target2);
}
else /* single head mode */
{
@@ -275,9 +255,6 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
/* set the timing */
// head1_set_timing(target);
/* TVout support: program TVout encoder and modify CRTC timing */
// if (si->ps.tvout && (target.flags & TV_BITS)) BT_setmode(target);
//fixme: shut-off the videoPLL if it exists...
}
@@ -493,100 +470,10 @@ status_t SET_DPMS_MODE(uint32 dpms_flags)
return B_ERROR;
}
/* CRTC used for TVout needs specific DPMS programming */
if (si->dm.flags & TV_BITS)
{
/* TV_PRIMARY tells us that the head to be used with TVout is the head that's
* actually assigned as being the primary head at powerup:
* so non dualhead-mode-dependant, and not 'fixed' CRTC1! */
if (si->dm.flags & TV_PRIMARY)
{
LOG(4,("SET_DPMS_MODE: tuning primary head DPMS settings for TVout compatibility\n"));
if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
{
if (!(si->settings.vga_on_tv))
{
/* block VGA output on head displaying on TV */
/* Note:
* this specific sync setting is required: Vsync is used to keep TVout
* synchronized to the CRTC 'vertically' (otherwise 'rolling' occurs).
* This leaves Hsync only for shutting off the VGA screen. */
h1h = false;
h1v = true;
/* block panel DPMS updates */
do_p1 = false;
}
else
{
/* when concurrent VGA is used alongside TVout on a head, DPMS is safest
* applied this way: Vsync is needed for stopping TVout successfully when
* a (new) modeswitch occurs.
* (see routine BT_stop_tvout() in nv_brooktreetv.c) */
/* Note:
* applying 'normal' DPMS here and forcing Vsync on in the above mentioned
* routine seems to not always be enough: sometimes image generation will
* not resume in that case. */
h1h = display;
h1v = true;
}
}
else
{
if (!(si->settings.vga_on_tv))
{
h2h = false;
h2v = true;
do_p2 = false;
}
else
{
h2h = display;
h2v = true;
}
}
}
else
{
LOG(4,("SET_DPMS_MODE: tuning secondary head DPMS settings for TVout compatibility\n"));
if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_SWITCH)
{
if (!(si->settings.vga_on_tv))
{
h2h = false;
h2v = true;
do_p2 = false;
}
else
{
h2h = display;
h2v = true;
}
}
else
{
if (!(si->settings.vga_on_tv))
{
h1h = false;
h1v = true;
do_p1 = false;
}
else
{
h1h = display;
h1v = true;
}
}
}
}
/* issue actual DPMS commands as far as applicable */
head1_dpms(display, h1h, h1v, do_p1);
if ((si->ps.secondary_head) && (si->dm.flags & DUALHEAD_BITS))
head2_dpms(display, h2h, h2v, do_p2);
if (si->dm.flags & TV_BITS)
BT_dpms(display);
//fixme:
//add head2 once we use one driver instance 'per head' (instead of 'per card')
@@ -8,7 +8,6 @@ UsePrivateHeaders [ FDirName graphics nvidia_gpgpu ] ;
StaticLibrary libnvidia_gpgpu_engine.a :
nv_acc_dma.c
nv_bes.c
nv_brooktreetv.c
nv_crtc.c
nv_crtc2.c
nv_dac.c
@@ -1,7 +1,7 @@
/* NV Acceleration functions */
/* Author:
Rudolf Cornelissen 8/2003-9/2007.
Rudolf Cornelissen 8/2003-6/2008.
This code was possible thanks to:
- the Linux XFree86 NV driver,
@@ -270,14 +270,6 @@ status_t nv_acc_init_dma()
ACCW(HT_HANDL_13, (0x80000000 | NV_SCALED_IMAGE_FROM_MEMORY)); /* 32bit handle */
ACCW(HT_VALUE_13, 0x8001114b); /* instance $114b, engine = acc engine, CHID = $00 */
//2007 3D tests..
if (si->ps.card_type == NV15)
{
ACCW(HT_HANDL_14, (0x80000000 | NV_TCL_PRIMITIVE_3D)); /* 32bit handle */
ACCW(HT_VALUE_14, 0x8001114d); /* instance $114d, engine = acc engine, CHID = $00 */
}
}
/* program CTX registers: CTX1 is mostly done later (colorspace dependant) */
@@ -359,201 +351,6 @@ status_t nv_acc_init_dma()
* table is located at end of cardRAM (b12-31):
* It's adress needs to be at a 4kb boundary! */
}
else
{
/* setup a DMA define for use by command defines below. */
ACCW(PR_CTX0_R, 0x00003000); /* DMA page table present and of linear type;
* DMA target node is NVM (non-volatile memory?)
* (instead of doing PCI or AGP transfers) */
ACCW(PR_CTX1_R, (si->ps.memory_size - 1)); /* DMA limit: size is all cardRAM */
ACCW(PR_CTX2_R, ((0x00000000 & 0xfffff000) | 0x00000002));
/* DMA access type is READ_AND_WRITE;
* memory starts at start of cardRAM (b12-31):
* It's adress needs to be at a 4kb boundary! */
ACCW(PR_CTX3_R, 0x00000002); /* unknown (looks like this is rubbish/not needed?) */
/* setup set '0' for cmd NV_ROP5_SOLID */
ACCW(PR_CTX0_0, 0x01008043); /* NVclass $043, patchcfg ROP_AND, nv10+: little endian */
ACCW(PR_CTX1_0, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_0, 0x00000000); /* DMA0 and DMA1 instance invalid */
ACCW(PR_CTX3_0, 0x00000000); /* method traps disabled */
/* setup set '1' for cmd NV_IMAGE_BLACK_RECTANGLE */
ACCW(PR_CTX0_1, 0x01008019); /* NVclass $019, patchcfg ROP_AND, nv10+: little endian */
ACCW(PR_CTX1_1, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_1, 0x00000000); /* DMA0 and DMA1 instance invalid */
ACCW(PR_CTX3_1, 0x00000000); /* method traps disabled */
/* setup set '2' for cmd NV_IMAGE_PATTERN */
ACCW(PR_CTX0_2, 0x01008018); /* NVclass $018, patchcfg ROP_AND, nv10+: little endian */
ACCW(PR_CTX1_2, 0x00000002); /* colorspace not set, notify instance is $0200 (b16-31) */
ACCW(PR_CTX2_2, 0x00000000); /* DMA0 and DMA1 instance invalid */
ACCW(PR_CTX3_2, 0x00000000); /* method traps disabled */
/* setup set '3' for ... */
if(si->ps.card_arch >= NV10A)
{
/* ... cmd NV10_CONTEXT_SURFACES_2D */
ACCW(PR_CTX0_3, 0x01008062); /* NVclass $062, nv10+: little endian */
}
else
{
/* ... cmd NV4_SURFACE */
ACCW(PR_CTX0_3, 0x01008042); /* NVclass $042, nv10+: little endian */
}
ACCW(PR_CTX1_3, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_3, 0x11401140); /* DMA0 instance is $1140, DMA1 instance invalid */
ACCW(PR_CTX3_3, 0x00000000); /* method trap 0 is $1140, trap 1 disabled */
/* setup set '4' for ... */
if (si->ps.card_type >= NV11)
{
/* ... cmd NV12_IMAGE_BLIT */
ACCW(PR_CTX0_4, 0x0100809f); /* NVclass $09f, patchcfg ROP_AND, nv10+: little endian */
}
else
{
/* ... cmd NV_IMAGE_BLIT */
ACCW(PR_CTX0_4, 0x0100805f); /* NVclass $05f, patchcfg ROP_AND, nv10+: little endian */
}
ACCW(PR_CTX1_4, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_4, 0x11401140); /* DMA0 instance is $1140, DMA1 instance invalid */
ACCW(PR_CTX3_4, 0x00000000); /* method trap 0 is $1140, trap 1 disabled */
/* setup set '5' for cmd NV4_GDI_RECTANGLE_TEXT */
ACCW(PR_CTX0_5, 0x0100804a); /* NVclass $04a, patchcfg ROP_AND, nv10+: little endian */
ACCW(PR_CTX1_5, 0x00000002); /* colorspace not set, notify instance is $0200 (b16-31) */
ACCW(PR_CTX2_5, 0x00000000); /* DMA0 and DMA1 instance invalid */
ACCW(PR_CTX3_5, 0x00000000); /* method traps disabled */
/* setup set '6' ... */
if (si->ps.card_arch >= NV10A)
{
/* ... for cmd NV10_CONTEXT_SURFACES_ARGB_ZS */
ACCW(PR_CTX0_6, 0x00000093); /* NVclass $093, nv10+: little endian */
}
else
{
/* ... for cmd NV4_CONTEXT_SURFACES_ARGB_ZS */
ACCW(PR_CTX0_6, 0x00000053); /* NVclass $053, nv10+: little endian */
}
ACCW(PR_CTX1_6, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_6, 0x11401140); /* DMA0, DMA1 instance = $1140 */
ACCW(PR_CTX3_6, 0x00000000); /* method traps disabled */
/* setup set '7' ... */
if (si->ps.card_arch >= NV10A)
{
/* ... for cmd NV10_DX5_TEXTURE_TRIANGLE */
ACCW(PR_CTX0_7, 0x0300a094); /* NVclass $094, patchcfg ROP_AND, userclip enable,
* context surface0 valid, nv10+: little endian */
}
else
{
/* ... for cmd NV4_DX5_TEXTURE_TRIANGLE */
ACCW(PR_CTX0_7, 0x0300a054); /* NVclass $054, patchcfg ROP_AND, userclip enable,
* context surface0 valid */
}
ACCW(PR_CTX1_7, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_7, 0x11401140); /* DMA0, DMA1 instance = $1140 */
ACCW(PR_CTX3_7, 0x00000000); /* method traps disabled */
/* setup set '8' ... */
if (si->ps.card_arch >= NV10A)
{
/* ... for cmd NV10_DX6_MULTI_TEXTURE_TRIANGLE (not used) */
ACCW(PR_CTX0_8, 0x0300a095); /* NVclass $095, patchcfg ROP_AND, userclip enable,
* context surface0 valid, nv10+: little endian */
}
else
{
/* ... for cmd NV4_DX6_MULTI_TEXTURE_TRIANGLE (not used) */
ACCW(PR_CTX0_8, 0x0300a055); /* NVclass $055, patchcfg ROP_AND, userclip enable,
* context surface0 valid */
}
ACCW(PR_CTX1_8, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_8, 0x11401140); /* DMA0, DMA1 instance = $1140 */
ACCW(PR_CTX3_8, 0x00000000); /* method traps disabled */
/* setup set '9' for cmd NV_SCALED_IMAGE_FROM_MEMORY */
ACCW(PR_CTX0_9, 0x01018077); /* NVclass $077, patchcfg SRC_COPY,
* context surface0 valid, nv10+: little endian */
ACCW(PR_CTX1_9, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_9, 0x11401140); /* DMA0, DMA1 instance = $1140 */
ACCW(PR_CTX3_9, 0x00000000); /* method traps disabled */
/* setup set 'A' for cmd NV1_RENDER_SOLID_LIN (not used) */
ACCW(PR_CTX0_A, 0x0300a01c); /* NVclass $01c, patchcfg ROP_AND, userclip enable,
* context surface0 valid, nv10+: little endian */
ACCW(PR_CTX1_A, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_A, 0x11401140); /* DMA0, DMA1 instance = $1140 */
ACCW(PR_CTX3_A, 0x00000000); /* method traps disabled */
//2007 3D tests..
/* setup set 'B' ... */
if (si->ps.card_type == NV15)
{
/* ... for cmd NV11_TCL_PRIMITIVE_3D */
ACCW(PR_CTX0_B, 0x0300a096); /* NVclass $096, patchcfg ROP_AND, userclip enable,
* context surface0 valid, nv10+: little endian */
ACCW(PR_CTX1_B, 0x00000000); /* colorspace not set, notify instance invalid (b16-31) */
ACCW(PR_CTX2_B, 0x11401140); /* DMA0, DMA1 instance = $1140 */
ACCW(PR_CTX3_B, 0x00000000); /* method traps disabled */
}
/* setup DMA set pointed at by PF_CACH1_DMAI */
if (0)//si->engine.agp_mode)
{
/* DMA page table present and of linear type;
* DMA class is $002 (b0-11);
* DMA target node is AGP */
ACCW(PR_CTX0_C, 0x00033002);
}
else
{
/* DMA page table present and of linear type;
* DMA class is $002 (b0-11);
* DMA target node is PCI */
ACCW(PR_CTX0_C, 0x00023002);
}
ACCW(PR_CTX1_C, 0x000fffff); /* DMA limit: tablesize is 1M bytes */
ACCW(PR_CTX2_C, (((uint32)((uint8 *)(si->dma_buffer_pci))) | 0x00000002));
/* DMA access type is READ_AND_WRITE;
* table is located in main system RAM (b12-31):
* It's adress needs to be at a 4kb boundary! */
/* set the 3D rendering functions colordepth via BPIXEL's 'depth 2' */
/* note:
* setting a depth to 'invalid' (zero) makes the engine report
* ready with drawing 'immediately'. */
//fixme: NV30A and above (probably) needs to be corrected...
switch(si->dm.space)
{
case B_CMAP8:
if (si->ps.card_arch < NV30A)
/* set depth 2: $1 = Y8 */
ACCW(BPIXEL, 0x00000100);
else
/* set depth 0-1: $1 = Y8, $2 = X1R5G5B5_Z1R5G5B5 */
ACCW(BPIXEL, 0x00000021);
break;
case B_RGB15_LITTLE:
if (si->ps.card_arch < NV30A)
/* set depth 2: $4 = A1R5G5B5 */
ACCW(BPIXEL, 0x00000400);
else
/* set depth 0-1: $2 = X1R5G5B5_Z1R5G5B5, $4 = A1R5G5B5 */
ACCW(BPIXEL, 0x00000042);
break;
case B_RGB16_LITTLE:
if (si->ps.card_arch < NV30A)
/* set depth 2: $5 = R5G6B5 */
ACCW(BPIXEL, 0x00000500);
else
/* set depth 0-1: $5 = R5G6B5, $a = X1A7R8G8B8_O1A7R8G8B8 */
ACCW(BPIXEL, 0x000000a5);
break;
case B_RGB32_LITTLE:
case B_RGBA32_LITTLE:
if (si->ps.card_arch < NV30A)
/* set depth 2: $c = A8R8G8B8 */
ACCW(BPIXEL, 0x00000c00);
else
/* set depth 0-1: $7 = X8R8G8B8_Z8R8G8B8, $e = V8YB8U8YA8 */
ACCW(BPIXEL, 0x000000e7);
break;
default:
LOG(8,("ACC: init, invalid bit depth\n"));
return B_ERROR;
}
}
if (si->ps.card_arch == NV04A)
{
@@ -921,11 +718,8 @@ status_t nv_acc_init_dma()
/* setup sync parameters for NV12_IMAGE_BLIT command for the current mode:
* values given are CRTC vertical counter limit values. The NV12 command will wait
* for the specified's CRTC's vertical counter to be in between the given values */
if (si->ps.card_type >= NV11)
{
ACCW(NV11_CRTC_LO, si->dm.timing.v_display - 1);
ACCW(NV11_CRTC_HI, si->dm.timing.v_display + 1);
}
ACCW(NV11_CRTC_LO, si->dm.timing.v_display - 1);
ACCW(NV11_CRTC_HI, si->dm.timing.v_display + 1);
/*** PFIFO ***/
/* (setup caches) */
@@ -1773,26 +1567,15 @@ void SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT_DMA(engine_token *et, scaled_blit_par
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000002; /* Format */
}
/* TNT1 has fixed operation mode 'SRCcopy' while the rest can be programmed: */
if (si->ps.card_type != NV04)
{
/* wait for room in fifo for cmds if needed. */
if (nv_acc_fifofree_dma(5) != B_OK) return;
/* now setup source bitmap colorspace */
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SETCOLORFORMAT, 2);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth; /* SetColorFormat */
/* now setup operation mode to SRCcopy */
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000003; /* SetOperation */
}
else
{
/* wait for room in fifo for cmd if needed. */
if (nv_acc_fifofree_dma(4) != B_OK) return;
/* now setup source bitmap colorspace */
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SETCOLORFORMAT, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth; /* SetColorFormat */
/* TNT1 has fixed operation mode SRCcopy */
}
/* program operation mode 'SRCcopy' */
/* wait for room in fifo for cmds if needed. */
if (nv_acc_fifofree_dma(5) != B_OK) return;
/* now setup source bitmap colorspace */
nv_acc_cmd_dma(NV_SCALED_IMAGE_FROM_MEMORY, NV_SCALED_IMAGE_FROM_MEMORY_SETCOLORFORMAT, 2);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = cmd_depth; /* SetColorFormat */
/* now setup operation mode to SRCcopy */
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000003; /* SetOperation */
/* now setup fill color (writing 2 32bit words) */
nv_acc_cmd_dma(NV4_GDI_RECTANGLE_TEXT, NV4_GDI_RECTANGLE_TEXT_COLOR1A, 1);
((uint32*)(si->dma_buffer))[si->engine.dma.current++] = 0x00000000; /* Color1A */
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/* CTRC functionality */
/* Author:
Rudolf Cornelissen 11/2002-2/2006
Rudolf Cornelissen 11/2002-6/2008
*/
#define MODULE_BIT 0x00040000
@@ -29,79 +29,8 @@ status_t nv_crtc_interrupt_enable(bool flag)
return result;
}
/* doing general fail-safe default setup here */
//fixme: this is a _very_ basic setup, and it's preliminary...
status_t nv_crtc_update_fifo()
{
uint8 bytes_per_pixel = 1;
uint32 drain;
/* we are only using this on >>coldstarted<< cards which really need this */
//fixme: re-enable or remove after general user confirmation of behaviour...
if (/*(si->settings.usebios) ||*/ (si->ps.card_type != NV05M64)) return B_OK;
/* enable access to primary head */
set_crtc_owner(0);
/* set CRTC FIFO low watermark according to memory drain */
switch(si->dm.space)
{
case B_CMAP8:
bytes_per_pixel = 1;
break;
case B_RGB15_LITTLE:
case B_RGB16_LITTLE:
bytes_per_pixel = 2;
break;
case B_RGB24_LITTLE:
bytes_per_pixel = 3;
break;
case B_RGB32_LITTLE:
bytes_per_pixel = 4;
break;
}
/* fixme:
* - I should probably include the refreshrate as well;
* - and the memory clocking speed, core clocking speed, RAM buswidth.. */
drain = si->dm.timing.h_display * si->dm.timing.v_display * bytes_per_pixel;
/* Doesn't work for other than 32bit space (yet?) */
if (si->dm.space != B_RGB32_LITTLE)
{
/* BIOS defaults */
CRTCW(FIFO, 0x03);
CRTCW(FIFO_LWM, 0x20);
LOG(4,("CRTC: FIFO low-watermark set to $20, burst size 256 (BIOS defaults)\n"));
return B_OK;
}
if (drain > (((uint32)1280) * 1024 * 4))
{
/* set CRTC FIFO burst size for 'smaller' bursts */
CRTCW(FIFO, 0x01);
/* Instruct CRTC to fetch new data 'earlier' */
CRTCW(FIFO_LWM, 0x40);
LOG(4,("CRTC: FIFO low-watermark set to $40, burst size 64\n"));
}
else
{
if (drain > (((uint32)1024) * 768 * 4))
{
/* BIOS default */
CRTCW(FIFO, 0x02);
/* Instruct CRTC to fetch new data 'earlier' */
CRTCW(FIFO_LWM, 0x40);
LOG(4,("CRTC: FIFO low-watermark set to $40, burst size 128\n"));
}
else
{
/* BIOS defaults */
CRTCW(FIFO, 0x03);
CRTCW(FIFO_LWM, 0x20);
LOG(4,("CRTC: FIFO low-watermark set to $20, burst size 256 (BIOS defaults)\n"));
}
}
return B_OK;
}
@@ -127,14 +56,7 @@ status_t nv_crtc_validate_timing(
/* NOTE: keep horizontal timing at multiples of 8! */
/* confine to a reasonable width */
if (*hd_e < 640) *hd_e = 640;
if (si->ps.card_type > NV04)
{
if (*hd_e > 2048) *hd_e = 2048;
}
else
{
if (*hd_e > 1920) *hd_e = 1920;
}
if (*hd_e > 2048) *hd_e = 2048;
/* if hor. total does not leave room for a sensible sync pulse, increase it! */
if (*ht < (*hd_e + 80)) *ht = (*hd_e + 80);
@@ -160,14 +82,7 @@ status_t nv_crtc_validate_timing(
/* confine to a reasonable height */
if (*vd_e < 480) *vd_e = 480;
if (si->ps.card_type > NV04)
{
if (*vd_e > 1536) *vd_e = 1536;
}
else
{
if (*vd_e > 1440) *vd_e = 1440;
}
if (*vd_e > 1536) *vd_e = 1536;
/*if vertical total does not leave room for a sync pulse, increase it!*/
if (*vt < (*vd_e + 3)) *vt = (*vd_e + 3);
@@ -238,12 +153,8 @@ status_t nv_crtc_set_timing(display_mode target)
* OTOH the overlay unit distorts if we reserve too much time! */
if (target.timing.h_display == si->ps.p1_timing.h_display)
{
/* NV11 timing has different constraints than later cards */
if (si->ps.card_type == NV11)
target.timing.h_total -= 56;
else
/* confirmed NV34 with 1680x1050 panel */
target.timing.h_total -= 32;
/* confirmed NV34 with 1680x1050 panel */
target.timing.h_total -= 32;
}
if (target.timing.h_sync_start == target.timing.h_display)
@@ -409,7 +320,6 @@ status_t nv_crtc_set_timing(display_mode target)
CRTCW(INTERLACE, 0xff);
/* disable CRTC slaved mode unless a panel is in use */
// fixme: this kills TVout when it was in use...
if (!si->ps.tmds1_active) CRTCW(PIXEL, (CRTCR(PIXEL) & 0x7f));
/* setup flatpanel if connected and active */
@@ -622,7 +532,7 @@ status_t nv_crtc_dpms(bool display, bool h, bool v, bool do_panel)
{
//fixme? linux only does this on dualhead cards...
//fixme: see if LVDS head can be determined with two panels there...
if (!si->ps.tmds2_active && (si->ps.card_type != NV11))
if (!si->ps.tmds2_active)
{
/* b2 = 0 = enable laptop panel backlight */
/* note: this seems to be a write-only register. */
@@ -665,7 +575,7 @@ status_t nv_crtc_dpms(bool display, bool h, bool v, bool do_panel)
{
//fixme? linux only does this on dualhead cards...
//fixme: see if LVDS head can be determined with two panels there...
if (!si->ps.tmds2_active && (si->ps.card_type != NV11))
if (!si->ps.tmds2_active)
{
/* b2 = 1 = disable laptop panel backlight */
/* note: this seems to be a write-only register. */
@@ -984,131 +894,3 @@ status_t nv_crtc_cursor_position(uint16 x, uint16 y)
return B_OK;
}
status_t nv_crtc_stop_tvout(void)
{
uint16 cnt;
LOG(4,("CRTC: stopping TV output\n"));
/* enable access to primary head */
set_crtc_owner(0);
/* just to be sure Vsync is _really_ enabled */
CRTCW(REPAINT1, (CRTCR(REPAINT1) & 0xbf));
/* wait for one image to be generated to make sure VGA has kicked in and is
* running OK before continuing...
* (Kicking in will fail often if we do not wait here) */
/* Note:
* The used CRTC's Vsync is required to be enabled here. The DPMS state
* programming in the driver makes sure this is the case.
* (except for driver startup: see nv_general.c.) */
/* make sure we are 'in' active VGA picture: wait with timeout! */
cnt = 1;
while ((NV_REG8(NV8_INSTAT1) & 0x08) && cnt)
{
snooze(1);
cnt++;
}
/* wait for next vertical retrace start on VGA: wait with timeout! */
cnt = 1;
while ((!(NV_REG8(NV8_INSTAT1) & 0x08)) && cnt)
{
snooze(1);
cnt++;
}
/* now wait until we are 'in' active VGA picture again: wait with timeout! */
cnt = 1;
while ((NV_REG8(NV8_INSTAT1) & 0x08) && cnt)
{
snooze(1);
cnt++;
}
/* set CRTC to master mode (b7 = 0) if it wasn't slaved for a panel before */
if (!(si->ps.slaved_tmds1)) CRTCW(PIXEL, (CRTCR(PIXEL) & 0x03));
/* CAUTION:
* On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but
* write actions do succeed ...
* This is confirmed for both ISA and PCI access, on NV04 and NV11. */
/* setup TVencoder connection */
/* b1-0 = %00: encoder type is SLAVE;
* b24 = 1: VIP datapos is b0-7 */
//fixme if needed: setup completely instead of relying on pre-init by BIOS..
//(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work)
DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000003) | 0x01000000));
/* tell GPU to use pixelclock from internal source instead of using TVencoder */
if (si->ps.secondary_head)
DACW(PLLSEL, 0x30000f00);
else
DACW(PLLSEL, 0x10000700);
/* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of
* H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */
CRTCW(TREG, 0x00);
/* select panel encoder, not TV encoder if needed (b0 = 1).
* Note:
* Both are devices (often) using the CRTC in slaved mode. */
if (si->ps.slaved_tmds1) CRTCW(LCD, (CRTCR(LCD) | 0x01));
return B_OK;
}
status_t nv_crtc_start_tvout(void)
{
LOG(4,("CRTC: starting TV output\n"));
if (si->ps.secondary_head)
{
/* switch TV encoder to CRTC1 */
NV_REG32(NV32_2FUNCSEL) &= ~0x00000100;
NV_REG32(NV32_FUNCSEL) |= 0x00000100;
}
/* enable access to primary head */
set_crtc_owner(0);
/* CAUTION:
* On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but
* write actions do succeed ...
* This is confirmed for both ISA and PCI access, on NV04 and NV11. */
/* setup TVencoder connection */
/* b1-0 = %01: encoder type is MASTER;
* b24 = 1: VIP datapos is b0-7 */
//fixme if needed: setup completely instead of relying on pre-init by BIOS..
//(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work)
DACW(TV_SETUP, ((DACR(TV_SETUP) & ~0x00000002) | 0x01000001));
/* tell GPU to use pixelclock from TVencoder instead of using internal source */
/* (nessecary or display will 'shiver' on both TV and VGA.) */
if (si->ps.secondary_head)
DACW(PLLSEL, 0x20030f00);
else
DACW(PLLSEL, 0x00030700);
/* Set overscan color to 'black' */
/* note:
* Change this instruction for a visible overscan color if you're trying to
* center the output on TV. Use it as a guide-'line' then ;-) */
ATBW(OSCANCOLOR, 0x00);
/* set CRTC to slaved mode (b7 = 1) and clear TVadjust (b3-5 = %000) */
CRTCW(PIXEL, ((CRTCR(PIXEL) & 0xc7) | 0x80));
/* select TV encoder, not panel encoder (b0 = 0).
* Note:
* Both are devices (often) using the CRTC in slaved mode. */
CRTCW(LCD, (CRTCR(LCD) & 0xfe));
/* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of
* H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */
CRTCW(TREG, 0x80);
return B_OK;
}
@@ -1,6 +1,6 @@
/* second CTRC functionality for GeForce cards */
/* Author:
Rudolf Cornelissen 11/2002-2/2006
Rudolf Cornelissen 11/2002-6/2008
*/
#define MODULE_BIT 0x00020000
@@ -29,79 +29,8 @@ status_t nv_crtc2_interrupt_enable(bool flag)
return result;
}
/* doing general fail-safe default setup here */
//fixme: this is a _very_ basic setup, and it's preliminary...
status_t nv_crtc2_update_fifo()
{
uint8 bytes_per_pixel = 1;
uint32 drain;
/* we are only using this on >>coldstarted<< cards which really need this */
//fixme: re-enable or remove after general user confirmation of behaviour...
if (/*(si->settings.usebios) ||*/ (si->ps.card_type != NV11)) return B_OK;
/* enable access to secondary head */
set_crtc_owner(1);
/* set CRTC FIFO low watermark according to memory drain */
switch(si->dm.space)
{
case B_CMAP8:
bytes_per_pixel = 1;
break;
case B_RGB15_LITTLE:
case B_RGB16_LITTLE:
bytes_per_pixel = 2;
break;
case B_RGB24_LITTLE:
bytes_per_pixel = 3;
break;
case B_RGB32_LITTLE:
bytes_per_pixel = 4;
break;
}
/* fixme:
* - I should probably include the refreshrate as well;
* - and the memory clocking speed, core clocking speed, RAM buswidth.. */
drain = si->dm.timing.h_display * si->dm.timing.v_display * bytes_per_pixel;
/* Doesn't work for other than 32bit space (yet?) */
if (si->dm.space != B_RGB32_LITTLE)
{
/* BIOS defaults */
CRTC2W(FIFO, 0x03);
CRTC2W(FIFO_LWM, 0x20);
LOG(4,("CRTC2: FIFO low-watermark set to $20, burst size 256 (BIOS defaults)\n"));
return B_OK;
}
if (drain > (((uint32)1280) * 1024 * 4))
{
/* set CRTC FIFO burst size for 'smaller' bursts */
CRTC2W(FIFO, 0x01);
/* Instruct CRTC to fetch new data 'earlier' */
CRTC2W(FIFO_LWM, 0x40);
LOG(4,("CRTC2: FIFO low-watermark set to $40, burst size 64\n"));
}
else
{
if (drain > (((uint32)1024) * 768 * 4))
{
/* BIOS default */
CRTC2W(FIFO, 0x02);
/* Instruct CRTC to fetch new data 'earlier' */
CRTC2W(FIFO_LWM, 0x40);
LOG(4,("CRTC2: FIFO low-watermark set to $40, burst size 128\n"));
}
else
{
/* BIOS defaults */
CRTC2W(FIFO, 0x03);
CRTC2W(FIFO_LWM, 0x20);
LOG(4,("CRTC2: FIFO low-watermark set to $20, burst size 256 (BIOS defaults)\n"));
}
}
return B_OK;
}
@@ -224,12 +153,8 @@ status_t nv_crtc2_set_timing(display_mode target)
* OTOH the overlay unit distorts if we reserve too much time! */
if (target.timing.h_display == si->ps.p2_timing.h_display)
{
/* NV11 timing has different constraints than later cards */
if (si->ps.card_type == NV11)
target.timing.h_total -= 56;
else
/* confirmed NV34 with 1680x1050 panel */
target.timing.h_total -= 32;
/* confirmed NV34 with 1680x1050 panel */
target.timing.h_total -= 32;
}
if (target.timing.h_sync_start == target.timing.h_display)
@@ -392,7 +317,6 @@ status_t nv_crtc2_set_timing(display_mode target)
CRTC2W(INTERLACE, 0xff);
/* disable CRTC slaved mode unless a panel is in use */
// fixme: this kills TVout when it was in use...
if (!si->ps.tmds2_active) CRTC2W(PIXEL, (CRTC2R(PIXEL) & 0x7f));
/* setup flatpanel if connected and active */
@@ -604,7 +528,7 @@ status_t nv_crtc2_dpms(bool display, bool h, bool v, bool do_panel)
else
{
//fixme: see if LVDS head can be determined with two panels there...
if (!si->ps.tmds1_active && (si->ps.card_type != NV11))
if (!si->ps.tmds1_active)
{
/* b2 = 0 = enable laptop panel backlight */
/* note: this seems to be a write-only register. */
@@ -646,7 +570,7 @@ status_t nv_crtc2_dpms(bool display, bool h, bool v, bool do_panel)
else
{
//fixme: see if LVDS head can be determined with two panels there...
if (!si->ps.tmds1_active && (si->ps.card_type != NV11))
if (!si->ps.tmds1_active)
{
/* b2 = 1 = disable laptop panel backlight */
/* note: this seems to be a write-only register. */
@@ -899,122 +823,3 @@ status_t nv_crtc2_cursor_position(uint16 x, uint16 y)
return B_OK;
}
status_t nv_crtc2_stop_tvout(void)
{
uint16 cnt;
LOG(4,("CRTC2: stopping TV output\n"));
/* enable access to secondary head */
set_crtc_owner(1);
/* just to be sure Vsync is _really_ enabled */
CRTC2W(REPAINT1, (CRTC2R(REPAINT1) & 0xbf));
/* wait for one image to be generated to make sure VGA has kicked in and is
* running OK before continuing...
* (Kicking in will fail often if we do not wait here) */
/* Note:
* The used CRTC's Vsync is required to be enabled here. The DPMS state
* programming in the driver makes sure this is the case.
* (except for driver startup: see nv_general.c.) */
/* make sure we are 'in' active VGA picture: wait with timeout! */
cnt = 1;
while ((NV_REG8(NV8_INSTAT1) & 0x08) && cnt)
{
snooze(1);
cnt++;
}
/* wait for next vertical retrace start on VGA: wait with timeout! */
cnt = 1;
while ((!(NV_REG8(NV8_INSTAT1) & 0x08)) && cnt)
{
snooze(1);
cnt++;
}
/* now wait until we are 'in' active VGA picture again: wait with timeout! */
cnt = 1;
while ((NV_REG8(NV8_INSTAT1) & 0x08) && cnt)
{
snooze(1);
cnt++;
}
/* set CRTC to master mode (b7 = 0) if it wasn't slaved for a panel before */
if (!(si->ps.slaved_tmds2)) CRTC2W(PIXEL, (CRTC2R(PIXEL) & 0x03));
/* CAUTION:
* On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but
* write actions do succeed ...
* This is confirmed for both ISA and PCI access, on NV04 and NV11. */
/* setup TVencoder connection */
/* b1-0 = %00: encoder type is SLAVE;
* b24 = 1: VIP datapos is b0-7 */
//fixme if needed: setup completely instead of relying on pre-init by BIOS..
//(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work)
DAC2W(TV_SETUP, ((DAC2R(TV_SETUP) & ~0x00000003) | 0x01000000));
/* tell GPU to use pixelclock from internal source instead of using TVencoder */
DACW(PLLSEL, 0x30000f00);
/* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of
* H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */
CRTC2W(TREG, 0x00);
/* select panel encoder, not TV encoder if needed (b0 = 1).
* Note:
* Both are devices (often) using the CRTC in slaved mode. */
if (si->ps.slaved_tmds2) CRTC2W(LCD, (CRTC2R(LCD) | 0x01));
return B_OK;
}
status_t nv_crtc2_start_tvout(void)
{
LOG(4,("CRTC2: starting TV output\n"));
/* switch TV encoder to CRTC2 */
NV_REG32(NV32_FUNCSEL) &= ~0x00000100;
NV_REG32(NV32_2FUNCSEL) |= 0x00000100;
/* enable access to secondary head */
set_crtc_owner(1);
/* CAUTION:
* On old cards, PLLSEL (and TV_SETUP?) cannot be read (sometimes?), but
* write actions do succeed ...
* This is confirmed for both ISA and PCI access, on NV04 and NV11. */
/* setup TVencoder connection */
/* b1-0 = %01: encoder type is MASTER;
* b24 = 1: VIP datapos is b0-7 */
//fixme if needed: setup completely instead of relying on pre-init by BIOS..
//(it seems to work OK on NV04 and NV11 although read reg. doesn't seem to work)
DAC2W(TV_SETUP, ((DAC2R(TV_SETUP) & ~0x00000002) | 0x01000001));
/* tell GPU to use pixelclock from TVencoder instead of using internal source */
/* (nessecary or display will 'shiver' on both TV and VGA.) */
DACW(PLLSEL, 0x100c0f00);
/* Set overscan color to 'black' */
/* note:
* Change this instruction for a visible overscan color if you're trying to
* center the output on TV. Use it as a guide-'line' then ;-) */
ATB2W(OSCANCOLOR, 0x00);
/* set CRTC to slaved mode (b7 = 1) and clear TVadjust (b3-5 = %000) */
CRTC2W(PIXEL, ((CRTC2R(PIXEL) & 0xc7) | 0x80));
/* select TV encoder, not panel encoder (b0 = 0).
* Note:
* Both are devices (often) using the CRTC in slaved mode. */
CRTC2W(LCD, (CRTC2R(LCD) & 0xfe));
/* HTOTAL, VTOTAL and OVERFLOW return their default CRTC use, instead of
* H, V-low and V-high 'shadow' counters(?)(b0, 4 and 6 = 0) (b7 use = unknown) */
CRTC2W(TREG, 0x80);
return B_OK;
}
@@ -250,8 +250,6 @@ void setup_virtualized_heads(bool cross)
head1_cursor_hide = (crtc_cursor_hide) nv_crtc2_cursor_hide;
head1_cursor_define = (crtc_cursor_define) nv_crtc2_cursor_define;
head1_cursor_position = (crtc_cursor_position) nv_crtc2_cursor_position;
head1_stop_tvout = (crtc_stop_tvout) nv_crtc2_stop_tvout;
head1_start_tvout = (crtc_start_tvout) nv_crtc2_start_tvout;
head1_mode = (dac_mode) nv_dac2_mode;
head1_palette = (dac_palette) nv_dac2_palette;
@@ -271,8 +269,6 @@ void setup_virtualized_heads(bool cross)
head2_cursor_hide = (crtc_cursor_hide) nv_crtc_cursor_hide;
head2_cursor_define = (crtc_cursor_define) nv_crtc_cursor_define;
head2_cursor_position = (crtc_cursor_position) nv_crtc_cursor_position;
head2_stop_tvout = (crtc_stop_tvout) nv_crtc_stop_tvout;
head2_start_tvout = (crtc_start_tvout) nv_crtc_start_tvout;
head2_mode = (dac_mode) nv_dac_mode;
head2_palette = (dac_palette) nv_dac_palette;
@@ -294,8 +290,6 @@ void setup_virtualized_heads(bool cross)
head1_cursor_hide = (crtc_cursor_hide) nv_crtc_cursor_hide;
head1_cursor_define = (crtc_cursor_define) nv_crtc_cursor_define;
head1_cursor_position = (crtc_cursor_position) nv_crtc_cursor_position;
head1_stop_tvout = (crtc_stop_tvout) nv_crtc_stop_tvout;
head1_start_tvout = (crtc_start_tvout) nv_crtc_start_tvout;
head1_mode = (dac_mode) nv_dac_mode;
head1_palette = (dac_palette) nv_dac_palette;
@@ -315,8 +309,6 @@ void setup_virtualized_heads(bool cross)
head2_cursor_hide = (crtc_cursor_hide) nv_crtc2_cursor_hide;
head2_cursor_define = (crtc_cursor_define) nv_crtc2_cursor_define;
head2_cursor_position = (crtc_cursor_position) nv_crtc2_cursor_position;
head2_stop_tvout = (crtc_stop_tvout) nv_crtc2_stop_tvout;
head2_start_tvout = (crtc_start_tvout) nv_crtc2_start_tvout;
head2_mode = (dac_mode) nv_dac2_mode;
head2_palette = (dac_palette) nv_dac2_palette;
@@ -391,8 +383,7 @@ static status_t nvxx_general_powerup()
// unlock_card();
/* get RAM size, detect TV encoder and do fake panel startup (panel init code
* is still missing). */
/* get RAM size and do fake panel startup (panel init code is still missing). */
// fake_panel_start();
/* log the final card specifications */
@@ -417,34 +408,26 @@ status_t nv_general_output_select(bool cross)
/* make sure this call is warranted */
if (si->ps.secondary_head)
{
/* NV11 cards can't switch heads (confirmed) */
if (si->ps.card_type != NV11)
if (cross)
{
if (cross)
{
LOG(4,("INIT: switching analog outputs to be cross-connected\n"));
LOG(4,("INIT: switching analog outputs to be cross-connected\n"));
/* enable head 2 on connector 1 */
/* (b8 = select CRTC (head) for output,
* b4 = ??? (confirmed not to be a FP switch),
* b0 = enable CRT) */
DACW(OUTPUT, 0x00000101);
/* enable head 1 on connector 2 */
DAC2W(OUTPUT, 0x00000001);
}
else
{
LOG(4,("INIT: switching analog outputs to be straight-through\n"));
/* enable head 1 on connector 1 */
DACW(OUTPUT, 0x00000001);
/* enable head 2 on connector 2 */
DAC2W(OUTPUT, 0x00000101);
}
/* enable head 2 on connector 1 */
/* (b8 = select CRTC (head) for output,
* b4 = ??? (confirmed not to be a FP switch),
* b0 = enable CRT) */
DACW(OUTPUT, 0x00000101);
/* enable head 1 on connector 2 */
DAC2W(OUTPUT, 0x00000001);
}
else
{
LOG(4,("INIT: NV11 analog outputs are hardwired to be straight-through\n"));
LOG(4,("INIT: switching analog outputs to be straight-through\n"));
/* enable head 1 on connector 1 */
DACW(OUTPUT, 0x00000001);
/* enable head 2 on connector 2 */
DAC2W(OUTPUT, 0x00000101);
}
return B_OK;
}
@@ -24,8 +24,6 @@ typedef status_t (*crtc_cursor_show)(void);
typedef status_t (*crtc_cursor_hide)(void);
typedef status_t (*crtc_cursor_define)(uint8*, uint8*);
typedef status_t (*crtc_cursor_position)(uint16, uint16);
typedef status_t (*crtc_stop_tvout)(void);
typedef status_t (*crtc_start_tvout)(void);
typedef status_t (*dac_mode)(int, float);
typedef status_t (*dac_palette)(uint8[256], uint8[256], uint8[256]);
@@ -45,8 +43,6 @@ crtc_cursor_show head1_cursor_show;
crtc_cursor_hide head1_cursor_hide;
crtc_cursor_define head1_cursor_define;
crtc_cursor_position head1_cursor_position;
crtc_stop_tvout head1_stop_tvout;
crtc_start_tvout head1_start_tvout;
crtc_interrupt_enable head2_interrupt_enable;
crtc_update_fifo head2_update_fifo;
@@ -61,8 +57,6 @@ crtc_cursor_show head2_cursor_show;
crtc_cursor_hide head2_cursor_hide;
crtc_cursor_define head2_cursor_define;
crtc_cursor_position head2_cursor_position;
crtc_stop_tvout head2_stop_tvout;
crtc_start_tvout head2_start_tvout;
dac_mode head1_mode;
dac_palette head1_palette;
@@ -1,7 +1,7 @@
/* Read initialisation information from card */
/* some bits are hacks, where PINS is not known */
/* Author:
Rudolf Cornelissen 7/2003-3/2006
Rudolf Cornelissen 7/2003-6/2008
*/
#define MODULE_BIT 0x00002000
@@ -21,10 +21,7 @@ typedef struct {
static void detect_panels(void);
static void setup_output_matrix(void);
static void pinsnv4_fake(void);
static void pinsnv5_nv5m64_fake(void);
static void pinsnv6_fake(void);
static void pinsnv10_arch_fake(void);
static void pinsnv20_arch_fake(void);
static void pinsnv30_arch_fake(void);
static void getRAMsize_arch_nv4(void);
@@ -2104,36 +2101,18 @@ void set_specs(void)
LOG(8,("INFO: setting up card specifications\n"));
/* set failsave speeds */
switch (si->ps.card_type)
switch (si->ps.card_arch)
{
case NV04:
pinsnv4_fake();
case NV20A:
pinsnv20_arch_fake();
break;
case NV05:
case NV05M64:
pinsnv5_nv5m64_fake();
break;
case NV06:
pinsnv6_fake();
case NV30A:
case NV40A:
pinsnv30_arch_fake();
break;
default:
switch (si->ps.card_arch)
{
case NV10A:
pinsnv10_arch_fake();
break;
case NV20A:
pinsnv20_arch_fake();
break;
case NV30A:
case NV40A:
pinsnv30_arch_fake();
break;
default:
/* 'failsafe' values... */
pinsnv10_arch_fake();
break;
}
/* 'failsafe' values... */
pinsnv20_arch_fake();
break;
}
@@ -2172,13 +2151,7 @@ void fake_panel_start(void)
si->ps.memory_size = si->settings.memory * 1024 * 1024;
}
/* find out if the card has a tvout chip */
si->ps.tvout = false;
si->ps.tv_encoder.type = NONE;
si->ps.tv_encoder.version = 0;
i2c_init();
//fixme: add support for more encoders...
BT_probe();
LOG(8,("INFO: faking panel startup\n"));
@@ -2198,14 +2171,13 @@ void fake_panel_start(void)
static void detect_panels()
{
/* detect if the BIOS enabled LCD's (internal panels or DVI) or TVout */
/* detect if the BIOS enabled LCD's (internal panels or DVI) */
/* both external TMDS transmitters (used for LCD/DVI) and external TVencoders
* (can) use the CRTC's in slaved mode. */
/* Note:
* DFP's are programmed with standard VESA modelines by the card's BIOS! */
bool slaved_for_dev1 = false, slaved_for_dev2 = false;
bool tvout1 = false, tvout2 = false;
/* check primary head: */
/* enable access to primary head */
@@ -2236,11 +2208,6 @@ static void detect_panels()
/* detect active slave device (if any) */
slaved_for_dev1 = (CRTCR(PIXEL) & 0x80);
if (slaved_for_dev1)
{
/* if the panel isn't selected, tvout is.. */
tvout1 = !(CRTCR(LCD) & 0x01);
}
if (si->ps.secondary_head)
{
@@ -2258,11 +2225,6 @@ static void detect_panels()
/* detect active slave device (if any) */
slaved_for_dev2 = (CRTC2R(PIXEL) & 0x80);
if (slaved_for_dev2)
{
/* if the panel isn't selected, tvout is.. */
tvout2 = !(CRTC2R(LCD) & 0x01);
}
}
LOG(2,("INFO: End flatpanel related CRTC registers dump.\n"));
@@ -2283,29 +2245,22 @@ static void detect_panels()
/* determine the situation we are in... (regarding flatpanels) */
/* fixme: add VESA DDC EDID stuff one day... */
/* fixme: find out how to program those transmitters one day instead of
* relying on the cards BIOS to do it. This adds TVout options where panels
* are used!
* relying on the cards BIOS to do it.
* Currently we'd loose the panel setup while not being able to restore it. */
/* note: (facts)
* -> NV11 and NV17 laptops have LVDS panels, programmed in both sets registers;
* -> NV34 laptops have TMDS panels, programmed in only one set of registers;
* -> NV11, NV25 and NV34 DVI cards, so external panels (TMDS) are programmed
* in only one set of registers;
* -> a register-set's FP_TG_CTRL register, bit 31 tells you if a LVDS panel is
* connected to the primary head (0), or to the secondary head (1) except
* on some NV11's if this bit is '0' there;
* connected to the primary head (0), or to the secondary head (1);
* -> for LVDS panels both registersets are programmed identically by the card's
* BIOSes;
* -> the programmed set of registers tells you where a TMDS (DVI) panel is
* connected;
* -> On all cards a CRTC is used in slaved mode when a panel is connected,
* except on NV11: here master mode is (might be?) detected. */
* -> On all cards a CRTC is used in slaved mode when a panel is connected. */
/* note also:
* external TMDS encoders are only used for logic-level translation: it's
* modeline registers are not used. Instead the GPU's internal modeline registers
* are used. The external encoder is not connected to a I2C bus (confirmed NV34). */
if (slaved_for_dev1 && !tvout1)
if (slaved_for_dev1)
{
uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
uint16 height = ((DACR(FP_VDISPEND) & 0x0000ffff) + 1);
@@ -2318,7 +2273,7 @@ static void detect_panels()
}
}
if (si->ps.secondary_head && slaved_for_dev2 && !tvout2)
if (si->ps.secondary_head && slaved_for_dev2)
{
uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1);
uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);
@@ -2331,34 +2286,6 @@ static void detect_panels()
}
}
if ((si->ps.card_type == NV11) &&
!si->ps.slaved_tmds1 && !tvout1)
{
uint16 width = ((DACR(FP_HDISPEND) & 0x0000ffff) + 1);
uint16 height = ((DACR(FP_VDISPEND) & 0x0000ffff) + 1);
if ((width >= 640) && (height >= 480))
{
si->ps.master_tmds1 = true;
si->ps.tmds1_active = true;
si->ps.p1_timing.h_display = width;
si->ps.p1_timing.v_display = height;
}
}
if ((si->ps.card_type == NV11) &&
si->ps.secondary_head && !si->ps.slaved_tmds2 && !tvout2)
{
uint16 width = ((DAC2R(FP_HDISPEND) & 0x0000ffff) + 1);
uint16 height = ((DAC2R(FP_VDISPEND) & 0x0000ffff) + 1);
if ((width >= 640) && (height >= 480))
{
si->ps.master_tmds2 = true;
si->ps.tmds2_active = true;
si->ps.p2_timing.h_display = width;
si->ps.p2_timing.v_display = height;
}
}
//fixme...:
//we are assuming that no DVI is used as external monitor on laptops;
//otherwise we probably get into trouble here if the checked specs match.
@@ -2369,9 +2296,9 @@ static void detect_panels()
{
LOG(2,("INFO: correcting double detection of single panel!\n"));
if (si->ps.card_type == NV11)
if (DACR(FP_TG_CTRL) & 0x80000000)
{
/* LVDS panel is _always_ on CRTC2, so clear false primary detection */
/* LVDS panel is on CRTC2, so clear false primary detection */
si->ps.slaved_tmds1 = false;
si->ps.master_tmds1 = false;
si->ps.tmds1_active = false;
@@ -2380,24 +2307,12 @@ static void detect_panels()
}
else
{
if (DACR(FP_TG_CTRL) & 0x80000000)
{
/* LVDS panel is on CRTC2, so clear false primary detection */
si->ps.slaved_tmds1 = false;
si->ps.master_tmds1 = false;
si->ps.tmds1_active = false;
si->ps.p1_timing.h_display = 0;
si->ps.p1_timing.v_display = 0;
}
else
{
/* LVDS panel is on CRTC1, so clear false secondary detection */
si->ps.slaved_tmds2 = false;
si->ps.master_tmds2 = false;
si->ps.tmds2_active = false;
si->ps.p2_timing.h_display = 0;
si->ps.p2_timing.v_display = 0;
}
/* LVDS panel is on CRTC1, so clear false secondary detection */
si->ps.slaved_tmds2 = false;
si->ps.master_tmds2 = false;
si->ps.tmds2_active = false;
si->ps.p2_timing.h_display = 0;
si->ps.p2_timing.v_display = 0;
}
}
@@ -2516,12 +2431,9 @@ static void detect_panels()
}
/* determine flatpanel type(s) */
/* note:
* on NV11 accessing registerset(s) hangs card. */
//fixme: how about NV11's with panels?
//fixme?: linux checks on (only and) all dualhead cards, and only on DAC1...
//fixme: testing...
if (/*si->ps.tmds1_active && */(si->ps.card_type != NV11))
if (/*si->ps.tmds1_active && */1)
{
/* Read a indexed register to see if it indicates LVDS or TMDS panel presence.
* b0-7 = adress, b16 = 1 = write_enable */
@@ -2533,8 +2445,8 @@ static void detect_panels()
LOG(2,("INFO: Flatpanel on head 1 is TMDS type\n"));
}
//fixme: testing...
// if (si->ps.tmds2_active && (si->ps.card_type != NV11))
if (si->ps.secondary_head && (si->ps.card_type != NV11))
// if (si->ps.tmds2_active)
if (si->ps.secondary_head)
{
/* Read a indexed register to see if it indicates LVDS or TMDS panel presence.
* b0-7 = adress, b16 = 1 = write_enable */
@@ -2560,178 +2472,113 @@ static void setup_output_matrix()
/* setup output devices and heads */
if (si->ps.secondary_head)
{
if (si->ps.card_type != NV11)
/* setup defaults: */
/* connect analog outputs straight through */
nv_general_output_select(false);
/* presetup by the card's BIOS, we can't change this (lack of info) */
if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
/* detect analog monitors (confirmed working OK on NV18, NV28 and NV34): */
/* sense analog monitor on primary connector */
if (nv_dac_crt_connected()) si->ps.monitors |= 0x02;
/* sense analog monitor on secondary connector */
if (nv_dac2_crt_connected()) si->ps.monitors |= 0x20;
/* setup correct output and head use */
switch (si->ps.monitors)
{
/* setup defaults: */
/* connect analog outputs straight through */
nv_general_output_select(false);
/* presetup by the card's BIOS, we can't change this (lack of info) */
if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
/* detect analog monitors (confirmed working OK on NV18, NV28 and NV34): */
/* sense analog monitor on primary connector */
if (nv_dac_crt_connected()) si->ps.monitors |= 0x02;
/* sense analog monitor on secondary connector */
if (nv_dac2_crt_connected()) si->ps.monitors |= 0x20;
/* setup correct output and head use */
//fixme? add TVout (only, so no CRT(s) connected) support...
switch (si->ps.monitors)
case 0x00: /* no monitor found at all */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x01: /* digital panel on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x02: /* analog panel or CRT on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x03: /* both types on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has a digital panel AND an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: correcting...\n"));
/* cross connect analog outputs so analog panel or CRT gets head 2 */
nv_general_output_select(true);
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x10: /* nothing on head 1, digital panel on head 2 */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x20: /* nothing on head 1, analog panel or CRT on head 2 */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x30: /* nothing on head 1, both types on head 2 */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has a digital panel AND an analog panel or CRT:\n"));
LOG(2,("INFO: correcting...\n"));
/* cross connect analog outputs so analog panel or CRT gets head 1 */
nv_general_output_select(true);
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x11: /* digital panels on both heads */
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x12: /* analog panel or CRT on head 1, digital panel on head 2 */
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x21: /* digital panel on head 1, analog panel or CRT on head 2 */
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x22: /* analog panel(s) or CRT(s) on both heads */
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x32: /* more than two monitors connected to just two outputs: illegal! */
//general fixme:
//NV40 architecture contains (an) additional switch(es) to
//connect a CRTC/DAC combination to a connector. We can't work as
//usual (yet) because this interferes via BIOS card pre-programming.
//
//Also: it looks as if each pixelclock PLL can select different CRTC's
//as well now via a new register: one PLL can be driving both CRTC's
//and there's nothing we can do about that (yet). (DVI/dualhead trouble)
if (si->ps.card_arch < NV40A)
{
case 0x00: /* no monitor found at all */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x01: /* digital panel on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x02: /* analog panel or CRT on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x03: /* both types on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has a digital panel AND an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: correcting...\n"));
/* cross connect analog outputs so analog panel or CRT gets head 2 */
nv_general_output_select(true);
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x10: /* nothing on head 1, digital panel on head 2 */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x20: /* nothing on head 1, analog panel or CRT on head 2 */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x30: /* nothing on head 1, both types on head 2 */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has a digital panel AND an analog panel or CRT:\n"));
LOG(2,("INFO: correcting...\n"));
/* cross connect analog outputs so analog panel or CRT gets head 1 */
nv_general_output_select(true);
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x11: /* digital panels on both heads */
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x12: /* analog panel or CRT on head 1, digital panel on head 2 */
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x21: /* digital panel on head 1, analog panel or CRT on head 2 */
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x22: /* analog panel(s) or CRT(s) on both heads */
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has an analog panel or CRT:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x32: /* more than two monitors connected to just two outputs: illegal! */
//general fixme:
//NV40 architecture contains (an) additional switch(es) to
//connect a CRTC/DAC combination to a connector. We can't work as
//usual (yet) because this interferes via BIOS card pre-programming.
//
//Also: it looks as if each pixelclock PLL can select different CRTC's
//as well now via a new register: one PLL can be driving both CRTC's
//and there's nothing we can do about that (yet). (DVI/dualhead trouble)
if (si->ps.card_arch < NV40A)
{
LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors));
/* head 2 takes precedence because it has a digital panel while
* head 1 has not. */
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
}
default: /* more than two monitors connected to just two outputs: illegal! */
LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
}
}
else /* dualhead NV11 cards */
{
/* confirmed no analog output switch-options for NV11 */
LOG(2,("INFO: NV11 outputs are hardwired to be straight-through\n"));
/* presetup by the card's BIOS, we can't change this (lack of info) */
if (si->ps.tmds1_active) si->ps.monitors |= 0x01;
if (si->ps.tmds2_active) si->ps.monitors |= 0x10;
/* detect analog monitor (confirmed working OK on NV11): */
/* sense analog monitor on primary connector */
if (nv_dac_crt_connected()) si->ps.monitors |= 0x02;
/* (sense analog monitor on secondary connector is impossible on NV11) */
/* setup correct output and head use */
//fixme? add TVout (only, so no CRT(s) connected) support...
switch (si->ps.monitors)
{
case 0x00: /* no monitor found at all */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x01: /* digital panel on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x02: /* analog panel or CRT on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x03: /* both types on head 1, nothing on head 2 */
LOG(2,("INFO: head 1 has a digital panel AND an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has nothing connected:\n"));
LOG(2,("INFO: correction not possible...\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x10: /* nothing on head 1, digital panel on head 2 */
LOG(2,("INFO: head 1 has nothing connected;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
case 0x11: /* digital panels on both heads */
LOG(2,("INFO: head 1 has a digital panel;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
case 0x12: /* analog panel or CRT on head 1, digital panel on head 2 */
LOG(2,("INFO: head 1 has an analog panel or CRT;\n"));
LOG(2,("INFO: head 2 has a digital panel:\n"));
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
default: /* more than two monitors connected to just two outputs: illegal! */
LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
/* head 2 takes precedence because it has a digital panel while
* head 1 has not. */
LOG(2,("INFO: defaulting to head 2 for primary use.\n"));
si->ps.crtc2_prim = true;
break;
}
default: /* more than two monitors connected to just two outputs: illegal! */
LOG(2,("INFO: illegal monitor setup ($%02x):\n", si->ps.monitors));
LOG(2,("INFO: defaulting to head 1 for primary use.\n"));
break;
}
}
else /* singlehead cards */
@@ -2741,8 +2588,6 @@ static void setup_output_matrix()
/* detect analog monitor (confirmed working OK on all cards): */
/* sense analog monitor on primary connector */
if (nv_dac_crt_connected()) si->ps.monitors |= 0x02;
//fixme? add TVout (only, so no CRT connected) support...
}
}
@@ -2781,160 +2626,6 @@ void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2)
*pan2 = false;
}
static void pinsnv4_fake(void)
{
/* we have a standard PLL */
si->ps.ext_pll = false;
/* carefull not to take to high limits, and high should be >= 2x low. */
si->ps.max_system_vco = 256;
si->ps.min_system_vco = 128;
si->ps.max_pixel_vco = 256;
si->ps.min_pixel_vco = 128;
si->ps.max_video_vco = 0;
si->ps.min_video_vco = 0;
si->ps.max_dac1_clock = 250;
si->ps.max_dac1_clock_8 = 250;
si->ps.max_dac1_clock_16 = 250;
/* 'failsave' values */
si->ps.max_dac1_clock_24 = 220;
si->ps.max_dac1_clock_32 = 180;
si->ps.max_dac1_clock_32dh = 180;
/* secondary head */
si->ps.max_dac2_clock = 0;
si->ps.max_dac2_clock_8 = 0;
si->ps.max_dac2_clock_16 = 0;
si->ps.max_dac2_clock_24 = 0;
si->ps.max_dac2_clock_32 = 0;
/* 'failsave' values */
si->ps.max_dac2_clock_32dh = 0;
//fixme: primary & secondary_dvi should be overrule-able via nv.settings
si->ps.primary_dvi = false;
si->ps.secondary_dvi = false;
/* not used (yet) because no coldstart will be attempted (yet) */
si->ps.std_engine_clock = 90;
si->ps.std_memory_clock = 110;
}
static void pinsnv5_nv5m64_fake(void)
{
/* we have a standard PLL */
si->ps.ext_pll = false;
/* carefull not to take to high limits, and high should be >= 2x low. */
si->ps.max_system_vco = 300;
si->ps.min_system_vco = 128;
si->ps.max_pixel_vco = 300;
si->ps.min_pixel_vco = 128;
si->ps.max_video_vco = 0;
si->ps.min_video_vco = 0;
si->ps.max_dac1_clock = 300;
si->ps.max_dac1_clock_8 = 300;
si->ps.max_dac1_clock_16 = 300;
/* 'failsave' values */
si->ps.max_dac1_clock_24 = 270;
si->ps.max_dac1_clock_32 = 230;
si->ps.max_dac1_clock_32dh = 230;
/* secondary head */
si->ps.max_dac2_clock = 0;
si->ps.max_dac2_clock_8 = 0;
si->ps.max_dac2_clock_16 = 0;
si->ps.max_dac2_clock_24 = 0;
si->ps.max_dac2_clock_32 = 0;
/* 'failsave' values */
si->ps.max_dac2_clock_32dh = 0;
//fixme: primary & secondary_dvi should be overrule-able via nv.settings
si->ps.primary_dvi = false;
si->ps.secondary_dvi = false;
/* not used (yet) because no coldstart will be attempted (yet) */
si->ps.std_engine_clock = 125;
si->ps.std_memory_clock = 150;
}
static void pinsnv6_fake(void)
{
/* we have a standard PLL */
si->ps.ext_pll = false;
/* carefull not to take to high limits, and high should be >= 2x low. */
si->ps.max_system_vco = 300;
si->ps.min_system_vco = 128;
si->ps.max_pixel_vco = 300;
si->ps.min_pixel_vco = 128;
si->ps.max_video_vco = 0;
si->ps.min_video_vco = 0;
si->ps.max_dac1_clock = 300;
si->ps.max_dac1_clock_8 = 300;
si->ps.max_dac1_clock_16 = 300;
/* 'failsave' values */
si->ps.max_dac1_clock_24 = 270;
si->ps.max_dac1_clock_32 = 230;
si->ps.max_dac1_clock_32dh = 230;
/* secondary head */
si->ps.max_dac2_clock = 0;
si->ps.max_dac2_clock_8 = 0;
si->ps.max_dac2_clock_16 = 0;
si->ps.max_dac2_clock_24 = 0;
si->ps.max_dac2_clock_32 = 0;
/* 'failsave' values */
si->ps.max_dac2_clock_32dh = 0;
//fixme: primary & secondary_dvi should be overrule-able via nv.settings
si->ps.primary_dvi = false;
si->ps.secondary_dvi = false;
/* not used (yet) because no coldstart will be attempted (yet) */
si->ps.std_engine_clock = 100;
si->ps.std_memory_clock = 125;
}
static void pinsnv10_arch_fake(void)
{
/* we have a standard PLL */
si->ps.ext_pll = false;
/* carefull not to take to high limits, and high should be >= 2x low. */
si->ps.max_system_vco = 350;
si->ps.min_system_vco = 128;
si->ps.max_pixel_vco = 350;
si->ps.min_pixel_vco = 128;
si->ps.max_video_vco = 350;
si->ps.min_video_vco = 128;
si->ps.max_dac1_clock = 350;
si->ps.max_dac1_clock_8 = 350;
si->ps.max_dac1_clock_16 = 350;
/* 'failsave' values */
si->ps.max_dac1_clock_24 = 320;
si->ps.max_dac1_clock_32 = 280;
si->ps.max_dac1_clock_32dh = 250;
/* secondary head */
if (si->ps.card_type < NV17)
{
/* if a GeForce2 has analog VGA dualhead capability,
* it uses an external secondary DAC probably with limited capability. */
/* (called twinview technology) */
si->ps.max_dac2_clock = 200;
si->ps.max_dac2_clock_8 = 200;
si->ps.max_dac2_clock_16 = 200;
si->ps.max_dac2_clock_24 = 200;
si->ps.max_dac2_clock_32 = 200;
/* 'failsave' values */
si->ps.max_dac2_clock_32dh = 180;
}
else
{
/* GeForce4 cards have dual integrated DACs with identical capaability */
/* (called nview technology) */
si->ps.max_dac2_clock = 350;
si->ps.max_dac2_clock_8 = 350;
si->ps.max_dac2_clock_16 = 350;
/* 'failsave' values */
si->ps.max_dac2_clock_24 = 320;
si->ps.max_dac2_clock_32 = 280;
si->ps.max_dac2_clock_32dh = 250;
}
//fixme: primary & secondary_dvi should be overrule-able via nv.settings
si->ps.primary_dvi = false;
si->ps.secondary_dvi = false;
/* not used (yet) because no coldstart will be attempted (yet) */
si->ps.std_engine_clock = 120;
si->ps.std_memory_clock = 150;
}
static void pinsnv20_arch_fake(void)
{
/* we have a standard PLL */
@@ -3139,12 +2830,6 @@ static void getstrap_arch_nv10_20_30_40(void)
si->ps.secondary_head = false;
switch (si->ps.card_type)
{
case NV04:
case NV05:
case NV05M64:
case NV06:
case NV10:
case NV15:
case NV20:
break;
default:
@@ -3164,7 +2849,7 @@ static void getstrap_arch_nv10_20_30_40(void)
else
si->ps.f_ref = 13.50000;
if ((si->ps.secondary_head) && (si->ps.card_type != NV11))
if (si->ps.secondary_head)
{
if (strapinfo & 0x00400000) si->ps.f_ref = 27.00000;
}
@@ -3172,8 +2857,6 @@ static void getstrap_arch_nv10_20_30_40(void)
void dump_pins(void)
{
char *msg = "";
LOG(2,("INFO: pinsdump follows:\n"));
LOG(2,("PLL type: "));
if (si->ps.ext_pll) LOG(2,("extended\n")); else LOG(2,("standard\n"));
@@ -3200,65 +2883,6 @@ void dump_pins(void)
LOG(2,("max_dac2_clock_32dh: %dMhz\n", si->ps.max_dac2_clock_32dh));
LOG(2,("secondary_head: "));
if (si->ps.secondary_head) LOG(2,("present\n")); else LOG(2,("absent\n"));
LOG(2,("tvout: "));
if (si->ps.tvout) LOG(2,("present\n")); else LOG(2,("absent\n"));
/* setup TVout logmessage text */
switch (si->ps.tv_encoder.type)
{
case NONE:
msg = "No";
break;
case CH7003:
msg = "Chrontel CH7003";
break;
case CH7004:
msg = "Chrontel CH7004";
break;
case CH7005:
msg = "Chrontel CH7005";
break;
case CH7006:
msg = "Chrontel CH7006";
break;
case CH7007:
msg = "Chrontel CH7007";
break;
case CH7008:
msg = "Chrontel CH7008";
break;
case SAA7102:
msg = "Philips SAA7102";
break;
case SAA7103:
msg = "Philips SAA7103";
break;
case SAA7104:
msg = "Philips SAA7104";
break;
case SAA7105:
msg = "Philips SAA7105";
break;
case BT868:
msg = "Brooktree/Conexant BT868";
break;
case BT869:
msg = "Brooktree/Conexant BT869";
break;
case CX25870:
msg = "Conexant CX25870";
break;
case CX25871:
msg = "Conexant CX25871";
break;
case NVIDIA:
msg = "Nvidia internal";
break;
default:
msg = "Unknown";
break;
}
LOG(2, ("%s TV encoder detected; silicon revision is $%02x\n",
msg, si->ps.tv_encoder.version));
// LOG(2,("primary_dvi: "));
// if (si->ps.primary_dvi) LOG(2,("present\n")); else LOG(2,("absent\n"));
// LOG(2,("secondary_dvi: "));
@@ -22,7 +22,6 @@ void delay(bigtime_t i);
void nv_log(char *format, ...);
/* i2c functions */
status_t i2c_sec_tv_adapter(void);
char i2c_flag_error (char ErrNo);
void i2c_bstart (uint8 BusNR);
void i2c_bstop (uint8 BusNR);
@@ -55,13 +54,6 @@ 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);
/* Brooktree TV functions */
bool BT_probe(void);
uint8 BT_dpms(bool display);
uint8 BT_check_tvmode(display_mode target);
status_t BT_stop_tvout(void);
status_t BT_setmode(display_mode target);
/* CRTC1 functions */
status_t nv_crtc_interrupt_enable(bool);
status_t nv_crtc_update_fifo(void);
@@ -79,8 +71,6 @@ status_t nv_crtc_cursor_define(uint8*,uint8*);
status_t nv_crtc_cursor_position(uint16 x ,uint16 y);
status_t nv_crtc_cursor_show(void);
status_t nv_crtc_cursor_hide(void);
status_t nv_crtc_stop_tvout(void);
status_t nv_crtc_start_tvout(void);
/* CRTC2 functions */
status_t nv_crtc2_interrupt_enable(bool);
@@ -99,8 +89,6 @@ status_t nv_crtc2_cursor_define(uint8*,uint8*);
status_t nv_crtc2_cursor_position(uint16 x ,uint16 y);
status_t nv_crtc2_cursor_show(void);
status_t nv_crtc2_cursor_hide(void);
status_t nv_crtc2_stop_tvout(void);
status_t nv_crtc2_start_tvout(void);
/* acceleration functions */
status_t check_acc_capability(uint32 feature);
@@ -124,14 +124,12 @@ static nv_settings sSettings = { // see comments in nvidia_gpgpu.settings
/* for accelerant */
0x00000000, // logmask
0, // memory
0, // tv_output
true, // usebios
true, // hardcursor
false, // switchhead
true, // pgm_panel
false, // vga_on_tv
false, // pgm_panel
false, // force_sync
false, // force_ws
true, // force_ws
0, // gpu_clk
0, // ram_clk
};
@@ -1132,11 +1130,6 @@ init_driver(void)
if (*end == '\0')
sSettings.memory = value;
item = get_driver_parameter(settings, "tv_output", "0", "0");
value = strtoul(item, &end, 0);
if (*end == '\0')
sSettings.tv_output = value;
sSettings.hardcursor = get_driver_boolean_parameter(settings,
"hardcursor", false, false);
sSettings.usebios = get_driver_boolean_parameter(settings,
@@ -1145,8 +1138,6 @@ init_driver(void)
"switchhead", false, false);
sSettings.pgm_panel = get_driver_boolean_parameter(settings,
"pgm_panel", false, false);
sSettings.vga_on_tv = get_driver_boolean_parameter(settings,
"vga_on_tv", false, false);
sSettings.force_sync = get_driver_boolean_parameter(settings,
"force_sync", false, false);
sSettings.force_ws = get_driver_boolean_parameter(settings,
@@ -17,13 +17,11 @@ hardcursor true # if true use on-chip cursor capabilities
#logmask 0x08000604 # log overlay use in full to file (in home folder)
#logmask 0xffffffff # log everything to file (in home folder)
switchhead false # switch head assignment (dualhead cards only)
#tv_output 0 # disabled or 0 = autodetect, 1 = Y/C (and CVBS if possible), 2 = CVBS
force_sync false # if true forces 3D rendering to be synchronized to the vertical retrace
force_ws false # if true forces widescreen type detection for all connected screens
force_ws true # if true forces widescreen type detection for all connected screens
# WARNING: tweak alert! modify stuff below on your own risk...
pgm_panel true # if false don't program DVI and laptop panel pixelclocks (refreshrates)
vga_on_tv false # if true enables VGA output on the head outputting to TV
pgm_panel false # if false don't program DVI and laptop panel pixelclocks (refreshrates)
#gpu_clk 150 # in Mhz, (tries to) override default GPU clockspeed (be carefull!!!)
#ram_clk 150 # in Mhz, (tries to) override default cardRAM clockspeed (be carefull!!!)
@@ -55,7 +53,6 @@ vga_on_tv false # if true enables VGA output on the head outputting to TV
#logmask 0x00020000 # engine: crtc2
#logmask 0x00040000 # engine: crtc1
#logmask 0x00080000 # engine: acc (both PIO and DMA)
#logmask 0x00100000 # engine: brooktree tv
#logmask 0x00200000 # set displaymode
#logmask 0x00400000 # propose displaymode
#logmask 0x00800000 # init accelerant