[haiku-commits] haiku: hrev53690 - src/add-ons/accelerants/intel_extreme headers/private/graphics/intel_extreme

  • From: Adrien Destugues <pulkomandy@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 5 Jan 2020 04:11:48 -0500 (EST)

hrev53690 adds 2 changesets to branch 'master'
old head: d927a11fff2eb3c2e7c7a09285d10979963f5d7c
new head: 2beddbfd468bc8c048e10fd100eedf5dcb61a10d
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=2beddbfd468b+%5Ed927a11fff2e

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

abcbfac60164: intel_extreme: use the panel fitter for generation 4 devices
  
  LVDS panels must really be driven at their native resolution, otherwise
  they will simply not work. This means we should basically never touch
  the video timings on that side. We need to only set the source size in
  the pipe configuration, and let the panel fitter figure out the scaling.
  
  On my G45 laptop, this allows me to use non-native resolutions on the
  laptop display. This also means when booting with a VGA display
  connected, I do get a valid display on the internal panel (using the VGA
  resolution). VGA still gets "out of range", so we're still not setting
  up something there.
  
  If I switch to VGA display in the BIOS, I get a working picture there
  and garbage on the internal display, which is progress (before I would
  get a black screen on the internal display)
  
  Fixes #12723.

2beddbfd468b: intel_extreme: fix pipe and plane size registers
  
  - The name for the registers were swapped
  - The width and height were also swapped in one of them
  - Remove some old #if 0 code that touched these registers but has been
    disabled for a while.

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

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

5 files changed, 90 insertions(+), 307 deletions(-)
.../graphics/intel_extreme/intel_extreme.h       |  14 +-
src/add-ons/accelerants/intel_extreme/Pipes.cpp  |  34 ++--
src/add-ons/accelerants/intel_extreme/Pipes.h    |   3 +-
src/add-ons/accelerants/intel_extreme/Ports.cpp  | 187 +++++++------------
src/add-ons/accelerants/intel_extreme/mode.cpp   | 159 ----------------

############################################################################

Commit:      abcbfac60164b52730388689344a72f049086285
URL:         https://git.haiku-os.org/haiku/commit/?id=abcbfac60164
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Sat Jan  4 19:44:48 2020 UTC

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

intel_extreme: use the panel fitter for generation 4 devices

LVDS panels must really be driven at their native resolution, otherwise
they will simply not work. This means we should basically never touch
the video timings on that side. We need to only set the source size in
the pipe configuration, and let the panel fitter figure out the scaling.

On my G45 laptop, this allows me to use non-native resolutions on the
laptop display. This also means when booting with a VGA display
connected, I do get a valid display on the internal panel (using the VGA
resolution). VGA still gets "out of range", so we're still not setting
up something there.

If I switch to VGA display in the BIOS, I get a working picture there
and garbage on the internal display, which is progress (before I would
get a black screen on the internal display)

Fixes #12723.

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

diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h 
b/headers/private/graphics/intel_extreme/intel_extreme.h
index 450db724d8..4a1d9ef59b 100644
--- a/headers/private/graphics/intel_extreme/intel_extreme.h
+++ b/headers/private/graphics/intel_extreme/intel_extreme.h
@@ -993,7 +993,11 @@ struct intel_free_graphics_memory {
 #define PCH_PANEL_FITTER_H_SCALE               0x90
 
 #define PANEL_FITTER_ENABLED                   (1 << 31)
-#define PANEL_FITTER_FILTER_MASK               (3 << 23)
+#define PANEL_FITTER_PIPE_MASK                 (3 << 29)
+#define PANEL_FITTER_PIPE_A                            (0 << 29)
+#define PANEL_FITTER_PIPE_B                            (1 << 29)
+#define PANEL_FITTER_SCALING_MODE_MASK (7 << 26)
+#define PANEL_FITTER_FILTER_MASK               (3 << 24)
 
 struct overlay_scale {
        uint32 _reserved0 : 3;
diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp 
b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
index 285415d1d5..92c5ee9963 100644
--- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
@@ -171,7 +171,7 @@ Pipe::_ConfigureTranscoder(display_mode* target)
 
 
 void
-Pipe::ConfigureTimings(display_mode* target)
+Pipe::ConfigureTimings(display_mode* target, bool hardware)
 {
        CALLED();
 
@@ -185,7 +185,7 @@ Pipe::ConfigureTimings(display_mode* target)
        /* If there is a transcoder, leave the display at its native resolution,
         * and configure only the transcoder (panel fitting will match them
         * together). */
-       if (!fHasTranscoder)
+       if (!fHasTranscoder && hardware)
        {
                // update timing (fPipeOffset bumps the DISPLAY_A to B when 
needed)
                write32(INTEL_DISPLAY_A_HTOTAL + fPipeOffset,
diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.h 
b/src/add-ons/accelerants/intel_extreme/Pipes.h
index c8cb5f4c36..596d21e626 100644
--- a/src/add-ons/accelerants/intel_extreme/Pipes.h
+++ b/src/add-ons/accelerants/intel_extreme/Pipes.h
@@ -39,7 +39,8 @@ public:
                void                                            Disable();
 
                void                                            
Configure(display_mode* mode);
-               void                                            
ConfigureTimings(display_mode* mode);
+               void                                            
ConfigureTimings(display_mode* mode,
+                                                                               
bool hardware = true);
                void                                            ConfigureClocks(
                                                                                
const pll_divisors& divisors,
                                                                                
uint32 pixelClock,
diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp 
b/src/add-ons/accelerants/intel_extreme/Ports.cpp
index 89452fef11..5e5daf2257 100644
--- a/src/add-ons/accelerants/intel_extreme/Ports.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp
@@ -468,12 +468,18 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 
colorMode)
                panelStatus = PCH_PANEL_STATUS;
        }
 
-       // Power off Panel
-       write32(panelControl, read32(panelControl) & 
~PANEL_CONTROL_POWER_TARGET_ON);
-       read32(panelControl);
-
-       if (!wait_for_clear(panelStatus, PANEL_STATUS_POWER_ON, 1000))
-               ERROR("%s: %s didn't power off within 1000ms!\n", __func__, 
PortName());
+       if (gInfo->shared_info->device_type.Generation() != 4) {
+               // TODO not needed on any generation if we are using the panel 
fitter
+               // Power off Panel
+               write32(panelControl,
+                       read32(panelControl) & ~PANEL_CONTROL_POWER_TARGET_ON);
+               read32(panelControl);
+
+               if (!wait_for_clear(panelStatus, PANEL_STATUS_POWER_ON, 1000)) {
+                       ERROR("%s: %s didn't power off within 1000ms!\n", 
__func__,
+                               PortName());
+               }
+       }
 
 #if 0
        // Disabled for now as our code doesn't work. Let's hope VESA/EFI has
@@ -484,52 +490,40 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 
colorMode)
                link->Train(target);
 #endif
 
-#if 0
-       // Disable PanelFitter for now
-       addr_t panelFitterControl = PCH_PANEL_FITTER_BASE_REGISTER
-               + PCH_PANEL_FITTER_CONTROL;
-       if (fPipe->Index() == INTEL_PIPE_B)
-               panelFitterControl += PCH_PANEL_FITTER_PIPE_OFFSET;
-       write32(panelFitterControl, (read32(panelFitterControl) & 
~PANEL_FITTER_ENABLED));
-       read32(panelFitterControl);
-#endif
-
        // 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 hardwareTarget;
        bool needsScaling = false;
-               // Try to get the panel preferred screen mode from EDID info
 
-#if 0
-       if (gInfo->shared_info->got_vbt) {
+       // TODO needed for the other generations as well, in some way?
+       if (gInfo->shared_info->device_type.Generation() == 4
+                       && gInfo->shared_info->got_vbt) {
                // Set vbios hardware panel mode as base
                memcpy(&hardwareTarget, &gInfo->shared_info->panel_mode,
                        sizeof(display_mode));
-               hardwareTarget.space = target->space;
 
-               if ((hardwareTarget.virtual_width <= target->virtual_width
-                               && hardwareTarget.virtual_height <= 
target->virtual_height
-                               && hardwareTarget.space <= target->space)
-                       || intel_propose_display_mode(&hardwareTarget, target, 
target)) {
+               if (hardwareTarget.virtual_width == target->virtual_width
+                               && hardwareTarget.virtual_height == 
target->virtual_height) {
+                       // We are setting the native video mode, nothing 
special to do
                        hardwareTarget = *target;
-               } else
-                       needsScaling = true;
+               } else {
+                       // We need to enable the panel fitter
+                       TRACE("%s: hardware mode will actually be %dx%d\n", 
__func__,
+                               hardwareTarget.virtual_width, 
hardwareTarget.virtual_height);
 
-               TRACE("%s: hardware mode will actually be %dx%d (%s)\n", 
__func__,
-                       hardwareTarget.virtual_width, 
hardwareTarget.virtual_height,
-                       needsScaling ? "scaled" : "unscaled");
+                       hardwareTarget.space = target->space;
+                       // FIXME we should also get the refresh frequency from 
the target
+                       // mode, and then "sanitize" the resulting mode we made 
up.
+
+                       needsScaling = true;
+               }
        } else {
-#endif
-       {
-               // We don't have EDID data, try to set the requested mode 
directly
+               // We don't have VBT data, try to set the requested mode 
directly
                hardwareTarget = *target;
        }
 
        pll_divisors divisors;
-       if (needsScaling)
-               compute_pll_divisors(&hardwareTarget, &divisors, true);
-       else
-               compute_pll_divisors(target, &divisors, true);
+       compute_pll_divisors(&hardwareTarget, &divisors, true);
 
        uint32 lvds = read32(_PortRegister())
                | LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
@@ -583,103 +577,50 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 
colorMode)
        // Program general pipe config
        fPipe->Configure(target);
 
-       // Program pipe PLL's (pixel_clock is *always* the hardware pixel clock)
+       // Program pipe PLL's (using the hardware mode timings, since that's 
what
+       // the PLL is used for)
        fPipe->ConfigureClocks(divisors, hardwareTarget.timing.pixel_clock,
                extraPLLFlags);
 
-       // 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)
-
-       // Power on Panel
-       write32(panelControl, read32(panelControl) | 
PANEL_CONTROL_POWER_TARGET_ON);
-       read32(panelControl);
+       if (gInfo->shared_info->device_type.Generation() != 4) {
+               // G45: no need to power the panel off
+               // Power on Panel
+               write32(panelControl,
+                       read32(panelControl) | PANEL_CONTROL_POWER_TARGET_ON);
+               read32(panelControl);
 
-       if (!wait_for_set(panelStatus, PANEL_STATUS_POWER_ON, 1000))
-               ERROR("%s: %s didn't power on within 1000ms!\n", __func__, 
PortName());
+               if (!wait_for_set(panelStatus, PANEL_STATUS_POWER_ON, 1000)) {
+                       ERROR("%s: %s didn't power on within 1000ms!\n", 
__func__,
+                               PortName());
+               }
+       }
 
        // Program target display mode
-       fPipe->ConfigureTimings(target);
+       fPipe->ConfigureTimings(target, false);
 
-#if 0
-       // update timing parameters
        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)(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));
-
-               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)(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);
+               // Enable panel fitter in automatic mode. It will figure out
+               // the scaling ratios automatically.
+               uint32 panelFitterControl = read32(INTEL_PANEL_FIT_CONTROL);
+               panelFitterControl |= PANEL_FITTER_ENABLED;
+               panelFitterControl &= ~(PANEL_FITTER_SCALING_MODE_MASK
+                       | PANEL_FITTER_PIPE_MASK);
+               panelFitterControl |= PANEL_FITTER_PIPE_B;
+                       // LVDS is always on pipe B.
+               write32(INTEL_PANEL_FIT_CONTROL, panelFitterControl);
        } else {
-               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)
-                       | ((uint32)target->timing.h_display - 1));
-               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)
-                       | ((uint32)target->timing.v_display - 1));
-               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)
-                       | ((uint32)target->timing.v_sync_start - 1));
+               if (gInfo->shared_info->device_type.Generation() == 4) {
+                       // Bypass the panel fitter
+                       uint32 panelFitterControl = 
read32(INTEL_PANEL_FIT_CONTROL);
+                       panelFitterControl &= ~PANEL_FITTER_ENABLED;
+                       write32(INTEL_PANEL_FIT_CONTROL, panelFitterControl);
+               } else {
+                       // 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)
+               }
        }
