diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index b6a8de615b..b7203807ad 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -213,12 +213,12 @@ struct intel_shared_info { area_id mode_list_area; // area containing display mode list uint32 mode_count; - display_mode current_mode; + display_mode panel_mode; // VBIOS VBT panel mode uint32 bytes_per_row; uint32 bits_per_pixel; uint32 dpms_mode; - area_id registers_area; // area of memory mapped registers + area_id registers_area; // area of memory mapped registers uint32 register_blocks[REGISTER_BLOCK_COUNT]; uint8* status_page; diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index be3c1448d2..c52a7c4888 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -963,8 +963,24 @@ EmbeddedDisplayPort::EmbeddedDisplayPort() bool EmbeddedDisplayPort::IsConnected() { - if (!gInfo->shared_info->device_type.IsMobile()) - return false; + addr_t portRegister = _PortRegister(); - return DisplayPort::IsConnected(); + TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(), + portRegister); + + if (!gInfo->shared_info->device_type.IsMobile()) { + TRACE("%s: skipping eDP on non-mobile GPU\n", __func__); + return false; + } + + if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0) { + TRACE("%s: %s link not detected\n", __func__, PortName()); + return false; + } + + HasEDID(); + + // If eDP has EDID, awesome. We use it. + // No EDID? The modesetting code falls back to VBIOS panel_mode + return true; } diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.h b/src/add-ons/accelerants/intel_extreme/accelerant.h index cda9523c87..0b34dda2f1 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.h +++ b/src/add-ons/accelerants/intel_extreme/accelerant.h @@ -40,6 +40,8 @@ struct accelerant_info { intel_shared_info* shared_info; area_id shared_info_area; + display_mode current_mode; // pretty much a hack until per-display modes + display_mode* mode_list; // cloned list of standard display modes area_id mode_list_area; @@ -68,9 +70,6 @@ struct accelerant_info { int device; uint8 head_mode; bool is_clone; - - // LVDS panel mode passed from the bios/startup. - display_mode lvds_panel_mode; }; @@ -114,7 +113,6 @@ extern void setup_ring_buffer(ring_buffer &ringBuffer, const char* name); // modes.cpp extern void wait_for_vblank(void); extern void set_frame_buffer_base(void); -extern void save_lvds_mode(void); extern status_t create_mode_list(void); // memory.cpp diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 7bb68f66e6..2438e99b38 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -40,6 +40,9 @@ #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__) +#if 0 +// This hack needs to die. Leaving in for a little while +// incase we *really* need it. static void retrieve_current_mode(display_mode& mode, uint32 pllRegister) { @@ -193,6 +196,7 @@ retrieve_current_mode(display_mode& mode, uint32 pllRegister) mode.flags = B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS | B_DPMS | B_SUPPORTS_OVERLAYS; } +#endif static void @@ -274,7 +278,8 @@ void set_frame_buffer_base() { intel_shared_info &sharedInfo = *gInfo->shared_info; - display_mode &mode = sharedInfo.current_mode; + display_mode &mode = gInfo->current_mode; + uint32 baseRegister; uint32 surfaceRegister; @@ -320,30 +325,29 @@ create_mode_list(void) gInfo->has_edid = true; } - if (!gInfo->has_edid) { + // If no EDID, but have vbt from driver, use that mode + if (!gInfo->has_edid && gInfo->shared_info->got_vbt) { // We could not read any EDID info. Fallback to creating a list with // only the mode set up by the BIOS. + // TODO: support lower modes via scaling and windowing - if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0 - && (gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0) { - size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1) - & ~(B_PAGE_SIZE - 1); + size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1) + & ~(B_PAGE_SIZE - 1); - display_mode* list; - area_id area = create_area("intel extreme modes", - (void**)&list, B_ANY_ADDRESS, size, B_NO_LOCK, - B_READ_AREA | B_WRITE_AREA); - if (area < 0) - return area; + display_mode* list; + area_id area = create_area("intel extreme modes", + (void**)&list, B_ANY_ADDRESS, size, B_NO_LOCK, + B_READ_AREA | B_WRITE_AREA); + if (area < 0) + return area; - memcpy(list, &gInfo->lvds_panel_mode, sizeof(display_mode)); + memcpy(list, &gInfo->shared_info->panel_mode, sizeof(display_mode)); - gInfo->mode_list_area = area; - gInfo->mode_list = list; - gInfo->shared_info->mode_list_area = gInfo->mode_list_area; - gInfo->shared_info->mode_count = 1; - return B_OK; - } + gInfo->mode_list_area = area; + gInfo->mode_list = list; + gInfo->shared_info->mode_list_area = gInfo->mode_list_area; + gInfo->shared_info->mode_count = 1; + return B_OK; } // Otherwise return the 'real' list of modes @@ -373,24 +377,6 @@ wait_for_vblank(void) } -/*! Store away panel information if identified on startup - (used for pipe B->lvds). -*/ -void -save_lvds_mode(void) -{ - // dump currently programmed mode. - display_mode biosMode; - retrieve_current_mode(biosMode, INTEL_DISPLAY_B_PLL); - - sanitize_display_mode(biosMode); - // The BIOS mode may not be a valid mode, as LVDS output does not - // really care about the sync values - - gInfo->lvds_panel_mode = biosMode; -} - - // #pragma mark - @@ -488,7 +474,7 @@ intel_set_display_mode(display_mode* mode) base) < B_OK) { // oh, how did that happen? Unfortunately, there is no really good way // back - if (intel_allocate_memory(sharedInfo.current_mode.virtual_height + if (intel_allocate_memory(gInfo->current_mode.virtual_height * sharedInfo.bytes_per_row, 0, base) == B_OK) { sharedInfo.frame_buffer = base; sharedInfo.frame_buffer_offset = base @@ -618,8 +604,10 @@ intel_set_display_mode(display_mode* mode) write32(INTEL_DISPLAY_B_BYTES_PER_ROW, bytesPerRow); // update shared info + gInfo->current_mode = target; + + // TODO: move to gInfo sharedInfo.bytes_per_row = bytesPerRow; - sharedInfo.current_mode = target; sharedInfo.bits_per_pixel = bitsPerPixel; set_frame_buffer_base(); @@ -637,7 +625,7 @@ intel_get_display_mode(display_mode* _currentMode) { CALLED(); - *_currentMode = gInfo->shared_info->current_mode; + *_currentMode = gInfo->current_mode; // This seems unreliable. We should always know the current_mode //retrieve_current_mode(*_currentMode, INTEL_DISPLAY_A_PLL); @@ -710,7 +698,7 @@ intel_move_display(uint16 horizontalStart, uint16 verticalStart) intel_shared_info &sharedInfo = *gInfo->shared_info; Autolock locker(sharedInfo.accelerant_lock); - display_mode &mode = sharedInfo.current_mode; + display_mode &mode = gInfo->current_mode; if (horizontalStart + mode.timing.h_display > mode.virtual_width || verticalStart + mode.timing.v_display > mode.virtual_height) diff --git a/src/add-ons/accelerants/intel_extreme/overlay.cpp b/src/add-ons/accelerants/intel_extreme/overlay.cpp index afa7ef752d..2ad5c4c94f 100644 --- a/src/add-ons/accelerants/intel_extreme/overlay.cpp +++ b/src/add-ons/accelerants/intel_extreme/overlay.cpp @@ -207,7 +207,7 @@ set_color_key(uint8 red, uint8 green, uint8 blue, uint8 redMask, static void set_color_key(const overlay_window* window) { - switch (gInfo->shared_info->current_mode.space) { + switch (gInfo->current_mode.space) { case B_CMAP8: set_color_key(0, 0, window->blue.value, 0x0, 0x0, 0xff); break; @@ -589,10 +589,10 @@ intel_configure_overlay(overlay_token overlayToken, left = 0; if (top < 0) top = 0; - if (right > gInfo->shared_info->current_mode.timing.h_display) - right = gInfo->shared_info->current_mode.timing.h_display; - if (bottom > gInfo->shared_info->current_mode.timing.v_display) - bottom = gInfo->shared_info->current_mode.timing.v_display; + if (right > gInfo->current_mode.timing.h_display) + right = gInfo->current_mode.timing.h_display; + if (bottom > gInfo->current_mode.timing.v_display) + bottom = gInfo->current_mode.timing.v_display; if (left >= right || top >= bottom) { // overlay is not within visible bounds hide_overlay(); diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/bios.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/bios.cpp index 1c23bd8a6b..ecd6f36ae2 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/bios.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/bios.cpp @@ -119,8 +119,6 @@ static struct vbios { } vbios; -/* TODO: move code to accelerant, if possible */ - /*! This is reimplementation, Haiku uses BIOS call and gets most current panel info, we're, otherwise, digging in VBIOS memory and parsing VBT tables to get native panel timings. This will allow to get non-updated, diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index bf1d5c70f0..f9af40e1f3 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -405,8 +405,10 @@ intel_extreme_init(intel_info &info) info.shared_info->frame_buffer = 0; info.shared_info->dpms_mode = B_DPMS_ON; + // Pull VBIOS panel mode for later use info.shared_info->got_vbt = get_lvds_mode_from_bios( - &info.shared_info->current_mode); + &info.shared_info->panel_mode); + /* at least 855gm can't drive more than one head at time */ if (info.device_type.InFamily(INTEL_FAMILY_8xx)) info.shared_info->single_head_locked = 1; diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme_private.h b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme_private.h index 45d6b2f9ae..0632c57bc9 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme_private.h +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme_private.h @@ -70,7 +70,7 @@ find_reg(const intel_info& info, uint32 target) } -extern bool get_lvds_mode_from_bios(display_mode *shared_info); +extern bool get_lvds_mode_from_bios(display_mode *mode); extern status_t intel_free_memory(intel_info& info, addr_t offset); extern status_t intel_allocate_memory(intel_info& info, size_t size, size_t alignment, uint32 flags, addr_t* _offset,