[haiku-commits] haiku: hrev50303 - src/add-ons/accelerants/intel_extreme

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 11 May 2016 20:10:18 +0200 (CEST)

hrev50303 adds 2 changesets to branch 'master'
old head: 95e38537e0e9a86f28e4c39aed6df55e4fb55fd1
new head: a32e8156730975d66634c655655fdf68b56660fc
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=a32e81567309+%5E95e38537e0e9

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

9407ab29c429: intel_extreme: Rework PLL calculation
  
  * More like linux, improved G4x calculations
  * Reduce un-needed pll limit complexity
  * Improved pll limits on ports based on type

a32e81567309: intel_extreme: Shorten graphics family names

                          [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]

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

5 files changed, 331 insertions(+), 171 deletions(-)
src/add-ons/accelerants/intel_extreme/Pipes.cpp  |  19 +-
src/add-ons/accelerants/intel_extreme/Ports.cpp  |   2 +-
.../accelerants/intel_extreme/accelerant.cpp     |  18 +-
src/add-ons/accelerants/intel_extreme/pll.cpp    | 453 +++++++++++++------
src/add-ons/accelerants/intel_extreme/pll.h      |  10 +-

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

Commit:      9407ab29c4297af831ac9e6b80768af10fe8a5f4
URL:         http://cgit.haiku-os.org/haiku/commit/?id=9407ab29c429
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Tue May 10 04:12:03 2016 UTC

intel_extreme: Rework PLL calculation

* More like linux, improved G4x calculations
* Reduce un-needed pll limit complexity
* Improved pll limits on ports based on type

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

diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp 
b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
index 8f272e7..2848d0a 100644
--- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
@@ -239,7 +239,7 @@ Pipe::ConfigureClocks(const pll_divisors& divisors, uint32 
pixelClock,
        float refFreq = gInfo->shared_info->pll_info.reference_frequency / 
1000.0f;
 
        if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_96x)) {
-               float adjusted = ((refFreq * divisors.m) / divisors.n)  / 
divisors.post;
+               float adjusted = ((refFreq * divisors.m) / divisors.n)  / 
divisors.p;
                uint32 pixelMultiply = uint32(adjusted  / (pixelClock / 
1000.0f));
                write32(pllMD, (0 << 24) | ((pixelMultiply - 1) << 8));
        }
