[haiku-commits] r38363 - haiku/trunk/src/add-ons/accelerants/intel_extreme

  • From: pulkomandy@xxxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 26 Aug 2010 11:13:42 +0200 (CEST)

Author: pulkomandy
Date: 2010-08-26 11:13:41 +0200 (Thu, 26 Aug 2010)
New Revision: 38363
Changeset: http://dev.haiku-os.org/changeset/38363

Modified:
   haiku/trunk/src/add-ons/accelerants/intel_extreme/mode.cpp
Log:
Intel_extreme now centers the screen when one select a resolution smaller than 
the ne of the LVDS panel.
Also clean up the style and add some more TODOs.


Modified: haiku/trunk/src/add-ons/accelerants/intel_extreme/mode.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/intel_extreme/mode.cpp  2010-08-26 
08:42:58 UTC (rev 38362)
+++ haiku/trunk/src/add-ons/accelerants/intel_extreme/mode.cpp  2010-08-26 
09:13:41 UTC (rev 38363)
@@ -605,16 +605,17 @@
                return B_BAD_VALUE;
 
        display_mode target = *mode;
+
+       // TODO: it may be acceptable to continue when using panel fitting or
+       // centering, since the data from propose_display_mode will not 
actually be
+       // used as is in this case.
        if (intel_propose_display_mode(&target, mode, mode))
                return B_BAD_VALUE;
-               // TODO : it may be acceptable to continue when using panel 
fitting,
-               // since the data from propose_display_mode will not actually 
get any
-               // use
 
        uint32 colorMode, bytesPerRow, bitsPerPixel;
        get_color_space_format(target, colorMode, bytesPerRow, bitsPerPixel);
 
-       // TODO : do not go further if the mode is identical to the current one.
+       // TODO: do not go further if the mode is identical to the current one.
        // This would avoid the screen being off when switching workspaces when 
they
        // have the same resolution.
 
@@ -673,42 +674,45 @@
        read32(INTEL_VGA_DISPLAY_CONTROL);
 
        if ((gInfo->head_mode & HEAD_MODE_B_DIGITAL) != 0) {
-               // For LVDS panels, we actuallyalways set the native mode in 
hardware
+               // For LVDS panels, we actually always set the native mode in 
hardware
                // Then we use the panel fitter to scale the picture to that.
-               display_mode hardware_target;
-               bool needs_scaling = false;
+               display_mode hardwareTarget;
+               bool needsScaling = false;
 
+               // Try to get the panel preferred screen mode from EDID info
                if (gInfo->has_edid) {
-                       hardware_target.space = target.space;
-                       hardware_target.virtual_width
+                       hardwareTarget.space = target.space;
+                       hardwareTarget.virtual_width
                                = gInfo->edid_info.std_timing[0].h_size;
-                       hardware_target.virtual_height
+                       hardwareTarget.virtual_height
                                = gInfo->edid_info.std_timing[0].v_size;
-                       // TODO : use the info from EDID 1.2
-                       /* Each detailed_monitor has a type, find the first one 
which is
-                       * actually a detailed_timing
-                       hardware_target.virtual_width = gInfo->edid_info
-                               
.detailed_monitor[0].data.detailed_timing.h_visible;
-                       hardware_target.virtual_height = gInfo->edid_info
-                               
.detailed_monitor[0].data.detailed_timing.v_visible;
-                       */
+                       for (int i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; 
i++) {
+                               if 
(gInfo->edid_info.detailed_monitor[i].monitor_desc_type
+                                               == EDID1_IS_DETAILED_TIMING) {
+                                       hardwareTarget.virtual_width = 
gInfo->edid_info
+                                               
.detailed_monitor[i].data.detailed_timing.h_active;
+                                       hardwareTarget.virtual_height = 
gInfo->edid_info
+                                               
.detailed_monitor[i].data.detailed_timing.v_active;
+                                       break;
+                               }
+                       }
                        TRACE(("intel_extreme : hardware mode will actually be 
%dx%d\n",
-                               hardware_target.virtual_width, 
hardware_target.virtual_height));
-                       if ((hardware_target.virtual_width <= 
target.virtual_width
-                               && hardware_target.virtual_height <= 
target.virtual_height
-                               && hardware_target.space <= target.space)
-                               || intel_propose_display_mode(&hardware_target, 
mode, mode)) {
-                               hardware_target = target;
+                               hardwareTarget.virtual_width, 
hardwareTarget.virtual_height));
+                       if ((hardwareTarget.virtual_width <= 
target.virtual_width
+                               && hardwareTarget.virtual_height <= 
target.virtual_height
+                               && hardwareTarget.space <= target.space)
+                               || intel_propose_display_mode(&hardwareTarget, 
mode, mode)) {
+                               hardwareTarget = target;
                        } else
-                               needs_scaling = true;
+                               needsScaling = true;
                } else {
-                       // we don't have EDID data, try to set the requested 
mode directly
-                       hardware_target = target;
+                       // We don't have EDID data, try to set the requested 
mode directly
+                       hardwareTarget = target;
                }
 
                pll_divisors divisors;
