[haiku-commits] haiku: hrev52279 - in src: add-ons/accelerants/intel_extreme tests/add-ons/accelerants/intel_extreme add-ons/kernel/drivers/graphics/intel_extreme

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 25 Aug 2018 14:52:35 -0400 (EDT)

hrev52279 adds 1 changeset to branch 'master'
old head: c0bbce07c8f99bbf3f7c7b54a5e8e30ce906113c
new head: c2d37953f3bbe2e53c1c937040858bbbe59a664d
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=c2d37953f3bb+%5Ec0bbce07c8f9

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

c2d37953f3bb: Rework PLL calculations for Iron Lake
  
  The limits were wrong in several places. Checked the sandy bridge, ivy
  brige and haswell docs, they all say mostly the same.
  
  - The value of p2 is either 7, 14, 5 or 10 depending on 1 bit in the
    config register and on the display type. We can guess which values are
    right according to the global P limit (5-80 when using 5/10,
    28-something when using 14/7). The values are different because CRT
    need a precise, but rather low pixel clock, while modern display
    interface can accomodate being faster than required by a few MHz, but
    need a much higher speed (the bits are transferred serially, so they
    need to be at least 8 times faster than a DAC).
  
  - The limits for N were obviously wrong, as the register is written with
    N-2, so values less than 2 make no sense. Use 3-8 as specified in the
    datasheet.
  
  - The reference frequency (set by the driver) was wrong, too. It is
    120MHz, not 96. It is 100MHz in some cases (FDI, etc), we should see
    when this happens and switch to the right reference for PLL
    computations.
  
  - There was an attempt to minimize the value of N (a powersaving effort,
    I guess?), but it would basically force the loop to stop at the first
    value of N tested, resulting in way off timings in some cases.
  
  - To ease testing and stop sending patches and syslogs back and forth
    with vidrep, extract the "test mode" from pll.cpp into a proper test
    executable, making it a little easier to experiment with the code and
    fix the problems.
  
  This should fix #13669 and possibly other cases of "out of range", black
  screen, bad timings, etc.
  
  Change-Id: Ic4c1c159701f352b7c1ef15a647f023c82ac26c
  Reviewed-on: https://review.haiku-os.org/360
  Reviewed-by: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
  Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

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

Revision:    hrev52279
Commit:      c2d37953f3bbe2e53c1c937040858bbbe59a664d
URL:         https://git.haiku-os.org/haiku/commit/?id=c2d37953f3bb
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Sat Jul 28 20:52:37 2018 UTC
Committer:   waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Sat Aug 25 18:52:33 2018 UTC

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

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

6 files changed, 171 insertions(+), 121 deletions(-)
src/add-ons/accelerants/intel_extreme/pll.cpp    | 135 +++----------------
.../graphics/intel_extreme/intel_extreme.cpp     |  15 ++-
src/tests/add-ons/Jamfile                        |   1 +
src/tests/add-ons/accelerants/Jamfile            |   3 +
.../add-ons/accelerants/intel_extreme/Jamfile    |  17 +++
.../accelerants/intel_extreme/PllTest.cpp        | 121 +++++++++++++++++

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

diff --git a/src/add-ons/accelerants/intel_extreme/pll.cpp 
b/src/add-ons/accelerants/intel_extreme/pll.cpp
index 1b0026e23b..e319253c83 100644
--- a/src/add-ons/accelerants/intel_extreme/pll.cpp
+++ b/src/add-ons/accelerants/intel_extreme/pll.cpp
@@ -1,20 +1,11 @@
 /*
- * Copyright 2006-2016, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2018, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
  *             Alexander von Gluck IV, kallisti5@xxxxxxxxxxx
- *
- * PLL TEST MODE
- *  pll's on Intel can be extremely difficult. After
- *  making any changes, it is advised to run PLL_TEST_MODE
- *  to simulate your pll calculations on every card.
- *  Example:
- *  gcc pll.cpp \
- *    -I $TOP/headers/private/graphics/intel_extreme/
- *    -I $TOP/headers/private/graphics/common/
- *    -I $TOP/headers/private/graphics/ -D PLL_TEST_MODE
+ *             Adrien Destugues, pulkomandy@xxxxxxxxxxxxx
  */
 
 
