added support for haiku specific driverhook GET_PREFERRED_DISPLAY_MODE. Now laptops and other systems where EDID fails but a screen is digitally connected should also come up in their native modes from first system boot on.Updated docs. Bumped version to 0.97. +alphabranch
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32765 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1c2a5ae241
commit
42529205ad
@ -65,6 +65,7 @@ void * get_accelerant_hook(uint32 feature, void *data)
|
||||
HOOK(GET_DISPLAY_MODE);
|
||||
#ifdef __HAIKU__
|
||||
HOOK(GET_EDID_INFO);
|
||||
HOOK(GET_PREFERRED_DISPLAY_MODE);
|
||||
#endif
|
||||
HOOK(GET_FRAME_BUFFER_CONFIG);
|
||||
HOOK(GET_PIXEL_CLOCK_LIMITS);
|
||||
|
@ -26,9 +26,10 @@ status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info * adi)
|
||||
|
||||
#ifdef __HAIKU__
|
||||
|
||||
/* Get the info fetched from the attached screen */
|
||||
status_t GET_EDID_INFO(void* info, size_t size, uint32* _version)
|
||||
{
|
||||
if ((!si->ps.crtc1_screen.have_full_edid) && (!si->ps.crtc2_screen.have_full_edid)) {
|
||||
if (!si->ps.crtc1_screen.have_full_edid && !si->ps.crtc2_screen.have_full_edid) {
|
||||
LOG(4,("GET_EDID_INFO: EDID info not available\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
@ -40,28 +41,31 @@ status_t GET_EDID_INFO(void* info, size_t size, uint32* _version)
|
||||
LOG(4,("GET_EDID_INFO: returning info\n"));
|
||||
|
||||
/* if we have two screens, make the best of it (go for the best compatible info) */
|
||||
if ((si->ps.crtc1_screen.have_full_edid) && (si->ps.crtc2_screen.have_full_edid)) {
|
||||
/* return info on screen with lowest aspect (4:3 takes precedence over ws) */
|
||||
if (si->ps.crtc1_screen.aspect < si->ps.crtc2_screen.aspect)
|
||||
if (si->ps.crtc1_screen.have_full_edid && si->ps.crtc2_screen.have_full_edid) {
|
||||
/* return info on screen with lowest aspect (4:3 takes precedence over ws)
|
||||
* NOTE:
|
||||
* allow 0.10 difference so 4:3 and 5:4 aspect screens are regarded as being the same. */
|
||||
if (si->ps.crtc1_screen.aspect < (si->ps.crtc2_screen.aspect - 0.10)) {
|
||||
memcpy(info, &si->ps.crtc1_screen.full_edid, sizeof(struct edid1_info));
|
||||
if (si->ps.crtc1_screen.aspect > si->ps.crtc2_screen.aspect)
|
||||
memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
|
||||
|
||||
/* if both screens have the same aspect, return info on the one with
|
||||
* the lowest native resolution */
|
||||
if (si->ps.crtc1_screen.aspect == si->ps.crtc2_screen.aspect) {
|
||||
if ((si->ps.crtc1_screen.timing.h_display) < (si->ps.crtc2_screen.timing.h_display))
|
||||
memcpy(info, &si->ps.crtc1_screen.full_edid, sizeof(struct edid1_info));
|
||||
if ((si->ps.crtc1_screen.timing.h_display) > (si->ps.crtc2_screen.timing.h_display))
|
||||
} else {
|
||||
if (si->ps.crtc1_screen.aspect > (si->ps.crtc2_screen.aspect + 0.10)) {
|
||||
memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
|
||||
|
||||
/* if both screens have the same resolution and aspect, return info on the
|
||||
* one used as main screen */
|
||||
if ((si->ps.crtc1_screen.timing.h_display) == (si->ps.crtc2_screen.timing.h_display)) {
|
||||
if (si->ps.crtc2_prim)
|
||||
memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
|
||||
else
|
||||
} else {
|
||||
/* both screens have the same aspect, return info on the one with
|
||||
* the lowest native resolution */
|
||||
if (si->ps.crtc1_screen.timing.h_display < si->ps.crtc2_screen.timing.h_display)
|
||||
memcpy(info, &si->ps.crtc1_screen.full_edid, sizeof(struct edid1_info));
|
||||
if (si->ps.crtc1_screen.timing.h_display > si->ps.crtc2_screen.timing.h_display)
|
||||
memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
|
||||
|
||||
/* if both screens have the same resolution and aspect, return info on the
|
||||
* one used as main screen */
|
||||
if (si->ps.crtc1_screen.timing.h_display == si->ps.crtc2_screen.timing.h_display) {
|
||||
if (si->ps.crtc2_prim)
|
||||
memcpy(info, &si->ps.crtc2_screen.full_edid, sizeof(struct edid1_info));
|
||||
else
|
||||
memcpy(info, &si->ps.crtc1_screen.full_edid, sizeof(struct edid1_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -76,4 +80,60 @@ status_t GET_EDID_INFO(void* info, size_t size, uint32* _version)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/* Return the optimum (native) mode for the attached screen */
|
||||
status_t GET_PREFERRED_DISPLAY_MODE(display_mode* preferredMode)
|
||||
{
|
||||
if (si->ps.crtc1_screen.have_full_edid || si->ps.crtc2_screen.have_full_edid) {
|
||||
LOG(4,("GET_PREFERRED_DISPLAY_MODE: full EDID known, aborting (fetch EDID instead).\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (!si->ps.crtc1_screen.have_native_edid && !si->ps.crtc2_screen.have_native_edid) {
|
||||
LOG(4,("GET_PREFERRED_DISPLAY_MODE: native mode(s) not known\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
/* if we got here then we're probably on a laptop, but DDC/EDID may have failed
|
||||
* for another reason as well. */
|
||||
LOG(4,("GET_PREFERRED_DISPLAY_MODE: returning mode\n"));
|
||||
|
||||
/* if we have two screens, make the best of it (go for the best compatible mode) */
|
||||
if (si->ps.crtc1_screen.have_native_edid && si->ps.crtc2_screen.have_native_edid) {
|
||||
/* return mode of screen with lowest aspect (4:3 takes precedence over ws)
|
||||
* NOTE:
|
||||
* allow 0.10 difference so 4:3 and 5:4 aspect screens are regarded as being the same. */
|
||||
if (si->ps.crtc1_screen.aspect < (si->ps.crtc2_screen.aspect - 0.10)) {
|
||||
get_crtc1_screen_native_mode(preferredMode);
|
||||
} else {
|
||||
if (si->ps.crtc1_screen.aspect > (si->ps.crtc2_screen.aspect + 0.10)) {
|
||||
get_crtc2_screen_native_mode(preferredMode);
|
||||
} else {
|
||||
/* both screens have the same aspect, return mode of the one with
|
||||
* the lowest native resolution */
|
||||
if (si->ps.crtc1_screen.timing.h_display < si->ps.crtc2_screen.timing.h_display)
|
||||
get_crtc1_screen_native_mode(preferredMode);
|
||||
if (si->ps.crtc1_screen.timing.h_display > si->ps.crtc2_screen.timing.h_display)
|
||||
get_crtc2_screen_native_mode(preferredMode);
|
||||
|
||||
/* if both screens have the same resolution and aspect, return mode of the
|
||||
* one used as main screen */
|
||||
if (si->ps.crtc1_screen.timing.h_display == si->ps.crtc2_screen.timing.h_display) {
|
||||
if (si->ps.crtc2_prim)
|
||||
get_crtc2_screen_native_mode(preferredMode);
|
||||
else
|
||||
get_crtc1_screen_native_mode(preferredMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* there's just one screen of which we have native mode information, return it's mode */
|
||||
if (si->ps.crtc1_screen.have_native_edid)
|
||||
get_crtc1_screen_native_mode(preferredMode);
|
||||
else
|
||||
get_crtc2_screen_native_mode(preferredMode);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
#endif // __HAIKU__
|
||||
|
@ -163,14 +163,14 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
|
||||
case CRTC1_TMDS: /* digital panel on head 1, nothing on head 2 */
|
||||
case CRTC1_VGA: /* analog connected screen on head 1, nothing on head 2 */
|
||||
if (si->ps.crtc1_screen.aspect < (target_aspect - 0.10)) {
|
||||
LOG(4, ("PROPOSEMODE: screen at crtc1 is not widescreen type, aborted.\n"));
|
||||
LOG(4, ("PROPOSEMODE: screen at crtc1 is not widescreen (enough) type, aborted.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
break;
|
||||
case CRTC2_TMDS: /* nothing on head 1, digital panel on head 2 */
|
||||
case CRTC2_VGA: /* analog connected screen on head 2, nothing on head 1 */
|
||||
if (si->ps.crtc2_screen.aspect < (target_aspect - 0.10)) {
|
||||
LOG(4, ("PROPOSEMODE: screen at crtc2 is not widescreen type, aborted.\n"));
|
||||
LOG(4, ("PROPOSEMODE: screen at crtc2 is not widescreen (enough) type, aborted.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
break;
|
||||
@ -181,7 +181,7 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
|
||||
default: /* more than two screens connected (illegal setup) */
|
||||
if ((si->ps.crtc1_screen.aspect < (target_aspect - 0.10)) ||
|
||||
(si->ps.crtc2_screen.aspect < (target_aspect - 0.10))) {
|
||||
LOG(4, ("PROPOSEMODE: not all connected screens are widescreen type, aborted.\n"));
|
||||
LOG(4, ("PROPOSEMODE: not all connected screens are widescreen (enough) type, aborted.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
break;
|
||||
|
@ -28,6 +28,7 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set);
|
||||
status_t GET_DISPLAY_MODE(display_mode *current_mode);
|
||||
#ifdef __HAIKU__
|
||||
status_t GET_EDID_INFO(void* info, size_t size, uint32* _version);
|
||||
status_t GET_PREFERRED_DISPLAY_MODE(display_mode* preferredMode);
|
||||
#endif
|
||||
status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *a_frame_buffer);
|
||||
status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high);
|
||||
|
@ -92,7 +92,7 @@ status_t nv_general_powerup()
|
||||
{
|
||||
status_t status;
|
||||
|
||||
LOG(1,("POWERUP: Haiku nVidia Accelerant 0.96 running.\n"));
|
||||
LOG(1,("POWERUP: Haiku nVidia Accelerant 0.97 running.\n"));
|
||||
|
||||
/* log VBLANK INT usability status */
|
||||
if (si->ps.int_assigned)
|
||||
|
@ -2897,39 +2897,34 @@ static void setup_output_matrix()
|
||||
}
|
||||
}
|
||||
|
||||
void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2)
|
||||
status_t get_crtc1_screen_native_mode(display_mode *mode)
|
||||
{
|
||||
if (si->ps.monitors & CRTC1_TMDS)
|
||||
{
|
||||
/* timing ('modeline') */
|
||||
p1->timing = si->ps.p1_timing;
|
||||
/* setup the rest */
|
||||
p1->space = B_CMAP8;
|
||||
p1->virtual_width = p1->timing.h_display;
|
||||
p1->virtual_height = p1->timing.v_display;
|
||||
p1->h_display_start = 0;
|
||||
p1->v_display_start = 0;
|
||||
p1->flags = 0;
|
||||
*pan1 = true;
|
||||
}
|
||||
else
|
||||
*pan1 = false;
|
||||
if (!si->ps.crtc1_screen.have_native_edid) return B_ERROR;
|
||||
|
||||
if (si->ps.monitors & CRTC2_TMDS)
|
||||
{
|
||||
/* timing ('modeline') */
|
||||
p2->timing = si->ps.p2_timing;
|
||||
/* setup the rest */
|
||||
p2->space = B_CMAP8;
|
||||
p2->virtual_width = p2->timing.h_display;
|
||||
p2->virtual_height = p2->timing.v_display;
|
||||
p2->h_display_start = 0;
|
||||
p2->v_display_start = 0;
|
||||
p2->flags = 0;
|
||||
*pan2 = true;
|
||||
}
|
||||
else
|
||||
*pan2 = false;
|
||||
mode->space = B_RGB32_LITTLE;
|
||||
mode->virtual_width = si->ps.crtc1_screen.timing.h_display;
|
||||
mode->virtual_height = si->ps.crtc1_screen.timing.v_display;
|
||||
mode->h_display_start = 0;
|
||||
mode->v_display_start = 0;
|
||||
mode->flags = 0;
|
||||
memcpy(&mode->timing, &si->ps.crtc1_screen.timing, sizeof(mode->timing));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t get_crtc2_screen_native_mode(display_mode *mode)
|
||||
{
|
||||
if (!si->ps.crtc2_screen.have_native_edid) return B_ERROR;
|
||||
|
||||
mode->space = B_RGB32_LITTLE;
|
||||
mode->virtual_width = si->ps.crtc2_screen.timing.h_display;
|
||||
mode->virtual_height = si->ps.crtc2_screen.timing.v_display;
|
||||
mode->h_display_start = 0;
|
||||
mode->v_display_start = 0;
|
||||
mode->flags = 0;
|
||||
memcpy(&mode->timing, &si->ps.crtc2_screen.timing, sizeof(mode->timing));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
static void pinsnv4_fake(void)
|
||||
|
@ -42,6 +42,8 @@ status_t parse_pins(void);
|
||||
void set_pll(uint32 reg, uint32 clk);
|
||||
void get_panel_modes(display_mode *p1, display_mode *p2, bool *pan1, bool *pan2);
|
||||
void fake_panel_start(void);
|
||||
status_t get_crtc1_screen_native_mode(display_mode *mode);
|
||||
status_t get_crtc2_screen_native_mode(display_mode *mode);
|
||||
void set_specs(void);
|
||||
void dump_pins(void);
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<p><h2>Changes done for each driverversion:</h2></p>
|
||||
<p><h1>head (SVN 0.96, Rudolf)</h1></p>
|
||||
<p><h1>head (SVN 0.97, Rudolf)</h1></p>
|
||||
<ul>
|
||||
<li>Fixed driver assuming enabling AGP mode succeeded on some occasions if it did not block it itself. Blocking AGP mode completely via the AGP busmanager (option 'block_agp') resulted in a crashing acceleration engine because it was setup for AGP transfers instead of using PCI transfers. Error was solved with help from user kraton.
|
||||
<li>Fixed shared_info struct problem occuring when 3D 'accelerant' is used (tested Alpha 4.1): the TVencoder type definition list apparantly gets some memory assigned these days when done inside the definition of shared_info. Moved encoder list outside the shared_info definition.
|
||||
@ -23,7 +23,8 @@
|
||||
<li>Fixed acceleration engine crashes on at least G72 cards (Geforce 7300/7400/7500) by powering up new part(s) of the acceleration engines too..
|
||||
<li>Modified GPU PTimer programming which according to the Nouveau project fixes LVDS panel programming in some cases.
|
||||
<li>Corrected/Added detection of third I2C bus on cards that support it. The old detection method for a third and (non-existing) fourth bus was faulty. The driver uses I2C channels for monitor DDC/EDID and TVencoder communications.
|
||||
<li>DDC/EDID fetching now also works on GCC4 binaries due to a fixed fault in the accelerants/common code (which is used for that function).
|
||||
<li>DDC/EDID fetching now also works on GCC4 binaries due to a fixed fault in the accelerants/common code (which is used for that function);
|
||||
<li>Added support for Haiku specific driverhook GET_PREFERRED_DISPLAY_MODE. Laptops should now also startup in native mode automatically at first system boot.
|
||||
</ul>
|
||||
<p><h1>nv_driver 0.80 (Rudolf)</h1></p>
|
||||
<ul>
|
||||
@ -253,7 +254,7 @@ The features below are shutdown because they are possibly dangerous without feed
|
||||
<p><h1>Still todo:</h1></p>
|
||||
<ul>
|
||||
<li>Extend TVout feature to support more encoder-types (Chrontel, Philips);
|
||||
<li>Improve/extend various stuff when/if possible (like extending the use of DDC/EDID).
|
||||
<li>Improve/extend various stuff when/if possible.
|
||||
</ul>
|
||||
</p>
|
||||
</body>
|
||||
|
Loading…
Reference in New Issue
Block a user