From 3a9bb1e729dcb2c023fee74357fa14567ad168e0 Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Sat, 16 Oct 2021 21:14:35 +0000 Subject: [PATCH] intel_extreme: updated PLL restricts, updated set- and proposemode. Requested modes are now set more precise. --- .../accelerants/intel_extreme/mode.cpp | 60 ++++------------ src/add-ons/accelerants/intel_extreme/pll.cpp | 71 +++++++++---------- 2 files changed, 47 insertions(+), 84 deletions(-) diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index c0f9ae4c08..f864c5b279 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -273,42 +273,21 @@ intel_propose_display_mode(display_mode* target, const display_mode* low, { CALLED(); - // first search for the specified mode in the list, if no mode is found - // try to fix the target mode in sanitize_display_mode - // TODO: Only sanitize_display_mode should be used. However, at the moment - // the mode constraints are not optimal and do not work for all - // configurations. - uint32 VirtualWidth = target->virtual_width; - uint32 VirtualHeight = target->virtual_height; - float RefreshRate = (float)target->timing.pixel_clock / - (target->timing.h_total * target->timing.v_total); + display_mode mode = *target; - for (uint32 i = 0; i < gInfo->shared_info->mode_count; i++) { - display_mode *mode = &gInfo->mode_list[i]; - - // TODO: improve this, ie. adapt pixel clock to allowed values!!! - - if (target->timing.h_display != mode->timing.h_display - || target->timing.v_display != mode->timing.v_display - || target->space != mode->space) { - continue; - } - - *target = *mode; - // retain requested virtual size - target->virtual_width = VirtualWidth; - target->virtual_height = VirtualHeight; - // retain requested refreshrate - target->timing.pixel_clock = - target->timing.h_total * target->timing.v_total * RefreshRate; - - // (most) modeflags are outputs from us (the driver). So we should - // set them depending on the mode and the current hardware config - target->flags |= B_SCROLL; - return B_OK; + if (sanitize_display_mode(*target)) { + TRACE("Video mode was adjusted by sanitize_display_mode\n"); + TRACE("Initial mode: Hd %d Hs %d He %d Ht %d Vd %d Vs %d Ve %d Vt %d\n", + mode.timing.h_display, mode.timing.h_sync_start, + mode.timing.h_sync_end, mode.timing.h_total, + mode.timing.v_display, mode.timing.v_sync_start, + mode.timing.v_sync_end, mode.timing.v_total); + TRACE("Sanitized: Hd %d Hs %d He %d Ht %d Vd %d Vs %d Ve %d Vt %d\n", + target->timing.h_display, target->timing.h_sync_start, + target->timing.h_sync_end, target->timing.h_total, + target->timing.v_display, target->timing.v_sync_start, + target->timing.v_sync_end, target->timing.v_total); } - - sanitize_display_mode(*target); // (most) modeflags are outputs from us (the driver). So we should // set them depending on the mode and the current hardware config target->flags |= B_SCROLL; @@ -329,19 +308,6 @@ intel_set_display_mode(display_mode* mode) display_mode target = *mode; - if (sanitize_display_mode(target)) { //should be in proposemode.. - TRACE("Video mode was adjusted by sanitize_display_mode\n"); - TRACE("Initial mode: Hd %d Hs %d He %d Ht %d Vd %d Vs %d Ve %d Vt %d\n", - mode->timing.h_display, mode->timing.h_sync_start, - mode->timing.h_sync_end, mode->timing.h_total, - mode->timing.v_display, mode->timing.v_sync_start, - mode->timing.v_sync_end, mode->timing.v_total); - TRACE("Sanitized: Hd %d Hs %d He %d Ht %d Vd %d Vs %d Ve %d Vt %d\n", - target.timing.h_display, target.timing.h_sync_start, - target.timing.h_sync_end, target.timing.h_total, - target.timing.v_display, target.timing.v_sync_start, - target.timing.v_sync_end, target.timing.v_total); - } if (intel_propose_display_mode(&target, &target, &target) != B_OK) return B_BAD_VALUE; diff --git a/src/add-ons/accelerants/intel_extreme/pll.cpp b/src/add-ons/accelerants/intel_extreme/pll.cpp index 301069380e..3260009576 100644 --- a/src/add-ons/accelerants/intel_extreme/pll.cpp +++ b/src/add-ons/accelerants/intel_extreme/pll.cpp @@ -39,89 +39,86 @@ #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__) -// PLL limits, taken from programming manual when available, and from Linux KMS -// drivers otherwise. However, note that we use the values of N+2, M1+2 and -// M2+2 here, the - 2 being applied when we write the values to the registers. +// PLL limits, taken from i915 DRM driver. However, note that we use the values of +// N+2, M1+2 and M2+2 here, the - 2 being applied when we write the values to the registers. static pll_limits kLimits85x = { // p, p1, p2, n, m, m1, m2 - { 4, 2, 2, 5, 96, 20, 8}, + { 4, 2, 2, 4, 96, 20, 8}, {128, 33, 4, 18, 140, 28, 18}, - 165000, 930000, 1400000 + 165000, 908000, 1512000 }; -// TODO according to the docs, the limits for 9xx anf G45 should be the same. // For Iron Lake, a new set of timings is introduced along with the FDI system, // and carried on to later cards with just one further change (to the P2 cutoff // frequency) in Sandy Bridge. -// -// So, it makes no sense to have separate limits and algorithm for 9xx and G45. static pll_limits kLimits9xxSdvo = { // p, p1, p2, n, m, m1, m2 - { 5, 1, 5, 5, 70, 12, 7}, // min - { 80, 8, 10, 10, 120, 22, 11}, // max + { 5, 1, 5, 3, 70, 10, 5}, // min + { 80, 8, 10, 8, 120, 20, 9}, // max 200000, 1400000, 2800000 }; static pll_limits kLimits9xxLvds = { // p, p1, p2, n, m, m1, m2 - { 7, 1, 7, 1, 70, 8, 3}, // min - { 98, 8, 14, 6, 120, 18, 7}, // max + { 7, 1, 7, 3, 70, 10, 5}, // min + { 98, 8, 14, 8, 120, 20, 9}, // max 112000, 1400000, 2800000 }; -// Limits for G45 cards taken from g45_vlo3_register_0_0_0.pdf, page 46 -// Note that n here is actually n+2, but m1 and m2 are as in the datasheet. +// Limits for G45 cards taken from i915 DRM driver, mixed with old setup +// plus tests to accomodate lower resolutions with still correct refresh. +// Note that n here is actually n+2, same applies to m1 and m2. static pll_limits kLimitsG4xSdvo = { // p, p1, p2, n, m, m1, m2 - { 5, 1, 5, 5, 70, 12, 7}, // min - { 80, 8, 10, 10, 120, 22, 11}, // max - 270000, 1400000, 2800000 + { 10, 1, 10, 3, 104, 19, 7}, // min + { 80, 8, 10, 8, 138, 25, 13}, // max + 270000, 1750000, 3500000 }; #if 0 static pll_limits kLimitsG4xHdmi = { // p, p1, p2, n, m, m1, m2 - { 5, 1, 5, 5, 70, 12, 7}, // min - { 80, 8, 10, 10, 120, 22, 11}, // max - 165000, 1400000, 2800000 + { 5, 1, 5, 3, 104, 18, 7}, // min + { 80, 8, 10, 8, 138, 25, 13}, // max + 165000, 1750000, 3500000 }; #endif static pll_limits kLimitsG4xLvdsSingle = { // p, p1, p2, n, m, m1, m2 - { 7, 1, 14, 5, 70, 12, 7}, // min - { 98, 8, 14, 10, 120, 22, 11}, // max - 0, 1400000, 2800000 + { 28, 2, 14, 3, 104, 19, 7}, // min + {112, 8, 14, 8, 138, 25, 13}, // max + 0, 1750000, 3500000 }; static pll_limits kLimitsG4xLvdsDual = { // p, p1, p2, n, m, m1, m2 - { 14, 2, 7, 5, 70, 12, 7}, // min - { 42, 6, 7, 10, 120, 22, 11}, // max - 0, 1400000, 2800000 + { 14, 2, 7, 3, 104, 19, 7}, // min + { 42, 6, 7, 8, 138, 25, 13}, // max + 0, 1750000, 3500000 }; static pll_limits kLimitsIlkDac = { // p, p1, p2, n, m, m1, m2 { 5, 1, 5, 3, 79, 14, 7}, // min - { 80, 8, 10, 8, 118, 24, 11}, // max + { 80, 8, 10, 7, 127, 24, 11}, // max 225000, 1760000, 3510000 }; static pll_limits kLimitsIlkLvdsSingle = { // p, p1, p2, n, m, m1, m2 { 28, 2, 14, 3, 79, 14, 7}, // min - {112, 8, 14, 8, 118, 24, 11}, // max + {112, 8, 14, 5, 118, 24, 11}, // max 225000, 1760000, 3510000 }; static pll_limits kLimitsIlkLvdsDual = { // p, p1, p2, n, m, m1, m2 { 14, 2, 7, 3, 79, 14, 7}, // min - { 56, 8, 7, 8, 127, 24, 11}, // max + { 56, 8, 7, 5, 127, 24, 11}, // max 225000, 1760000, 3510000 }; @@ -129,14 +126,14 @@ static pll_limits kLimitsIlkLvdsDual = { static pll_limits kLimitsIlkLvdsSingle100 = { // p, p1, p2, n, m, m1, m2 { 28, 2, 14, 3, 79, 14, 7}, // min - {112, 8, 14, 8, 126, 24, 11}, // max + {112, 8, 14, 4, 126, 24, 11}, // max 225000, 1760000, 3510000 }; static pll_limits kLimitsIlkLvdsDual100 = { // p, p1, p2, n, m, m1, m2 { 14, 2, 7, 3, 79, 14, 7}, // min - { 42, 6, 7, 8, 126, 24, 11}, // max + { 42, 6, 7, 5, 126, 24, 11}, // max 225000, 1760000, 3510000 }; @@ -345,8 +342,8 @@ compute_dpll_g4x(display_mode* current, pll_divisors* divisors, bool isLVDS) continue; float error = fabs(requestedPixelClock - - ((referenceClock * divisors->m) / divisors->n) - / divisors->p); + - (referenceClock * divisors->m) + / (divisors->n * divisors->p)); if (error < best) { best = error; bestDivisors = *divisors; @@ -360,7 +357,7 @@ compute_dpll_g4x(display_mode* current, pll_divisors* divisors, bool isLVDS) } *divisors = bestDivisors; TRACE("%s: best MHz: %g (error: %g)\n", __func__, - ((referenceClock * divisors->m) / divisors->n) / divisors->p, + (referenceClock * divisors->m) / (divisors->n * divisors->p), best); } @@ -423,8 +420,8 @@ compute_dpll_9xx(display_mode* current, pll_divisors* divisors, bool isLVDS) continue; float error = fabs(requestedPixelClock - - ((referenceClock * divisors->m) / divisors->n) - / divisors->p); + - (referenceClock * divisors->m) + / (divisors->n * divisors->p)); if (error < best) { best = error; bestDivisors = *divisors; @@ -443,7 +440,7 @@ compute_dpll_9xx(display_mode* current, pll_divisors* divisors, bool isLVDS) debugger("No valid PLL configuration found"); else { TRACE("%s: best MHz: %g (error: %g)\n", __func__, - ((referenceClock * divisors->m) / divisors->n) / divisors->p, + (referenceClock * divisors->m) / (divisors->n * divisors->p), best); } }