@@ -48,52 +39,42 @@
 #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
 
 
-#ifdef PLL_TEST_MODE
-#undef ERROR
-#undef CALLED
-#undef TRACE
-
-#define TRACE(x...) printf("intel_extreme: " x)
-#define ERROR(x...) printf("intel_extreme: " x)
-#define CALLED(X...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
-struct accelerant_info* gInfo;
-#endif
 
 // 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
+       {  5,  1,  5, 3,  79, 12,  5}, // min
+       { 80,  8, 10, 8, 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
+       { 28,  2, 14, 3,  79, 12,  5}, // min
+       {112,  8, 14, 8, 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
+       { 14,  2,  7, 3,  79, 12,  5}, // min
+       { 56,  8,  7, 8, 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
+       { 28,  2, 14, 3,  79, 12,  5}, // min
+       {112,  8, 14, 8, 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
+       { 14,  2,  7, 3,  79, 12,  5}, // min
+       { 42,  6,  7, 8, 126, 22,  9}, // max
        225000, 1760000, 3510000
 };
 
@@ -232,10 +213,10 @@ compute_pll_p2(display_mode* current, pll_divisors* 
divisors,
        } else {
                if (current->timing.pixel_clock < limits->dot_limit) {
                        // slow DAC timing
-                       divisors->p2 = limits->min.p2;
+                       divisors->p2 = limits->max.p2;
                } else {
                        // fast DAC timing
-                       divisors->p2 = limits->max.p2;
+                       divisors->p2 = limits->min.p2;
                }
        }
 }
@@ -277,7 +258,8 @@ compute_dpll_g4x(display_mode* current, pll_divisors* 
divisors, bool isLVDS)
        float referenceClock
                = gInfo->shared_info->pll_info.reference_frequency / 1000.0f;
 
-       TRACE("%s: required MHz: %g\n", __func__, requestedPixelClock);
+       TRACE("%s: required MHz: %g, reference clock: %g\n", __func__,
+               requestedPixelClock, referenceClock);
 
        pll_limits limits;
        if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_G4x)) {
@@ -292,6 +274,7 @@ compute_dpll_g4x(display_mode* current, pll_divisors* 
divisors, bool isLVDS)
                } else
                        memcpy(&limits, &kLimitsG4xSdvo, sizeof(pll_limits));
        } else {
+               // There must be a PCH, so this is ivy bridge or later
                if (isLVDS) {
                        if (lvds_dual_link(current)) {
                                if (referenceClock == 100.0)
@@ -327,8 +310,8 @@ compute_dpll_g4x(display_mode* current, pll_divisors* 
divisors, bool isLVDS)
        float best = requestedPixelClock;
        pll_divisors bestDivisors;
 
-       uint32 maxn = limits.max.n;
-       for (divisors->n = limits.min.n; divisors->n <= maxn; divisors->n++) {
+       for (divisors->n = limits.min.n; divisors->n <= limits.max.n;
+                       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;
@@ -347,7 +330,6 @@ compute_dpll_g4x(display_mode* current, pll_divisors* 
divisors, bool isLVDS)
                                        if (error < best) {
                                                best = error;
                                                bestDivisors = *divisors;
-                                               maxn = divisors->n;
 
                                                if (error == 0)
                                                        break;
@@ -548,82 +530,3 @@ refclk_activate_ilk(bool hasPanel)
        }
 }
 
-
-#ifdef PLL_TEST_MODE
-
-const struct  test_device {
-       uint32 type;
-       const char* name;
-} kTestDevices[] = {
-       {INTEL_MODEL_915, "915"},
-       {INTEL_MODEL_945, "945"},
-       {INTEL_MODEL_965, "965"},
-       {INTEL_MODEL_G33, "G33"},
-       {INTEL_MODEL_G45, "G45"},
-       {INTEL_MODEL_PINE, "PineView"},
-       {INTEL_MODEL_ILKG, "IronLake"},
-       {INTEL_MODEL_SNBG, "SandyBridge"},
-       {INTEL_MODEL_IVBG, "IvyBridge"}
-};
-
-
-static void
-simulate_mode(display_mode* mode)
-{
-       mode->timing.flags = 0;
-       mode->timing.pixel_clock = uint32(75.2 * 1000);
-       mode->timing.h_display = 1366;
-       mode->timing.h_sync_start = 1414;
-       mode->timing.h_sync_end = 1478;
-       mode->timing.h_total = 1582;
-
-       mode->timing.v_display = 768;
-       mode->timing.v_sync_start = 772;
-       mode->timing.v_sync_end = 779;
-       mode->timing.v_total = 792;
-
-       mode->virtual_width = 1366;
-       mode->virtual_height = 768;
-}
-
-
-int
-main(void)
-{
-       display_mode fakeMode;
-       simulate_mode(&fakeMode);
-
-       // First we simulate our global card info structs
-       gInfo = (accelerant_info*)malloc(sizeof(accelerant_info));
-       if (gInfo == NULL) {
-               ERROR("Unable to malloc artificial gInfo!\n");
-               return 1;
-       }
-       gInfo->shared_info = 
(intel_shared_info*)malloc(sizeof(intel_shared_info));
-
-       for (uint32 index = 0; index < (sizeof(kTestDevices) / 
sizeof(test_device));
-               index++) {
-               gInfo->shared_info->device_type = kTestDevices[index].type;
-               ERROR("=== %s (Generation %d)\n",  kTestDevices[index].name,
-                       gInfo->shared_info->device_type.Generation());
-
-               if (gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_9xx)
-                       | 
gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_SER5)) {
-                       gInfo->shared_info->pll_info.reference_frequency = 
96000;
-                       gInfo->shared_info->pll_info.max_frequency = 400000;
-                       gInfo->shared_info->pll_info.min_frequency = 20000;
-               } else {
-                       gInfo->shared_info->pll_info.reference_frequency = 
96000;
-                       gInfo->shared_info->pll_info.max_frequency = 400000;
-                       gInfo->shared_info->pll_info.min_frequency = 20000;
-               }
-
-               pll_divisors output;
-               compute_pll_divisors(&fakeMode, &output, false);
-       }
-
-       free(gInfo->shared_info);
-       free(gInfo);
-       return 0;
-}
-#endif
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 0614f6e86e..b7c6d13a7c 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
@@ -1,10 +1,11 @@
 /*
- * Copyright 2006-2014, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2018, Haiku, Inc. All Rights Reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
  *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
  *             Alexander von Gluck IV, kallisti5@xxxxxxxxxxx
+ *             Adrien Destugues, pulkomandy@xxxxxxxxxxxxx
  */
 
 
@@ -461,14 +462,18 @@ intel_extreme_init(intel_info &info)
        if (info.device_type.InFamily(INTEL_FAMILY_8xx))
                info.shared_info->single_head_locked = 1;
 
-       if (info.device_type.InFamily(INTEL_FAMILY_9xx)
-               | info.device_type.InFamily(INTEL_FAMILY_SER5)) {
-               info.shared_info->pll_info.reference_frequency = 96000; // 96 
kHz
+       if (info.device_type.InFamily(INTEL_FAMILY_SER5)) {
+               info.shared_info->pll_info.reference_frequency = 120000;        
// 120 MHz
+               info.shared_info->pll_info.max_frequency = 350000;
+                       // 350 MHz RAM DAC speed
+               info.shared_info->pll_info.min_frequency = 20000;               
// 20 MHz
+       } else if (info.device_type.InFamily(INTEL_FAMILY_9xx)) {
+               info.shared_info->pll_info.reference_frequency = 96000; // 96 
MHz
                info.shared_info->pll_info.max_frequency = 400000;
                        // 400 MHz RAM DAC speed
                info.shared_info->pll_info.min_frequency = 20000;               
// 20 MHz
        } else {
-               info.shared_info->pll_info.reference_frequency = 48000; // 48 
kHz
+               info.shared_info->pll_info.reference_frequency = 48000; // 48 
MHz
                info.shared_info->pll_info.max_frequency = 350000;
                        // 350 MHz RAM DAC speed
                info.shared_info->pll_info.min_frequency = 25000;               
// 25 MHz
diff --git a/src/tests/add-ons/Jamfile b/src/tests/add-ons/Jamfile
index 26a4111a69..63f8d416d9 100644
--- a/src/tests/add-ons/Jamfile
+++ b/src/tests/add-ons/Jamfile
@@ -1,5 +1,6 @@
 SubDir HAIKU_TOP src tests add-ons ;
 
+SubInclude HAIKU_TOP src tests add-ons accelerants ;
 SubInclude HAIKU_TOP src tests add-ons input_server ;
 SubInclude HAIKU_TOP src tests add-ons index_server ;
 SubInclude HAIKU_TOP src tests add-ons kernel ;
diff --git a/src/tests/add-ons/accelerants/Jamfile 
b/src/tests/add-ons/accelerants/Jamfile
new file mode 100644
index 0000000000..06109cb676
--- /dev/null
+++ b/src/tests/add-ons/accelerants/Jamfile
@@ -0,0 +1,3 @@
+SubDir HAIKU_TOP src tests add-ons accelerants ;
+
+SubInclude HAIKU_TOP src tests add-ons accelerants intel_extreme ;
diff --git a/src/tests/add-ons/accelerants/intel_extreme/Jamfile 
b/src/tests/add-ons/accelerants/intel_extreme/Jamfile
new file mode 100644
index 0000000000..40a463fa5e
--- /dev/null
+++ b/src/tests/add-ons/accelerants/intel_extreme/Jamfile
@@ -0,0 +1,17 @@
+SubDir HAIKU_TOP src tests add-ons accelerants intel_extreme ;
+
+SubDirHdrs $(HAIKU_TOP) src add-ons accelerants intel_extreme ;
+UsePrivateHeaders [ FDirName graphics ] ;
+UsePrivateHeaders [ FDirName graphics common ] ;
+UsePrivateHeaders [ FDirName graphics intel_extreme ] ;
+#UsePrivateSystemHeaders ;
+
+SimpleTest PllTest :
+       PllTest.cpp
+       pll.cpp
+       :
+       ;
+
+SEARCH on [ FGristFiles pll.cpp ] = [
+       FDirName $(HAIKU_TOP) src add-ons accelerants intel_extreme ] ;
+
diff --git a/src/tests/add-ons/accelerants/intel_extreme/PllTest.cpp 
b/src/tests/add-ons/accelerants/intel_extreme/PllTest.cpp
new file mode 100644
index 0000000000..74b2b94b37
--- /dev/null
+++ b/src/tests/add-ons/accelerants/intel_extreme/PllTest.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2006-2018, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Alexander von Gluck IV, kallisti5@xxxxxxxxxxx
+ *             Adrien Destugues, pulkomandy@xxxxxxxxxxxxx
+ */
+
+#include "accelerant_protos.h"
+#include "accelerant.h"
+#include "intel_extreme.h"
+#include "pll.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+struct accelerant_info* gInfo;
+
+const struct  test_device {
+       uint32 type;
+       const char* name;
+} kTestDevices[] = {
+       {INTEL_MODEL_915, "915"},
+       {INTEL_MODEL_945, "945"},
+       {INTEL_MODEL_965, "965"},
+       {INTEL_MODEL_G33, "G33"},
+       {INTEL_MODEL_G45, "G45"},
+       {INTEL_MODEL_PINE, "PineView"},
+       {INTEL_MODEL_ILKG, "IronLake"},
+       {INTEL_MODEL_SNBG, "SandyBridge"},
+       {INTEL_MODEL_IVBG, "IvyBridge"}
+};
+
+
+// This is a function from app_server which the accelerant calls, we need an
+// implementation so pll.cpp can link.
+extern "C" void spin(long long int) {
+}
+
+
+static void
+simulate_mode(display_mode* mode, int j)
+{
+       mode->timing.flags = 0;
+       if (j == 0)
+               mode->timing.pixel_clock = uint32(75.2 * 1000);
+       else
+               mode->timing.pixel_clock = uint32(146.25 * 1000);
+       mode->timing.h_display = 1366;
+       mode->timing.h_sync_start = 1414;
+       mode->timing.h_sync_end = 1478;
+       mode->timing.h_total = 1582;
+
+       mode->timing.v_display = 768;
+       mode->timing.v_sync_start = 772;
+       mode->timing.v_sync_end = 779;
+       mode->timing.v_total = 792;
+
+       mode->virtual_width = 1366;
+       mode->virtual_height = 768;
+}
+
+
+int
+main(void)
+{
+       // First we simulate our global card info structs
+       gInfo = (accelerant_info*)malloc(sizeof(accelerant_info));
+       if (gInfo == NULL) {
+               fprintf(stderr, "Unable to malloc artificial gInfo!\n");
+               return 1;
+       }
+
+       gInfo->shared_info = 
(intel_shared_info*)malloc(sizeof(intel_shared_info));
+       if (gInfo->shared_info == NULL) {
+               fprintf(stderr, "Unable to malloc shared_info!\n");
+               free(gInfo);
+               return 2;
+       }
+
+       for (uint32 index = 0; index < (sizeof(kTestDevices) / 
sizeof(test_device));
+               index++) {
+               gInfo->shared_info->device_type = kTestDevices[index].type;
+               fprintf(stderr, "=== %s (Generation %d)\n",  
kTestDevices[index].name,
+                       gInfo->shared_info->device_type.Generation());
+
+               if 
(gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_SER5)) {
+                       printf("Is series 5\n");
+                       gInfo->shared_info->pll_info.reference_frequency = 
120000;
+                       gInfo->shared_info->pll_info.max_frequency = 350000;
+                       gInfo->shared_info->pll_info.min_frequency = 20000;
+                       gInfo->shared_info->pch_info = INTEL_PCH_CPT;
+               } else if 
(gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_9xx)) {
+                       printf("Is 9xx\n");
+                       gInfo->shared_info->pll_info.reference_frequency = 
96000;
+                       gInfo->shared_info->pll_info.max_frequency = 400000;
+                       gInfo->shared_info->pll_info.min_frequency = 20000;
+               } else {
+                       printf("Is other\n");
+                       gInfo->shared_info->pll_info.reference_frequency = 
96000;
+                       gInfo->shared_info->pll_info.max_frequency = 400000;
+                       gInfo->shared_info->pll_info.min_frequency = 20000;
+               }
+
+               pll_divisors output;
+               for (uint32 j = 0; j < 2; j++) {
+                       display_mode fakeMode;
+                       simulate_mode(&fakeMode, j);
+                       compute_pll_divisors(&fakeMode, &output, false);
+
+                       printf("%d -> %d\n", fakeMode.timing.pixel_clock,
+                               
gInfo->shared_info->pll_info.reference_frequency * output.m
+                                       / (output.n * output.p));
+               }
+       }
+
+       free(gInfo->shared_info);
+       free(gInfo);
+       return 0;
+}


Other related posts:

  • » [haiku-commits] haiku: hrev52279 - in src: add-ons/accelerants/intel_extreme tests/add-ons/accelerants/intel_extreme add-ons/kernel/drivers/graphics/intel_extreme - waddlesplash