-#endif
 
        // Set fCurrentMode to our set display mode
        memcpy(&fCurrentMode, target, sizeof(display_mode));

############################################################################

Revision:    hrev53690
Commit:      2beddbfd468bc8c048e10fd100eedf5dcb61a10d
URL:         https://git.haiku-os.org/haiku/commit/?id=2beddbfd468b
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Sat Jan  4 20:08:10 2020 UTC

intel_extreme: fix pipe and plane size registers

- The name for the registers were swapped
- The width and height were also swapped in one of them
- Remove some old #if 0 code that touched these registers but has been
  disabled for a while.

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

diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h 
b/headers/private/graphics/intel_extreme/intel_extreme.h
index 4a1d9ef59b..1982d9b390 100644
--- a/headers/private/graphics/intel_extreme/intel_extreme.h
+++ b/headers/private/graphics/intel_extreme/intel_extreme.h
@@ -549,8 +549,8 @@ struct intel_free_graphics_memory {
 #define INTEL_DISPLAY_B_VBLANK                 (0x1010 | 
REGS_NORTH_PIPE_AND_PORT)
 #define INTEL_DISPLAY_B_VSYNC                  (0x1014 | 
REGS_NORTH_PIPE_AND_PORT)
 
-#define INTEL_DISPLAY_A_IMAGE_SIZE             (0x001c | 
REGS_NORTH_PIPE_AND_PORT)
-#define INTEL_DISPLAY_B_IMAGE_SIZE             (0x101c | 
REGS_NORTH_PIPE_AND_PORT)
+#define INTEL_DISPLAY_A_PIPE_SIZE              (0x001c | 
REGS_NORTH_PIPE_AND_PORT)
+#define INTEL_DISPLAY_B_PIPE_SIZE              (0x101c | 
REGS_NORTH_PIPE_AND_PORT)
 
 // Cougar Point transcoder pipe selection
 #define  PORT_TRANS_A_SEL_CPT                  0
