added/rewrote TVout enabling/disabling routines: moved CRTC specific stuff to the respective files. Driver now has support for TVout head switching, although it's not completed yet (switch mode will likely mess up as that's not taken into account yet :). On singlehead cards TVout is on the one and only head, on dualhead cards TVout defaults to the secondary head (use dualhead setupthere ). Tested OK on NV11 in dualhead clone and stretch mode.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14545 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -195,6 +195,10 @@ status_t INIT_ACCELERANT(int the_fd) {
|
||||
/* ensure DPMS state */
|
||||
si->dpms_flags = B_DPMS_ON;
|
||||
|
||||
/* ensure TVout state */
|
||||
//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. */
|
||||
|
||||
@@ -1578,47 +1578,28 @@ static status_t BT_update_mode_for_gpu(display_mode *target, uint8 tvmode)
|
||||
* tested on ELSA Erazor III 32Mb AGP (TNT2/BT869),
|
||||
* Diamond Viper V550 16Mb PCI (TNT1/BT869),
|
||||
* and ASUS V7100 GeForce2 MX200 AGP/32Mb (CH7007). */
|
||||
static status_t BT_start_tvout(void)
|
||||
static status_t BT_start_tvout(display_mode tv_target)
|
||||
{
|
||||
/* enable access to primary head */
|
||||
set_crtc_owner(0);
|
||||
if (!si->ps.secondary_head || (tv_target.flags & TV_PRIMARY))
|
||||
{
|
||||
if (si->ps.secondary_head)
|
||||
{
|
||||
/* switch TV encoder to CRTC1 */
|
||||
NV_REG32(NV32_2FUNCSEL) &= ~0x00000100;
|
||||
NV_REG32(NV32_FUNCSEL) |= 0x00000100;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
nv_crtc_start_tvout();
|
||||
}
|
||||
|
||||
/* 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));
|
||||
if (si->ps.secondary_head && !(tv_target.flags & TV_PRIMARY))
|
||||
{
|
||||
/* switch TV encoder to CRTC2 */
|
||||
NV_REG32(NV32_FUNCSEL) &= ~0x00000100;
|
||||
NV_REG32(NV32_2FUNCSEL) |= 0x00000100;
|
||||
|
||||
/* 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)
|
||||
//fixme: assuming TVout is on crtc1!!
|
||||
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);
|
||||
nv_crtc2_start_tvout();
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}//end BT_start_tvout.
|
||||
@@ -1632,57 +1613,11 @@ status_t BT_stop_tvout(void)
|
||||
/* prevent BT from being overclocked by VGA-only modes & black-out TV-out */
|
||||
BT_killclk_blackout();
|
||||
|
||||
/* enable access to primary head */
|
||||
set_crtc_owner(0);
|
||||
if (!si->ps.secondary_head || (si->dm.flags & TV_PRIMARY))
|
||||
nv_crtc_stop_tvout();
|
||||
|
||||
/* 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 */
|
||||
while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
|
||||
/* wait for next vertical retrace start on VGA */
|
||||
while (!(NV_REG8(NV8_INSTAT1) & 0x08)) snooze(1);
|
||||
/* now wait until we are 'in' active VGA picture again */
|
||||
while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
|
||||
|
||||
|
||||
/* 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));
|
||||
if (si->ps.secondary_head && !(si->dm.flags & TV_PRIMARY))
|
||||
nv_crtc2_stop_tvout();
|
||||
|
||||
/* fixme if needed:
|
||||
* a full encoder chip reset could be done here (so after decoupling crtc)... */
|
||||
@@ -1773,7 +1708,11 @@ status_t BT_setmode(display_mode target)
|
||||
BT_update_mode_for_gpu(&tv_target, tvmode);
|
||||
|
||||
/* setup GPU CRTC timing */
|
||||
head1_set_timing(tv_target);
|
||||
if (!si->ps.secondary_head || (si->dm.flags & TV_PRIMARY))
|
||||
head1_set_timing(tv_target);
|
||||
|
||||
if (si->ps.secondary_head && !(si->dm.flags & TV_PRIMARY))
|
||||
head2_set_timing(tv_target);
|
||||
|
||||
//fixme: only testing older cards for now...
|
||||
if (si->ps.secondary_head && (si->ps.card_type > NV15))
|
||||
@@ -1783,7 +1722,7 @@ if (si->ps.secondary_head && (si->ps.card_type > NV15))
|
||||
}
|
||||
|
||||
/* now set GPU CRTC to slave mode */
|
||||
BT_start_tvout();
|
||||
BT_start_tvout(tv_target);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -914,3 +914,104 @@ status_t nv_crtc_cursor_position(uint16 x, uint16 y)
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t nv_crtc_stop_tvout(void)
|
||||
{
|
||||
/* 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 */
|
||||
while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
|
||||
/* wait for next vertical retrace start on VGA */
|
||||
while (!(NV_REG8(NV8_INSTAT1) & 0x08)) snooze(1);
|
||||
/* now wait until we are 'in' active VGA picture again */
|
||||
while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -764,3 +764,98 @@ status_t nv_crtc2_cursor_position(uint16 x, uint16 y)
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t nv_crtc2_stop_tvout(void)
|
||||
{
|
||||
/* 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 */
|
||||
while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
|
||||
/* wait for next vertical retrace start on VGA */
|
||||
while (!(NV_REG8(NV8_INSTAT1) & 0x08)) snooze(1);
|
||||
/* now wait until we are 'in' active VGA picture again */
|
||||
while (NV_REG8(NV8_INSTAT1) & 0x08) snooze(1);
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ status_t nv_general_powerup()
|
||||
{
|
||||
status_t status;
|
||||
|
||||
LOG(1,("POWERUP: Haiku nVidia Accelerant 0.59 running.\n"));
|
||||
LOG(1,("POWERUP: Haiku nVidia Accelerant 0.60 running.\n"));
|
||||
|
||||
/* log VBLANK INT usability status */
|
||||
if (si->ps.int_assigned)
|
||||
@@ -1270,15 +1270,15 @@ static status_t nv_general_bios_to_powergraphics()
|
||||
|
||||
if (si->ps.secondary_head)
|
||||
{
|
||||
/* switch overlay engine to CRTC1 */
|
||||
/* switch overlay engine and TV encoder to CRTC1 */
|
||||
/* bit 17: GPU FP port #1 (confirmed NV25, NV28, confirmed not on NV34),
|
||||
* bit 16: GPU FP port #2 (confirmed NV25, NV28, NV34),
|
||||
* bit 12: overlay engine (all cards),
|
||||
* bit 9: TVout chip #2 (confirmed on NV18, NV25, NV28),
|
||||
* bit 8: TVout chip #1 (all cards),
|
||||
* bit 4: both I2C busses (all cards) */
|
||||
NV_REG32(NV32_2FUNCSEL) &= ~0x00001000;
|
||||
NV_REG32(NV32_FUNCSEL) |= 0x00001000;
|
||||
NV_REG32(NV32_2FUNCSEL) &= ~0x00001100;
|
||||
NV_REG32(NV32_FUNCSEL) |= 0x00001100;
|
||||
}
|
||||
si->overlay.crtc = false;
|
||||
|
||||
|
||||
@@ -81,6 +81,8 @@ 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_validate_timing(
|
||||
@@ -97,6 +99,8 @@ 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);
|
||||
|
||||
Reference in New Issue
Block a user