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@pinc-software.de * Alexander von Gluck IV, kallisti5@unixzen.com - * - * 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@pulkomandy.tk */ @@ -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@pinc-software.de * Alexander von Gluck IV, kallisti5@unixzen.com + * Adrien Destugues, pulkomandy@pulkomandy.tk */ @@ -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@unixzen.com + * Adrien Destugues, pulkomandy@pulkomandy.tk + */ + +#include "accelerant_protos.h" +#include "accelerant.h" +#include "intel_extreme.h" +#include "pll.h" + +#include +#include + +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; +}