@@ -668,7 +668,7 @@ struct intel_free_graphics_memory {
 #define INTEL_DISPLAY_A_BYTES_PER_ROW  (0x0188 | REGS_NORTH_PLANE_CONTROL)
 #define INTEL_DISPLAY_A_POS                            (0x018c | 
REGS_NORTH_PLANE_CONTROL)
        // reserved on A
-#define INTEL_DISPLAY_A_PIPE_SIZE              (0x0190 | 
REGS_NORTH_PLANE_CONTROL)
+#define INTEL_DISPLAY_A_IMAGE_SIZE             (0x0190 | 
REGS_NORTH_PLANE_CONTROL)
 #define INTEL_DISPLAY_A_SURFACE                        (0x019c | 
REGS_NORTH_PLANE_CONTROL)
        // i965 and up only
 
@@ -676,7 +676,7 @@ struct intel_free_graphics_memory {
 #define INTEL_DISPLAY_B_BASE                   (0x1184 | 
REGS_NORTH_PLANE_CONTROL)
 #define INTEL_DISPLAY_B_BYTES_PER_ROW  (0x1188 | REGS_NORTH_PLANE_CONTROL)
 #define INTEL_DISPLAY_B_POS                            (0x118c | 
REGS_NORTH_PLANE_CONTROL)
-#define INTEL_DISPLAY_B_PIPE_SIZE              (0x1190 | 
REGS_NORTH_PLANE_CONTROL)
+#define INTEL_DISPLAY_B_IMAGE_SIZE             (0x1190 | 
REGS_NORTH_PLANE_CONTROL)
 #define INTEL_DISPLAY_B_SURFACE                        (0x119c | 
REGS_NORTH_PLANE_CONTROL)
        // i965 and up only
 
diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp 
b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
index 92c5ee9963..200d435ecb 100644
--- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
@@ -209,26 +209,22 @@ Pipe::ConfigureTimings(display_mode* target, bool 
hardware)
                        | ((uint32)target->timing.v_sync_start - 1));
        }
 
-       // XXX: Is it ok to do these on non-digital?
-
-       write32(INTEL_DISPLAY_A_POS + fPipeOffset, 0);
+       write32(INTEL_DISPLAY_A_PIPE_SIZE + fPipeOffset,
+               ((uint32)(target->timing.h_display - 1) << 16)
+                       | ((uint32)target->timing.v_display - 1));
 