-               if (needs_scaling)
-                       compute_pll_divisors(hardware_target, divisors, true);
+               if (needsScaling)
+                       compute_pll_divisors(hardwareTarget, divisors, true);
                else
                        compute_pll_divisors(target, divisors, true);
 
@@ -718,7 +722,7 @@
                                // DPLL mode LVDS for i915+
                }
 
-               // compute bitmask from p1 value
+               // Compute bitmask from p1 value
                dpll |= (1 << (divisors.post1 - 1)) << 
DISPLAY_PLL_POST1_DIVISOR_SHIFT;
                switch (divisors.post2) {
                        case 5:
@@ -729,6 +733,8 @@
 
                // Disable panel fitting, but enable 8 to 6-bit dithering
                write32(INTEL_PANEL_FIT_CONTROL, 0x4);
+                       // TODO: do not do this if the connected panel is 24-bit
+                       // (I don't know how to detect that)
 
                if ((dpll & DISPLAY_PLL_ENABLED) != 0) {
                        write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
@@ -746,9 +752,9 @@
                uint32 lvds = read32(INTEL_DISPLAY_LVDS_PORT)
                        | LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | 
LVDS_PIPEB_SELECT;
 
-               // TODO : do not do this if the connected panel is 24-bit
-               // (I don't know how to detect that)
                lvds |= LVDS_18BIT_DITHER;
+                       // TODO: do not do this if the connected panel is 24-bit
+                       // (I don't know how to detect that)
 
                float referenceClock = 
gInfo->shared_info->pll_info.reference_frequency
                        / 1000.0f;
@@ -781,11 +787,11 @@
                        float adjusted = ((referenceClock * divisors.m) / 
divisors.n)
                                / divisors.post;
                        uint32 pixelMultiply;
-                       if (needs_scaling) {
-                               pixelMultiply = uint32(adjusted
-                                       / (hardware_target.timing.pixel_clock / 
1000.0f));
+                       if (needsScaling) {
+                               pixelMultiply = uint32(adjusted
+                                       / (hardwareTarget.timing.pixel_clock / 
1000.0f));
                        } else {
-                               pixelMultiply = uint32(adjusted
+                               pixelMultiply = uint32(adjusted
                                        / (target.timing.pixel_clock / 
1000.0f));
                        }
 
@@ -798,39 +804,84 @@
                spin(150);
 
                // update timing parameters
-               // TODO : when harware_target != target, shift hsync and vsync 
to center
-               // the display area on the panel
-               if (needs_scaling) {
-                       write32(INTEL_DISPLAY_B_HTOTAL, 
((uint32)(hardware_target.timing.h_total - 1) << 16)
+               if (needsScaling) {
+                       // TODO: Alternatively, it should be possible to use 
the panel
+                       // fitter and scale the picture.
+
+                       // TODO: Perform some sanity check, for example if the 
target is
+                       // wider than the hardware mode we end up with negative 
borders and
+                       // broken timings
+                       uint32 borderWidth = hardwareTarget.timing.h_display
+                               - target.timing.h_display;
+
+                       uint32 syncWidth = hardwareTarget.timing.h_sync_end
+                               - hardwareTarget.timing.h_sync_start;
+
+                       uint32 syncCenter = target.timing.h_display
+                               + (hardwareTarget.timing.h_total
+                               - target.timing.h_display) / 2;
+
+                       write32(INTEL_DISPLAY_B_HTOTAL, (
+                               (uint32)(hardwareTarget.timing.h_total - 1) << 
16)
                                | ((uint32)target.timing.h_display - 1));
-                       write32(INTEL_DISPLAY_B_HBLANK, 
((uint32)(hardware_target.timing.h_total - 1) << 16)
-                               | ((uint32)target.timing.h_display - 1));
-                       write32(INTEL_DISPLAY_B_HSYNC, 
((uint32)(hardware_target.timing.h_sync_end - 1) << 16)
-                               | ((uint32)hardware_target.timing.h_sync_start 
- 1));
+                       write32(INTEL_DISPLAY_B_HBLANK, (
+                               (uint32)(hardwareTarget.timing.h_total - 
borderWidth / 2 - 1)
+                                       << 16)
+                               | ((uint32)target.timing.h_display + 
borderWidth / 2 - 1));
+                       write32(INTEL_DISPLAY_B_HSYNC, (
+                               (uint32)(syncCenter + syncWidth / 2 - 1) << 16)
+                               | ((uint32)syncCenter - syncWidth / 2 - 1));
 
-                       write32(INTEL_DISPLAY_B_VTOTAL, 
((uint32)(hardware_target.timing.v_total - 1) << 16)
+                       uint32 borderHeight = hardwareTarget.timing.v_display
+                               - target.timing.v_display;
+
+                       uint32 syncHeight = hardwareTarget.timing.v_sync_end
+                               - hardwareTarget.timing.v_sync_start;
+
+                       syncCenter = target.timing.v_display
+                               + (hardwareTarget.timing.v_total
+                               - target.timing.v_display) / 2;
+
+                       write32(INTEL_DISPLAY_B_VTOTAL, (
+                               (uint32)(hardwareTarget.timing.v_total - 1) << 
16)
                                | ((uint32)target.timing.v_display - 1));
-                       write32(INTEL_DISPLAY_B_VBLANK, 
((uint32)(hardware_target.timing.v_total - 1) << 16)
-                               | ((uint32)target.timing.v_display - 1));
-                       write32(INTEL_DISPLAY_B_VSYNC, 
((uint32)(hardware_target.timing.v_sync_end - 1) << 16)
-                               | ((uint32)hardware_target.timing.v_sync_start 
- 1));
+                       write32(INTEL_DISPLAY_B_VBLANK, (
+                               (uint32)(hardwareTarget.timing.v_total - 
borderHeight / 2 - 1)
+                                       << 16)
+                               | ((uint32)target.timing.v_display
+                                       + borderHeight / 2 - 1));
+                       write32(INTEL_DISPLAY_B_VSYNC, ((uint32)(syncCenter
+                                       + syncHeight / 2 - 1) << 16)
+                               | ((uint32)syncCenter - syncHeight / 2 - 1));
+
+                       // This is useful for debugging: it sets the border to 
red, so you
+                       // can see what is border and what is porch (black area 
around the
+                       // sync)
+                       // write32(0x61020, 0x00FF0000);
                } else {
-                       write32(INTEL_DISPLAY_B_HTOTAL, 
((uint32)(target.timing.h_total - 1) << 16)
+                       write32(INTEL_DISPLAY_B_HTOTAL, 
((uint32)(target.timing.h_total - 1)
+                                       << 16)
                                | ((uint32)target.timing.h_display - 1));
-                       write32(INTEL_DISPLAY_B_HBLANK, 
((uint32)(target.timing.h_total - 1) << 16)
+                       write32(INTEL_DISPLAY_B_HBLANK, 
((uint32)(target.timing.h_total - 1)
+                                       << 16)
                                | ((uint32)target.timing.h_display - 1));
-                       write32(INTEL_DISPLAY_B_HSYNC, 
((uint32)(target.timing.h_sync_end - 1) << 16)
+                       write32(INTEL_DISPLAY_B_HSYNC, (
+                               (uint32)(target.timing.h_sync_end - 1) << 16)
                                | ((uint32)target.timing.h_sync_start - 1));
 
-                       write32(INTEL_DISPLAY_B_VTOTAL, 
((uint32)(target.timing.v_total - 1) << 16)
+                       write32(INTEL_DISPLAY_B_VTOTAL, 
((uint32)(target.timing.v_total - 1)
+                                       << 16)
                                | ((uint32)target.timing.v_display - 1));
-                       write32(INTEL_DISPLAY_B_VBLANK, 
((uint32)(target.timing.v_total - 1) << 16)
+                       write32(INTEL_DISPLAY_B_VBLANK, 
((uint32)(target.timing.v_total - 1)
+                                       << 16)
                                | ((uint32)target.timing.v_display - 1));
-                       write32(INTEL_DISPLAY_B_VSYNC, 
((uint32)(target.timing.v_sync_end - 1) << 16)
+                       write32(INTEL_DISPLAY_B_VSYNC, (
+                               (uint32)(target.timing.v_sync_end - 1) << 16)
                                | ((uint32)target.timing.v_sync_start - 1));
                }
 
-               write32(INTEL_DISPLAY_B_IMAGE_SIZE, 
((uint32)(target.timing.h_display - 1) << 16)
+               write32(INTEL_DISPLAY_B_IMAGE_SIZE, (
+                       (uint32)(target.timing.h_display - 1) << 16)
                        | ((uint32)target.timing.v_display - 1));
 
                write32(INTEL_DISPLAY_B_POS, 0);
@@ -847,7 +898,7 @@
 
        if ((gInfo->head_mode & HEAD_MODE_A_ANALOG) != 0) {
                pll_divisors divisors;
-               compute_pll_divisors(target, divisors,false);
+               compute_pll_divisors(target, divisors, false);
 
                write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
                        (((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT) & 
DISPLAY_PLL_N_DIVISOR_MASK)


Other related posts:

  • » [haiku-commits] r38363 - haiku/trunk/src/add-ons/accelerants/intel_extreme - pulkomandy