* vesa_set_mode() now gets another parameter that specifies whether or not

the mode timing should be used.
* Apparently, some VBE3 implementations don't implement the CRTC support, and
  they seem to fail when the SET_MODE_SPECIFY_CRTC bit is set.
* Therefore, we'll first try with timing, and if that fails, we'll try again
  without it. This should bring back the boot screen for all those who had
  problems with it before.
* Added tracing output of the CRTC to be used.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28398 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-10-31 13:14:07 +00:00
parent 3a39905b59
commit 39c7faa460
1 changed files with 19 additions and 6 deletions

View File

@ -153,6 +153,10 @@ closest_video_mode(int32 width, int32 height, int32 depth)
static crtc_info_block* static crtc_info_block*
get_crtc_info_block(edid1_detailed_timing& timing) get_crtc_info_block(edid1_detailed_timing& timing)
{ {
// This feature is only available on chipsets supporting VBE3 and up
if (sInfo.version.major < 3)
return NULL;
// Copy timing structure to set the mode with // Copy timing structure to set the mode with
crtc_info_block* crtcInfo = (crtc_info_block*)malloc( crtc_info_block* crtcInfo = (crtc_info_block*)malloc(
sizeof(crtc_info_block)); sizeof(crtc_info_block));
@ -173,6 +177,12 @@ get_crtc_info_block(edid1_detailed_timing& timing)
/ (crtcInfo->horizontal_total / 10) / (crtcInfo->horizontal_total / 10)
/ (crtcInfo->vertical_total / 10); / (crtcInfo->vertical_total / 10);
TRACE(("crtc: h %u/%u/%u, v %u/%u/%u, pixel clock %lu, refresh %u\n",
crtcInfo->horizontal_sync_start, crtcInfo->horizontal_sync_end,
crtcInfo->horizontal_total, crtcInfo->vertical_sync_start,
crtcInfo->vertical_sync_end, crtcInfo->vertical_total,
crtcInfo->pixel_clock, crtcInfo->refresh_rate));
crtcInfo->flags = 0; crtcInfo->flags = 0;
if (timing.sync == 3) { if (timing.sync == 3) {
// TODO: this switches the default sync when sync != 3 (compared to // TODO: this switches the default sync when sync != 3 (compared to
@ -534,13 +544,13 @@ vesa_get_mode(uint16 *_mode)
static status_t static status_t
vesa_set_mode(video_mode* mode) vesa_set_mode(video_mode* mode, bool useTiming)
{ {
struct bios_regs regs; struct bios_regs regs;
regs.eax = 0x4f02; regs.eax = 0x4f02;
regs.ebx = (mode->mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; regs.ebx = (mode->mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
if (mode->timing != NULL) { if (useTiming && mode->timing != NULL) {
regs.ebx |= SET_MODE_SPECIFY_CRTC; regs.ebx |= SET_MODE_SPECIFY_CRTC;
regs.es = ADDRESS_SEGMENT(mode->timing); regs.es = ADDRESS_SEGMENT(mode->timing);
regs.edi = ADDRESS_OFFSET(mode->timing); regs.edi = ADDRESS_OFFSET(mode->timing);
@ -969,11 +979,14 @@ platform_switch_to_logo(void)
if (!sModeChosen) if (!sModeChosen)
get_mode_from_settings(); get_mode_from_settings();
// On some BIOS / chipset / monitor combinations, there seems to be a timing issue between // On some BIOS / chipset / monitor combinations, there seems to be a
// getting the EDID data and setting the video mode. As such we wait here briefly to give // timing issue between getting the EDID data and setting the video
// everything enough time to settle. // mode. As such we wait here briefly to give everything enough time
// to settle.
spin(1000); spin(1000);
if (vesa_set_mode(sMode) != B_OK)
if ((sMode->timing == NULL || vesa_set_mode(sMode, true) != B_OK)
&& vesa_set_mode(sMode, false) != B_OK)
goto fallback; goto fallback;
struct vbe_mode_info modeInfo; struct vbe_mode_info modeInfo;