-       // Set the image size for both pipes, just in case.
-       write32(INTEL_DISPLAY_A_IMAGE_SIZE,
-               ((uint32)(target->virtual_width - 1) << 16)
+       // Set the plane size as well while we're at it (this is independant, we
+       // could have a larger plane and scroll through it).
+       if (gInfo->shared_info->device_type.Generation() > 4) {
+               // This is "reserved" on G45 and below.
+               write32(INTEL_DISPLAY_A_IMAGE_SIZE + fPipeOffset,
+                       ((uint32)(target->virtual_width - 1) << 16)
                        | ((uint32)target->virtual_height - 1));
-       write32(INTEL_DISPLAY_B_IMAGE_SIZE,
-               ((uint32)(target->virtual_width - 1) << 16)
-                       | ((uint32)target->virtual_height - 1));
-
-       write32(INTEL_DISPLAY_A_PIPE_SIZE + fPipeOffset,
-               ((uint32)(target->timing.v_display - 1) << 16)
-                       | ((uint32)target->timing.h_display - 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(INTEL_DISPLAY_A_RED + fPipeOffset, 0x00FF0000);
+       // Since we set the plane to be the same size as the display, we can 
just
+       // show it starting at top-left.
+       write32(INTEL_DISPLAY_A_POS + fPipeOffset, 0);
 
        if (fHasTranscoder)
                _ConfigureTranscoder(target);
diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp 
b/src/add-ons/accelerants/intel_extreme/mode.cpp
index 1e7072102b..24bce5c5a7 100644
--- a/src/add-ons/accelerants/intel_extreme/mode.cpp
+++ b/src/add-ons/accelerants/intel_extreme/mode.cpp
@@ -40,165 +40,6 @@
 #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)
-{
-       uint32 pll = read32(pllRegister);
-       uint32 pllDivisor;
-       uint32 hTotalRegister;
-       uint32 vTotalRegister;
-       uint32 hSyncRegister;
-       uint32 vSyncRegister;
-       uint32 imageSizeRegister;
-       uint32 controlRegister;
-
-       if (pllRegister == INTEL_DISPLAY_A_PLL) {
-               pllDivisor = read32((pll & DISPLAY_PLL_DIVISOR_1) != 0
-                       ? INTEL_DISPLAY_A_PLL_DIVISOR_1 : 
INTEL_DISPLAY_A_PLL_DIVISOR_0);
-
-               hTotalRegister = INTEL_DISPLAY_A_HTOTAL;
-               vTotalRegister = INTEL_DISPLAY_A_VTOTAL;
-               hSyncRegister = INTEL_DISPLAY_A_HSYNC;
-               vSyncRegister = INTEL_DISPLAY_A_VSYNC;
-               imageSizeRegister = INTEL_DISPLAY_A_IMAGE_SIZE;
-               controlRegister = INTEL_DISPLAY_A_CONTROL;
-       } else if (pllRegister == INTEL_DISPLAY_B_PLL) {
-               pllDivisor = read32((pll & DISPLAY_PLL_DIVISOR_1) != 0
-                       ? INTEL_DISPLAY_B_PLL_DIVISOR_1 : 
INTEL_DISPLAY_B_PLL_DIVISOR_0);
-
-               hTotalRegister = INTEL_DISPLAY_B_HTOTAL;
-               vTotalRegister = INTEL_DISPLAY_B_VTOTAL;
-               hSyncRegister = INTEL_DISPLAY_B_HSYNC;
-               vSyncRegister = INTEL_DISPLAY_B_VSYNC;
-               imageSizeRegister = INTEL_DISPLAY_B_IMAGE_SIZE;
-               controlRegister = INTEL_DISPLAY_B_CONTROL;
-       } else {
-               ERROR("%s: PLL not supported\n", __func__);
-               return;
-       }
-
-       pll_divisors divisors;
-       if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
-               divisors.m1 = 0;
-               divisors.m2 = (pllDivisor & DISPLAY_PLL_IGD_M2_DIVISOR_MASK)
-                       >> DISPLAY_PLL_M2_DIVISOR_SHIFT;
-               divisors.n = ((pllDivisor & DISPLAY_PLL_IGD_N_DIVISOR_MASK)
-                       >> DISPLAY_PLL_N_DIVISOR_SHIFT) - 1;
-       } else {
-               divisors.m1 = (pllDivisor & DISPLAY_PLL_M1_DIVISOR_MASK)
-                       >> DISPLAY_PLL_M1_DIVISOR_SHIFT;
-               divisors.m2 = (pllDivisor & DISPLAY_PLL_M2_DIVISOR_MASK)
-                       >> DISPLAY_PLL_M2_DIVISOR_SHIFT;
-               divisors.n = (pllDivisor & DISPLAY_PLL_N_DIVISOR_MASK)
-                       >> DISPLAY_PLL_N_DIVISOR_SHIFT;
-       }
-
-       pll_limits limits;
-       get_pll_limits(&limits, false);
-               // TODO: Detect LVDS connector vs assume no
-
-       if (gInfo->shared_info->device_type.Generation() >= 3) {
-
-               if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
-                       divisors.post1 = (pll & 
DISPLAY_PLL_IGD_POST1_DIVISOR_MASK)
-                               >> DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT;
-               } else {
-                       divisors.post1 = (pll & 
DISPLAY_PLL_9xx_POST1_DIVISOR_MASK)
-                               >> DISPLAY_PLL_POST1_DIVISOR_SHIFT;
-               }
-
-               if (pllRegister == INTEL_DISPLAY_B_PLL
-                       && 
!gInfo->shared_info->device_type.InGroup(INTEL_GROUP_96x)) {
-                       // TODO: Fix this? Need to support dual channel LVDS.
-                       divisors.post2 = LVDS_POST2_RATE_SLOW;
-               } else {
-                       if ((pll & DISPLAY_PLL_DIVIDE_HIGH) != 0)
-                               divisors.post2 = limits.max.post2;
-                       else
-                               divisors.post2 = limits.min.post2;
-               }
-       } else {
-               // 8xx
-               divisors.post1 = (pll & DISPLAY_PLL_POST1_DIVISOR_MASK)
-                       >> DISPLAY_PLL_POST1_DIVISOR_SHIFT;
-
-               if ((pll & DISPLAY_PLL_DIVIDE_4X) != 0)
-                       divisors.post2 = limits.max.post2;
-               else
-                       divisors.post2 = limits.min.post2;
-       }
-
-       divisors.m = 5 * divisors.m1 + divisors.m2;
-       divisors.post = divisors.post1 * divisors.post2;
-
-       float referenceClock
-               = gInfo->shared_info->pll_info.reference_frequency / 1000.0f;
-       float pixelClock
-               = ((referenceClock * divisors.m) / divisors.n) / divisors.post;
-
-       // timing
-
-       mode.timing.pixel_clock = uint32(pixelClock * 1000);
-       mode.timing.flags = 0;
-
-       uint32 value = read32(hTotalRegister);
-       mode.timing.h_total = (value >> 16) + 1;
-       mode.timing.h_display = (value & 0xffff) + 1;
-
-       value = read32(hSyncRegister);
-       mode.timing.h_sync_end = (value >> 16) + 1;
-       mode.timing.h_sync_start = (value & 0xffff) + 1;
-
-       value = read32(vTotalRegister);
-       mode.timing.v_total = (value >> 16) + 1;
-       mode.timing.v_display = (value & 0xffff) + 1;
-
-       value = read32(vSyncRegister);
-       mode.timing.v_sync_end = (value >> 16) + 1;
-       mode.timing.v_sync_start = (value & 0xffff) + 1;
-
-       // image size and color space
-
-       value = read32(imageSizeRegister);
-       mode.virtual_width = (value >> 16) + 1;
-       mode.virtual_height = (value & 0xffff) + 1;
-
-       // using virtual size based on image size is the 'proper' way to do it,
-       // however the bios appears to be suggesting scaling or somesuch, so 
ignore
-       // the proper virtual dimension for now if they'd suggest a smaller 
size.
-       if (mode.virtual_width < mode.timing.h_display)
-               mode.virtual_width = mode.timing.h_display;
-       if (mode.virtual_height < mode.timing.v_display)
-               mode.virtual_height = mode.timing.v_display;
-
-       value = read32(controlRegister);
-       switch (value & DISPLAY_CONTROL_COLOR_MASK) {
-               case DISPLAY_CONTROL_RGB32:
-               default:
-                       mode.space = B_RGB32;
-                       break;
-               case DISPLAY_CONTROL_RGB16:
-                       mode.space = B_RGB16;
-                       break;
-               case DISPLAY_CONTROL_RGB15:
-                       mode.space = B_RGB15;
-                       break;
-               case DISPLAY_CONTROL_CMAP8:
-                       mode.space = B_CMAP8;
-                       break;
-       }
-
-       mode.h_display_start = 0;
-       mode.v_display_start = 0;
-       mode.flags = B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS
-               | B_DPMS | B_SUPPORTS_OVERLAYS;
-}
-#endif
-
-
 static void
 get_color_space_format(const display_mode &mode, uint32 &colorMode,
        uint32 &bytesPerRow, uint32 &bitsPerPixel)


Other related posts:

  • » [haiku-commits] haiku: hrev53690 - src/add-ons/accelerants/intel_extreme headers/private/graphics/intel_extreme - Adrien Destugues