@@ -273,34 +273,33 @@ Pipe::ConfigureClocks(const pll_divisors& divisors, 
uint32 pixelClock,
        uint32 pll = DISPLAY_PLL_ENABLED | DISPLAY_PLL_NO_VGA_CONTROL | 
extraFlags;
 
        if (gInfo->shared_info->device_type.Generation() >= 3) {
-               // post1 divisor << 1 , 1-8
+               // p1 divisor << 1 , 1-8
                if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
-                       pll |= ((1 << (divisors.post1 - 1))
+                       pll |= ((1 << (divisors.p1 - 1))
                                        << DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT)
                                & DISPLAY_PLL_IGD_POST1_DIVISOR_MASK;
                } else {
-                       pll |= ((1 << (divisors.post1 - 1))
+                       pll |= ((1 << (divisors.p1 - 1))
                                        << DISPLAY_PLL_POST1_DIVISOR_SHIFT)
                                & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
-               //      pll |= ((divisors.post1 - 1) << 
DISPLAY_PLL_POST1_DIVISOR_SHIFT)
+               //      pll |= ((divisors.p1 - 1) << 
DISPLAY_PLL_POST1_DIVISOR_SHIFT)
                //              & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
                }
 
-               // p2 clock divider. 5 or 7 high
-               if (divisors.post2_high)
+               if (divisors.p2 == 5 || divisors.p2 == 7)
                        pll |= DISPLAY_PLL_DIVIDE_HIGH;
 
                if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_96x))
                        pll |= 6 << DISPLAY_PLL_PULSE_PHASE_SHIFT;
        } else {
-               if (!divisors.post2_high)
+               if (divisors.p2 != 5 && divisors.p2 != 7)
                        pll |= DISPLAY_PLL_DIVIDE_4X;
 
                pll |= DISPLAY_PLL_2X_CLOCK;
 
                // TODO: Is this supposed to be 
DISPLAY_PLL_IGD_POST1_DIVISOR_MASK??
-               if (divisors.post1 > 2) {
-                       pll |= ((divisors.post1 - 2) << 
DISPLAY_PLL_POST1_DIVISOR_SHIFT)
+               if (divisors.p1 > 2) {
+                       pll |= ((divisors.p1 - 2) << 
DISPLAY_PLL_POST1_DIVISOR_SHIFT)
                                & DISPLAY_PLL_POST1_DIVISOR_MASK;
                } else
                        pll |= DISPLAY_PLL_POST1_DIVIDE_2;
diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp 
b/src/add-ons/accelerants/intel_extreme/Ports.cpp
index 7b91200..14e707d 100644
--- a/src/add-ons/accelerants/intel_extreme/Ports.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp
@@ -506,7 +506,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 
colorMode)
 
        // Set the B0-B3 data pairs corresponding to whether we're going to
        // set the DPLLs for dual-channel mode or not.
-       if (divisors.post2_high) {
+       if (divisors.p2 == 5 || divisors.p2 == 7) {
                TRACE("LVDS: dual channel\n");
                lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
        } else {
diff --git a/src/add-ons/accelerants/intel_extreme/pll.cpp 
b/src/add-ons/accelerants/intel_extreme/pll.cpp
index f6126d7..826bcb0 100644
--- a/src/add-ons/accelerants/intel_extreme/pll.cpp
+++ b/src/add-ons/accelerants/intel_extreme/pll.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2016, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -38,117 +38,146 @@
 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
 
 
-void
-get_pll_limits(pll_limits* limits, bool isLVDS)
+// Static pll limits taken from Linux kernel KMS
+
+static pll_limits kLimitsIlkDac = {
+       // p, p1, p2, n,   m, m1, m2
+       {  5,  2, 14, 1,  79, 12,  5}, // min
+       { 80,  8, 14, 3, 118, 22,  9}, // max
+       225000, 1760000, 3510000
+};
+
+static pll_limits kLimitsIlkLvdsSingle = {
+       // p, p1, p2, n,   m, m1, m2
+       { 28,  2, 14, 1,  79, 12,  5}, // min
+       {112,  8, 14, 3, 118, 22,  9}, // max
+       225000, 1760000, 3510000
+};
+
+static pll_limits kLimitsIlkLvdsDual = {
+       // p, p1, p2, n,   m, m1, m2
+       { 14,  2,  7, 1,  79, 12,  5}, // min
+       { 56,  8,  7, 3, 127, 22,  9}, // max
+       225000, 1760000, 3510000
+};
+
+// 100Mhz RefClock
+static pll_limits kLimitsIlkLvdsSingle100 = {
+       // p, p1, p2, n,   m, m1, m2
+       { 28,  2, 14, 1,  79, 12,  5}, // min
+       {112,  8, 14, 2, 126, 22,  9}, // max
+       225000, 1760000, 3510000
+};
+
+static pll_limits kLimitsIlkLvdsDual100 = {
+       // p, p1, p2, n,   m, m1, m2
+       { 14,  2,  7, 1,  79, 12,  5}, // min
+       { 42,  6,  7, 3, 126, 22,  9}, // max
+       225000, 1760000, 3510000
+};
+
+#if 0
+static pll_limits kLimitsChv = {
+       // p, p1, p2, n,   m, m1, m2
+       {  0,  2, 14, 1,  79, 2,   24 << 22}, // min
+       {  0,  4,  1, 1, 127, 2,  175 << 22}, // max
+       0, 4800000, 6480000
+};
+
+static pll_limits kLimitsVlv = {
+       // p, p1, p2, n,   m, m1, m2
+       {  0,  2, 20, 1,  79, 2,   11}, // min
+       {  0,  3,  2, 7, 127, 3,  156}, // max
+       0, 4000000, 6000000
+};
+
+static pll_limits kLimitsBxt = {
+       // p, p1, p2, n,  m, m1, m2
+       {  0,  2,  1, 1,  0,  2,   2 << 22}, // min
+       {  0,  4, 20, 1,  0,  2, 255 << 22}, // max
+       0, 4800000, 6700000
+};
+#endif
+
+static pll_limits kLimits9xxSdvo = {
+       // p, p1, p2,  n,   m, m1, m2
+       {  5,  1, 10,  5,  70, 12,  7}, // min
+       { 80,  8,  5, 10, 120, 22, 11}, // max
+       200000, 1400000, 2800000
+};
+
+static pll_limits kLimits9xxLvds = {
+       // p, p1, p2,  n,   m, m1, m2
+       {  7,  1, 14,  1,  70,  8,  3}, // min
+       { 98,  8,  7,  6, 120, 18,  7}, // max
+       112000, 1400000, 2800000
+};
+
+static pll_limits kLimitsG4xSdvo = {
+       // p, p1, p2, n,   m, m1, m2
+       { 10,  1, 10, 1, 104, 17,  5},  // min
+       { 30,  3, 10, 4, 138, 23, 11},  // max
+       270000, 1750000, 3500000
+};
+
+#if 0
+static pll_limits kLimitsG4xHdmi = {
+       // p, p1, p2, n,   m, m1, m2
+       {  5,  1, 10, 1, 104, 16,  5},  // min
+       { 80,  8,  5, 4, 138, 23, 11},  // max
+       165000, 1750000, 3500000
+};
+#endif
+
+static pll_limits kLimitsG4xLvdsSingle = {
+       // p,  p1, p2, n,   m, m1, m2
+       { 28,   2, 14, 1, 104, 17,  5}, // min
+       { 112,  8, 14, 3, 138, 23, 11}, // max
+       0, 1750000, 3500000
+};
+
+static pll_limits kLimitsG4xLvdsDual = {
+       // p, p1, p2, n,   m, m1, m2
+       { 14,  2,  7, 1, 104, 17,  5},  // min
+       { 42,  6,  7, 3, 138, 23, 11},  // max
+       0, 1750000, 3500000
+};
+
+static pll_limits kLimitsPinSdvo = {
+       // p, p1, p2, n,   m, m1,  m2
+       {  5,  1, 10, 3,   2,  0,   0}, // min
+       { 80,  8,  5, 6, 256,  0, 254}, // max
+       200000, 1700000, 3500000
+};
+
+static pll_limits kLimitsPinLvds = {
+       // p, p1, p2, n,   m, m1,  m2
+       {  7,  1, 14, 3,   2,  0,   0}, // min
+       {112,  8, 14, 6, 256,  0, 254}, // max
+       112000, 1700000, 3500000
+};
+
+#if 0
+static pll_limits kLimits = {
+       // p, p1, p2,  n,   m, m1, m2
+       {  4,  2,  4,  5,  96, 20,  8},
+       {128, 33,  2, 18, 140, 28, 18},
+       165000, 930000, 1400000
+};
+#endif
+
+
+static bool
+lvds_dual_link(display_mode* current)
 {
-       // Note, the limits are taken from the X driver; they have not yet been
-       // tested
-
-       // TODO: Breakout BXT
-
-       if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) {
-               pll_limits kLimits = {
-                       // p, p1, p2, high,   n,   m, m1, m2
-                       {  5,  2, 14, false,  1,  79, 2,  24 << 22},    // min
-                       { 80,  4,  1, true,   1, 127, 2,  175 << 22},   // max
-                       225000, 4800000, 6480000
-               };
-               memcpy(limits, &kLimits, sizeof(pll_limits));
-       } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) {
-               pll_limits kLimits = {
-                       // p, p1, p2, high,   n,   m, m1, m2
-                       {  5,  2, 20, false,  1,  79, 2,  11},  // min
-                       { 80,  3,  2, true,   7, 127, 3,  156}, // max
-                       225000, 4000000, 6000000
-               };
-               memcpy(limits, &kLimits, sizeof(pll_limits));
-       } else if (gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_SER5)
-               || gInfo->shared_info->device_type.InGroup(INTEL_GROUP_BXT)) {
-               pll_limits kLimits = {
-                       // p, p1, p2, high,   n,   m, m1, m2
-                       {  5,  1, 10, false,  1,  79, 12,  5},  // min
-                       { 80,  8,  5, true,   5, 127, 22,  9},  // max
-                       225000, 1760000, 3510000
-               };
-               // TODO: validate these LVDS dividers!
-               if (isLVDS) {
-                       kLimits.min.post = 7;
-                       kLimits.max.post = 98;
-                       kLimits.min.post2 = 14;
-                       kLimits.max.post2 = 7;
-               }
-               memcpy(limits, &kLimits, sizeof(pll_limits));
-       } else if (gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_9xx)) {
-               pll_limits kLimits = {
-                       // p, p1, p2, high,   n,   m, m1, m2
-                       {  5,  1, 10, false,  1,  70, 8,  3},   // min
-                       { 80,  8,  5, true,   6, 120, 18, 7},   // max
-                       200000, 1400000, 2800000
-               };
-               if (isLVDS) {
-                       kLimits.min.post = 7;
-                       kLimits.max.post = 98;
-                       kLimits.min.post2 = 14;
-                       kLimits.max.post2 = 7;
-               }
-               memcpy(limits, &kLimits, sizeof(pll_limits));
-       } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_G4x)) {
-               pll_limits kLimits = {
-                       // p, p1, p2, high,   n,   m, m1, m2
-                       { 10,  1, 10, false,  1, 104, 17,  5},  // min
-                       { 30,  3, 10, true,   4, 138, 23, 11},  // max
-                       270000, 1750000, 3500000
-               };
-               // TODO: validate these LVDS dividers!
-               if (isLVDS) {
-                       kLimits.min.post = 7;
-                       kLimits.max.post = 98;
-                       kLimits.min.post2 = 14;
-                       kLimits.max.post2 = 7;
-               }
-               memcpy(limits, &kLimits, sizeof(pll_limits));
-       } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
-               // m1 is reserved and must be 0
-               pll_limits kLimits = {
-                       // p, p1, p2, high,   n,   m, m1,  m2
-                       {  5,  1, 10, false,  3,   2,  0,   2}, // min
-                       { 80,  8,  5, true,   6, 256,  0, 254}, // max
-                       200000, 1700000, 3500000
-               };
-               if (isLVDS) {
-                       kLimits.min.post = 7;
-                       kLimits.max.post = 112;
-                       kLimits.min.post2 = 14;
-                       kLimits.max.post2 = 14;
-               }
-               memcpy(limits, &kLimits, sizeof(pll_limits));
-       } else {
-               static pll_limits kLimits = {
-                       // p, p1, p2, high,   n,   m, m1, m2
-                       {  4,  2,  4, false,  5,  96, 20,  8},
-                       {128, 33,  2, true,  18, 140, 28, 18},
-                       165000, 930000, 1400000
-               };
-               // TODO: Validate these LVDS dividers!
-               if (isLVDS) {
-                       kLimits.min.post = 7;
-                       kLimits.max.post = 98;
-                       kLimits.min.post2 = 14;
-                       kLimits.max.post2 = 7;
-               }
-               memcpy(limits, &kLimits, sizeof(pll_limits));
-       }
+       float requestedPixelClock = current->timing.pixel_clock / 1000.0f;
+       if (requestedPixelClock > 112.999)
+               return true;
 
