intel_extreme: updated PLL restricts, updated set- and proposemode. Requested modes are now set more precise.

This commit is contained in:
Rudolf Cornelissen 2021-10-16 21:14:35 +00:00
parent 6846668fd7
commit 3a9bb1e729
2 changed files with 47 additions and 84 deletions

View File

@ -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;

View File

@ -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);
}
}