[haiku-commits] haiku: hrev43767 - src/add-ons/accelerants/radeon_hd

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 21 Feb 2012 23:16:52 +0100 (CET)

hrev43767 adds 1 changeset to branch 'master'
old head: 9498da9c141e258af52351fe72d1b9068a2b0416
new head: 4bd6c200c1a30b78827a0f2852b8ab0995027d1a

----------------------------------------------------------------------------

4bd6c20: radeon_hd: Implement preferred mode
  
  * Add preferredMode display mode to each display.
  * If LVDS is detected, set preferredMode based on AtomBIOS
  * Fixes blocker #8329 ?

                          [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev43767
Commit:      4bd6c200c1a30b78827a0f2852b8ab0995027d1a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=4bd6c20
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Tue Feb 21 15:47:14 2012 UTC

Ticket:      https://dev.haiku-os.org/ticket/8329

----------------------------------------------------------------------------

7 files changed, 79 insertions(+), 25 deletions(-)
src/add-ons/accelerants/radeon_hd/accelerant.h     |    4 +-
.../accelerants/radeon_hd/accelerant_protos.h      |    1 +
src/add-ons/accelerants/radeon_hd/connector.cpp    |   23 ++++----
src/add-ons/accelerants/radeon_hd/connector.h      |    3 +-
src/add-ons/accelerants/radeon_hd/display.cpp      |   50 ++++++++++++---
src/add-ons/accelerants/radeon_hd/hooks.cpp        |    2 +
src/add-ons/accelerants/radeon_hd/mode.cpp         |   21 +++++++

----------------------------------------------------------------------------

diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h 
b/src/add-ons/accelerants/radeon_hd/accelerant.h
index 9e3dd51..db8e5b0 100644
--- a/src/add-ons/accelerants/radeon_hd/accelerant.h
+++ b/src/add-ons/accelerants/radeon_hd/accelerant.h
@@ -69,9 +69,6 @@ struct accelerant_info {
        struct fb_info  fb;     // used for frame buffer info within MC
 
        volatile uint32 dpms_mode;              // current driver dpms mode
-
-       // LVDS panel mode passed from the bios/startup.
-       display_mode    lvds_panel_mode;
 };
 
 
@@ -173,6 +170,7 @@ typedef struct {
        uint32                  hfreq_max;
        uint32                  hfreq_min;
        edid1_info              edid_info;
+       display_mode    preferredMode;
 } display_info;
 
 
diff --git a/src/add-ons/accelerants/radeon_hd/accelerant_protos.h 
b/src/add-ons/accelerants/radeon_hd/accelerant_protos.h
index 8731165..1f75ee3 100644
--- a/src/add-ons/accelerants/radeon_hd/accelerant_protos.h
+++ b/src/add-ons/accelerants/radeon_hd/accelerant_protos.h
@@ -32,6 +32,7 @@ uint32 radeon_accelerant_mode_count(void);
 status_t radeon_get_mode_list(display_mode* dm);
 status_t radeon_set_display_mode(display_mode* mode);
 status_t radeon_get_display_mode(display_mode* currentMode);
+status_t radeon_get_preferred_mode(display_mode* preferredMode);
 status_t radeon_get_frame_buffer_config(frame_buffer_config* config);
 status_t radeon_get_pixel_clock_limits(display_mode* mode,
        uint32* low, uint32* high);
diff --git a/src/add-ons/accelerants/radeon_hd/connector.cpp 
b/src/add-ons/accelerants/radeon_hd/connector.cpp
index 1a96239..9134526 100644
--- a/src/add-ons/accelerants/radeon_hd/connector.cpp
+++ b/src/add-ons/accelerants/radeon_hd/connector.cpp
@@ -121,16 +121,10 @@ connector_read_edid(uint32 connectorIndex, edid1_info* 
edid)
 {
        // ensure things are sane
        uint32 gpioID = gConnector[connectorIndex]->gpioID;
-       if (gGPIOInfo[gpioID]->valid == false)
+       if (gGPIOInfo[gpioID]->valid == false) {
+               ERROR("%s: invalid gpio %" B_PRIu32 " for connector %" B_PRIu32 
"\n",
+                       __func__, gpioID, connectorIndex);
                return false;
-
-       if (gConnector[connectorIndex]->type == VIDEO_CONNECTOR_LVDS) {
-               ERROR("%s: LCD panel detected (LVDS), sending VESA EDID!\n",
-                       __func__);
-               // TODO: connector_read_edid_lvds doesn't do anything yet
-               connector_read_edid_lvds(connectorIndex, edid);
-               memcpy(edid, &gInfo->shared_info->edid_info, sizeof(struct 
edid1_info));
-               return true;
        }
 
        i2c_bus bus;
@@ -155,7 +149,7 @@ connector_read_edid(uint32 connectorIndex, edid1_info* edid)
 
 
 bool
-connector_read_edid_lvds(uint32 connectorIndex, edid1_info* edid)
+connector_read_mode_lvds(uint32 connectorIndex, display_mode* mode)
 {
        uint8 dceMajor;
        uint8 dceMinor;
@@ -224,8 +218,15 @@ connector_read_edid_lvds(uint32 connectorIndex, 
edid1_info* edid)
                        timing.flags |= MODE_FLAG_DBLSCAN;
                #endif
 
-               // TODO: generate a fake EDID with information above. For now 
just dump
+               mode->timing = timing;
+               mode->h_display_start = 0;
+               mode->v_display_start = 0;
+               mode->virtual_width = timing.h_display;
+               mode->virtual_height = timing.v_display;
 
+               // Assume 32-bit color
+               mode->space = B_RGB32_LITTLE;
+               
                TRACE("%s: %" B_PRIu32 " %" B_PRIu16 " %" B_PRIu16 " %" 
B_PRIu16 " %" B_PRIu16
                        " %" B_PRIu16 " %" B_PRIu16 " %" B_PRIu16 " %" B_PRIu16 
"\n",
                        __func__, timing.pixel_clock, timing.h_display, 
timing.h_sync_start,
diff --git a/src/add-ons/accelerants/radeon_hd/connector.h 
b/src/add-ons/accelerants/radeon_hd/connector.h
index f2c7611..302cc00 100644
--- a/src/add-ons/accelerants/radeon_hd/connector.h
+++ b/src/add-ons/accelerants/radeon_hd/connector.h
@@ -63,7 +63,8 @@ const int kConnectorConvert[] = {
 status_t gpio_probe();
 status_t connector_attach_gpio(uint32 id, uint8 hwPin);
 bool connector_read_edid(uint32 connector, edid1_info* edid);
-bool connector_read_edid_lvds(uint32 connectorIndex, edid1_info* edid);
+bool connector_read_mode_lvds(uint32 connectorIndex, display_mode* mode);
+
 status_t connector_probe();
 status_t connector_probe_legacy();
 bool connector_is_dp(uint32 connectorIndex);
diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp 
b/src/add-ons/accelerants/radeon_hd/display.cpp
index 48697da..0b79026 100644
--- a/src/add-ons/accelerants/radeon_hd/display.cpp
+++ b/src/add-ons/accelerants/radeon_hd/display.cpp
@@ -256,13 +256,30 @@ detect_displays()
                if (displayIndex >= MAX_DISPLAY)
                        continue;
 
+               // TODO: As DP aux transactions don't work yet, just use LVDS 
as a hack
+               #if 0
                if (gConnector[id]->encoder.isDPBridge == true) {
-                       // if this is a DisplayPort Bridge, setup ddc on bus
+                       // If this is a DisplayPort Bridge, setup ddc on bus
+                       // TRAVIS (LVDS) or NUTMEG (VGA)
                        TRACE("%s: is bridge, performing bridge DDC setup\n", 
__func__);
-                       encoder_external_setup(id, 0, 
EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
+                       encoder_external_setup(id, 23860,
+                               EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
+               } else if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) {
+               #endif
+               if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) {
+                       // If plain (non-DP) laptop LVDS, read mode info from 
AtomBIOS
+                       //TRACE("%s: non-DP laptop LVDS detected\n", __func__);
+                       gDisplay[displayIndex]->active
+                               = connector_read_mode_lvds(id,
+                                       &gDisplay[displayIndex]->preferredMode);
                }
 
-               if (connector_read_edid(id, 
&gDisplay[displayIndex]->edid_info)) {
+               if (gDisplay[displayIndex]->active == false) {
+                       TRACE("%s: bit-banging ddc for edid on connector %" 
B_PRIu32 "\n",
+                               __func__, id);
+                       // Lets try bit-banging edid from connector
+                       gDisplay[displayIndex]->active =
+                               connector_read_edid(id, 
&gDisplay[displayIndex]->edid_info);
 
                        if (gConnector[id]->encoder.type == VIDEO_ENCODER_TVDAC
                                || gConnector[id]->encoder.type == 
VIDEO_ENCODER_DAC) {
@@ -271,23 +288,36 @@ detect_displays()
                                if (encoder_analog_load_detect(id) != true) {
                                        TRACE("%s: no analog load on EDID valid 
connector "
                                                "#%" B_PRIu32 "\n", __func__, 
id);
-                                       continue;
+                                       gDisplay[displayIndex]->active = false;
                                }
                        }
+               }
+
+               if (gDisplay[displayIndex]->active != true) {
+                       // Nothing interesting here, move along
+                       continue;
+               }
+
+               // We found a valid / active display
 
-                       gDisplay[displayIndex]->active = true;
-                       gDisplay[displayIndex]->connectorIndex = id;
-                               // set physical connector index from gConnector
+               gDisplay[displayIndex]->connectorIndex = id;
+                       // Populate physical connector index from gConnector
 
-                       init_registers(gDisplay[displayIndex]->regs, 
displayIndex);
+               init_registers(gDisplay[displayIndex]->regs, displayIndex);
 
+               if (gDisplay[displayIndex]->preferredMode.virtual_width > 0) {
+                       // Found a single preferred mode
+                       gDisplay[displayIndex]->found_ranges = false;
+               } else {
+                       // Use edid data and pull ranges
                        if (detect_crt_ranges(displayIndex) == B_OK)
                                gDisplay[displayIndex]->found_ranges = true;
-                       displayIndex++;
                }
+
+               displayIndex++;
        }
 
-       // fallback if no edid monitors were found
+       // fallback if no active monitors were found
        if (displayIndex == 0) {
                ERROR("%s: ERROR: 0 attached monitors were found on display 
connectors."
                        " Injecting first connector as a last resort.\n", 
__func__);
diff --git a/src/add-ons/accelerants/radeon_hd/hooks.cpp 
b/src/add-ons/accelerants/radeon_hd/hooks.cpp
index 645544b..d57bb73 100644
--- a/src/add-ons/accelerants/radeon_hd/hooks.cpp
+++ b/src/add-ons/accelerants/radeon_hd/hooks.cpp
@@ -48,6 +48,8 @@ get_accelerant_hook(uint32 feature, void* data)
                        return (void*)radeon_get_edid_info;
                case B_GET_MODE_LIST:
                        return (void*)radeon_get_mode_list;
+               case B_GET_PREFERRED_DISPLAY_MODE:
+                       return (void*)radeon_get_preferred_mode;
                case B_SET_DISPLAY_MODE:
                        return (void*)radeon_set_display_mode;
                case B_GET_DISPLAY_MODE:
diff --git a/src/add-ons/accelerants/radeon_hd/mode.cpp 
b/src/add-ons/accelerants/radeon_hd/mode.cpp
index 394cd28..beb2f88 100644
--- a/src/add-ons/accelerants/radeon_hd/mode.cpp
+++ b/src/add-ons/accelerants/radeon_hd/mode.cpp
@@ -85,6 +85,27 @@ radeon_get_mode_list(display_mode* modeList)
 
 
 status_t
+radeon_get_preferred_mode(display_mode* preferredMode)
+{
+       TRACE("%s\n", __func__);
+
+       // TODO: Argh!  Which display? :)
+       uint8_t crtc = 0;
+
+       if (gDisplay[crtc]->preferredMode.virtual_width > 0
+               && gDisplay[crtc]->preferredMode.virtual_height > 0) {
+               TRACE("%s: preferred mode was found for display %" B_PRIu8 "\n",
+                       __func__, crtc);
+               memcpy(preferredMode, &gDisplay[crtc]->preferredMode,
+                       sizeof(gDisplay[crtc]->preferredMode));
+               return B_OK;
+       }
+
+       return B_ERROR;
+}
+
+
+status_t
 radeon_get_edid_info(void* info, size_t size, uint32* edid_version)
 {
        // TODO: multi-monitor?  for now we use VESA edid


Other related posts:

  • » [haiku-commits] haiku: hrev43767 - src/add-ons/accelerants/radeon_hd - kallisti5