-       TRACE("PLL limits, min: p %" B_PRId32 " (p1 %" B_PRId32 ", "
-               "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
-               "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits->min.post,
-               limits->min.post1, limits->min.post2, limits->min.n, 
limits->min.m,
-               limits->min.m1, limits->min.m2);
-       TRACE("PLL limits, max: p %" B_PRId32 " (p1 %" B_PRId32 ", "
-               "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
-               "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits->max.post,
-               limits->max.post1, limits->max.post2, limits->max.n, 
limits->max.m,
-               limits->max.m1, limits->max.m2);
+       // TODO: Force dual link on MacBookPro6,2  MacBookPro8,2  MacBookPro9,1
+
+       return ((read32(INTEL_DIGITAL_LVDS_PORT) & LVDS_CLKB_POWER_MASK)
+               == LVDS_CLKB_POWER_UP);
 }
 
 
@@ -157,9 +186,9 @@ valid_pll_divisors(pll_divisors* divisors, pll_limits* 
limits)
 {
        pll_info &info = gInfo->shared_info->pll_info;
        uint32 vco = info.reference_frequency * divisors->m / divisors->n;
-       uint32 frequency = vco / divisors->post;
+       uint32 frequency = vco / divisors->p;
 
-       if (divisors->post < limits->min.post || divisors->post > 
limits->max.post
+       if (divisors->p < limits->min.p || divisors->p > limits->max.p
                || divisors->m < limits->min.m || divisors->m > limits->max.m
                || vco < limits->min_vco || vco > limits->max_vco
                || frequency < info.min_frequency || frequency > 
info.max_frequency)
@@ -169,6 +198,30 @@ valid_pll_divisors(pll_divisors* divisors, pll_limits* 
limits)
 }
 
 
+static void
+compute_pll_p2(display_mode* current, pll_divisors* divisors,
+       pll_limits* limits, bool isLVDS)
+{
+       if (isLVDS) {
+               if (lvds_dual_link(current)) {
+                       // fast DAC timing via 2 channels (dual link LVDS)
+                       divisors->p2 = limits->max.p2;
+               } else {
+                       // slow DAC timing
+                       divisors->p2 = limits->min.p2;
+               }
+       } else {
+               if (current->timing.pixel_clock < limits->dot_limit) {
+                       // slow DAC timing
+                       divisors->p2 = limits->min.p2;
+               } else {
+                       // fast DAC timing
+                       divisors->p2 = limits->max.p2;
+               }
+       }
+}
+
+
 static uint32
 compute_pll_m(pll_divisors* divisors)
 {
@@ -194,68 +247,160 @@ compute_pll_m(pll_divisors* divisors)
 static uint32
 compute_pll_p(pll_divisors* divisors)
 {
-       return divisors->post1 * divisors->post2;
+       return divisors->p1 * divisors->p2;
 }
 
 
-void
-compute_pll_divisors(display_mode* current, pll_divisors* divisors,
-       bool isLVDS)
+static void
+compute_dpll_g4x(display_mode* current, pll_divisors* divisors, bool isLVDS)
 {
        float requestedPixelClock = current->timing.pixel_clock / 1000.0f;
        float referenceClock
                = gInfo->shared_info->pll_info.reference_frequency / 1000.0f;
-       pll_limits limits;
-       get_pll_limits(&limits, isLVDS);
 
        TRACE("%s: required MHz: %g\n", __func__, requestedPixelClock);
 
-       // Calculate p2
-       if (isLVDS) {
-               if (requestedPixelClock > 112.999
-                       || (read32(INTEL_DIGITAL_LVDS_PORT) & 
LVDS_CLKB_POWER_MASK)
-                               == LVDS_CLKB_POWER_UP) {
-                       // fast DAC timing via 2 channels
-                       divisors->post2 = limits.max.post2;
-                       divisors->post2_high = limits.max.post2_high;
-               } else {
-                       // slow DAC timing
-                       divisors->post2 = limits.min.post2;
-                       divisors->post2_high = limits.min.post2_high;
-               }
+       pll_limits limits;
+       if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_G4x)) {
+               // TODO: Pass port type via video_configuration
+               if (isLVDS) {
+                       if (lvds_dual_link(current))
+                               memcpy(&limits, &kLimitsG4xLvdsDual, 
sizeof(pll_limits));
+                       else
+                               memcpy(&limits, &kLimitsG4xLvdsSingle, 
sizeof(pll_limits));
+               //} else if (type == INTEL_PORT_TYPE_HDMI) {
+               //      memcpy(&limits, &kLimitsG4xHdmi, sizeof(pll_limits));
+               } else
+                       memcpy(&limits, &kLimitsG4xSdvo, sizeof(pll_limits));
        } else {
-               if (current->timing.pixel_clock < limits.min_post2_frequency) {
-                       // slow DAC timing
-                       divisors->post2 = limits.min.post2;
-                       divisors->post2_high = limits.min.post2_high;
+               if (isLVDS) {
+                       if (lvds_dual_link(current)) {
+                               if (referenceClock == 100.0)
+                                       memcpy(&limits, &kLimitsIlkLvdsDual100, 
sizeof(pll_limits));
+                               else
+                                       memcpy(&limits, &kLimitsIlkLvdsDual, 
sizeof(pll_limits));
+                       } else {
+                               if (referenceClock == 100.0) {
+                                       memcpy(&limits, 
&kLimitsIlkLvdsSingle100,
+                                               sizeof(pll_limits));
+                               } else {
+                                       memcpy(&limits, &kLimitsIlkLvdsSingle, 
sizeof(pll_limits));
+                               }
+                       }
                } else {
-                       // fast DAC timing
-                       divisors->post2 = limits.max.post2;
-                       divisors->post2_high = limits.max.post2_high;
+                       memcpy(&limits, &kLimitsIlkDac, sizeof(pll_limits));
                }
        }
 
+       compute_pll_p2(current, divisors, &limits, isLVDS);
+
+       TRACE("PLL limits, min: p %" B_PRId32 " (p1 %" B_PRId32 ", "
+               "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
+               "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits.min.p,
+               limits.min.p1, limits.min.p2, limits.min.n, limits.min.m,
+               limits.min.m1, limits.min.m2);
+       TRACE("PLL limits, max: p %" B_PRId32 " (p1 %" B_PRId32 ", "
+               "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
+               "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits.max.p,
+               limits.max.p1, limits.max.p2, limits.max.n, limits.max.m,
+               limits.max.m1, limits.max.m2);
+
        float best = requestedPixelClock;
        pll_divisors bestDivisors;
 
+       uint32 maxn = limits.max.n;
+       for (divisors->n = limits.min.n; divisors->n <= maxn; divisors->n++) {
+               for (divisors->m1 = limits.max.m1; divisors->m1 >= 
limits.min.m1;
+                               divisors->m1--) {
+                       for (divisors->m2 = limits.max.m2; divisors->m2 >= 
limits.min.m2;
+                                       divisors->m2--) {
+                               for (divisors->p1 = limits.max.p1;
+                                               divisors->p1 >= limits.max.p1; 
divisors->p1--) {
+                                       divisors->m = compute_pll_m(divisors);
+                                       divisors->p = compute_pll_p(divisors);
+
+                                       if (!valid_pll_divisors(divisors, 
&limits))
+                                               continue;
+
+                                       float error = fabs(requestedPixelClock
+                                               - ((referenceClock * 
divisors->m) / divisors->n)
+                                               / divisors->p);
+                                       if (error < best) {
+                                               best = error;
+                                               bestDivisors = *divisors;
+                                               maxn = divisors->n;
+
+                                               if (error == 0)
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+       }
+       *divisors = bestDivisors;
+       TRACE("%s: best MHz: %g (error: %g)\n", __func__,
+               ((referenceClock * divisors->m) / divisors->n) / divisors->p,
+               best);
+}
+
+
+static void
+compute_dpll_9xx(display_mode* current, pll_divisors* divisors, bool isLVDS)
+{
+       float requestedPixelClock = current->timing.pixel_clock / 1000.0f;
+       float referenceClock
+               = gInfo->shared_info->pll_info.reference_frequency / 1000.0f;
+
+       TRACE("%s: required MHz: %g\n", __func__, requestedPixelClock);
+
+       pll_limits limits;
+       if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
+               if (isLVDS)
+                       memcpy(&limits, &kLimitsPinLvds, sizeof(pll_limits));
+               else
+                       memcpy(&limits, &kLimitsPinSdvo, sizeof(pll_limits));
+       } else {
+               if (isLVDS)
+                       memcpy(&limits, &kLimits9xxLvds, sizeof(pll_limits));
+               else
+                       memcpy(&limits, &kLimits9xxSdvo, sizeof(pll_limits));
+       }
+
+       compute_pll_p2(current, divisors, &limits, isLVDS);
+
+       TRACE("PLL limits, min: p %" B_PRId32 " (p1 %" B_PRId32 ", "
+               "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
+               "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits.min.p,
+               limits.min.p1, limits.min.p2, limits.min.n, limits.min.m,
+               limits.min.m1, limits.min.m2);
+       TRACE("PLL limits, max: p %" B_PRId32 " (p1 %" B_PRId32 ", "
+               "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
+               "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits.max.p,
+               limits.max.p1, limits.max.p2, limits.max.n, limits.max.m,
+               limits.max.m1, limits.max.m2);
+
        bool is_pine = gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN);
+
+       float best = requestedPixelClock;
+       pll_divisors bestDivisors;
+
        for (divisors->m1 = limits.min.m1; divisors->m1 <= limits.max.m1;
                        divisors->m1++) {
                for (divisors->m2 = limits.min.m2; divisors->m2 <= limits.max.m2
                                && ((divisors->m2 < divisors->m1) || is_pine); 
divisors->m2++) {
                        for (divisors->n = limits.min.n; divisors->n <= 
limits.max.n;
                                        divisors->n++) {
-                               for (divisors->post1 = limits.min.post1;
-                                               divisors->post1 <= 
limits.max.post1; divisors->post1++) {
+                               for (divisors->p1 = limits.min.p1;
+                                               divisors->p1 <= limits.max.p1; 
divisors->p1++) {
                                        divisors->m = compute_pll_m(divisors);
-                                       divisors->post = 
compute_pll_p(divisors);
+                                       divisors->p = compute_pll_p(divisors);
 
                                        if (!valid_pll_divisors(divisors, 
&limits))
                                                continue;
 
                                        float error = fabs(requestedPixelClock
                                                - ((referenceClock * 
divisors->m) / divisors->n)
-                                               / divisors->post);
+                                               / divisors->p);
                                        if (error < best) {
                                                best = error;
                                                bestDivisors = *divisors;
@@ -270,10 +415,28 @@ compute_pll_divisors(display_mode* current, pll_divisors* 
divisors,
 
        *divisors = bestDivisors;
 
-       TRACE("%s: found: %g MHz, p = %" B_PRId32 " (p1 = %" B_PRId32 ", "
+       TRACE("%s: best MHz: %g (error: %g)\n", __func__,
+               ((referenceClock * divisors->m) / divisors->n) / divisors->p,
+               best);
+}
+
+
+void
+compute_pll_divisors(display_mode* current, pll_divisors* divisors, bool 
isLVDS)
+{
+       if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_G4x)
+               || gInfo->shared_info->device_type.HasPlatformControlHub()) {
+               compute_dpll_g4x(current, divisors, isLVDS);
+       } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) {
+               // TODO: CherryView
+       } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) {
+               // TODO: VallyView
+       } else
+               compute_dpll_9xx(current, divisors, isLVDS);
+
+       TRACE("%s: found: p = %" B_PRId32 " (p1 = %" B_PRId32 ", "
                "p2 = %" B_PRId32 "), n = %" B_PRId32 ", m = %" B_PRId32 " "
                "(m1 = %" B_PRId32 ", m2 = %" B_PRId32 ")\n", __func__,
-               ((referenceClock * divisors->m) / divisors->n) / divisors->post,
-               divisors->post, divisors->post1, divisors->post2, divisors->n,
+               divisors->p, divisors->p1, divisors->p2, divisors->n,
                divisors->m, divisors->m1, divisors->m2);
 }
diff --git a/src/add-ons/accelerants/intel_extreme/pll.h 
b/src/add-ons/accelerants/intel_extreme/pll.h
index 706f97b..2b607ce 100644
--- a/src/add-ons/accelerants/intel_extreme/pll.h
+++ b/src/add-ons/accelerants/intel_extreme/pll.h
@@ -14,10 +14,9 @@
 
 
 struct pll_divisors {
-       uint32  post;
-       uint32  post1;
-       uint32  post2;
-       bool    post2_high;
+       uint32  p;
+       uint32  p1;
+       uint32  p2;
        uint32  n;
        uint32  m;
        uint32  m1;
@@ -27,13 +26,12 @@ struct pll_divisors {
 struct pll_limits {
        pll_divisors    min;
        pll_divisors    max;
-       uint32          min_post2_frequency;
+       uint32                  dot_limit;
        uint32          min_vco;
        uint32          max_vco;
 };
 
 
-void get_pll_limits(pll_limits* limits, bool isLVDS);
 bool valid_pll_divisors(pll_divisors* divisors, pll_limits* limits);
 void compute_pll_divisors(display_mode* current, pll_divisors* divisors,
        bool isLVDS);

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

Revision:    hrev50303
Commit:      a32e8156730975d66634c655655fdf68b56660fc
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a32e81567309
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Wed May 11 17:35:50 2016 UTC

intel_extreme: Shorten graphics family names

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

diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp 
b/src/add-ons/accelerants/intel_extreme/accelerant.cpp
index 6510c86..f2adfe2 100644
--- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp
+++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp
@@ -564,18 +564,18 @@ intel_get_accelerant_device_info(accelerant_device_info* 
info)
 
        DeviceType* type = &gInfo->shared_info->device_type;
 
-       if (type->InFamily(INTEL_FAMILY_7xx))
-               strcpy(info->name, "Intel Extreme Graphics");
-       else if (type->InFamily(INTEL_FAMILY_8xx))
-               strcpy(info->name, "Intel Extreme Graphics 2");
+       if (type->InFamily(INTEL_FAMILY_7xx) || 
type->InFamily(INTEL_FAMILY_8xx))
+               strcpy(info->name, "Intel Extreme");
        else if (type->InFamily(INTEL_FAMILY_9xx))
-               strcpy(info->name, "Intel Graphics Media Accelerator");
-       else if (type->InFamily(INTEL_FAMILY_SER5))
-               strcpy(info->name, "Intel HD/Iris Graphics");
+               strcpy(info->name, "Intel GMA");
        else if (type->InFamily(INTEL_FAMILY_POVR))
-               strcpy(info->name, "Intel PowerVR Graphics");
+               strcpy(info->name, "Intel PowerVR");
        else if (type->InFamily(INTEL_FAMILY_SOC0))
-               strcpy(info->name, "Intel Atom Graphics");
+               strcpy(info->name, "Intel Atom");
+       else if (type->InFamily(INTEL_FAMILY_SER5))
+               strcpy(info->name, "Intel HD/Iris");
+       else
+               strcpy(info->name, "Intel");
 
        strcpy(info->chipset, gInfo->shared_info->device_identifier);
        strcpy(info->serial_no, "None");


Other related posts:

  • » [haiku-commits] haiku: hrev50303 - src/add-ons/accelerants/intel_extreme - kallisti5