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:
Rudolf Cornelissen 2009-08-27 20:26:31 +00:00
parent 1c2a5ae241
commit 42529205ad
8 changed files with 118 additions and 58 deletions

View File

@ -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);

View File

@ -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__

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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>