From 84f7eb85cc7b5ed9c1a31c4eaaab8edebac9b4ad Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 14 Sep 2022 10:39:17 +0200 Subject: Fix TMDS clock limiting if DTD info is missing (Default to 165MHz) --- src/xprivate.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/xprivate.cpp b/src/xprivate.cpp index afdf32d..3aea9b5 100644 --- a/src/xprivate.cpp +++ b/src/xprivate.cpp @@ -47,15 +47,14 @@ static int modeEqual(const XRRModeInfo *a, const XRRModeInfo *b) { return (a->width == b->width && a->height == b->height && - a->dotClock / 10 == b->dotClock / 10 && + a->dotClock / 100 == b->dotClock / 100 && a->hSyncStart == b->hSyncStart && a->hSyncEnd == b->hSyncEnd && a->hTotal == b->hTotal && a->hSkew == b->hSkew && a->vSyncStart == b->vSyncStart && a->vSyncEnd == b->vSyncEnd && - a->vTotal == b->vTotal && - a->modeFlags == b->modeFlags); + a->vTotal == b->vTotal); } static int errorHandler(Display *dpy, XErrorEvent *err) @@ -291,6 +290,9 @@ void XPrivate::addMissingEdidResolutions() if (maxClock != 0) break; } + if (maxClock <= 0) { + maxClock = 165; + } qDebug() << "Standard block DTD for output" << resptr->outputs[i] << "aka" << _outputMap[resptr->outputs[i]]->outputName << "MaxClock" << maxClock << "MHz"; for (unsigned int j = 54; j < 125; j+= 18) { @@ -434,12 +436,7 @@ void XPrivate::addMissingModesFromDtd(XRRScreenResources *res, RROutput outputId m.vSyncEnd = static_cast(vactive + vsyncoff + vsyncwidth); m.vTotal = static_cast(vactive + vblank); m.id = 0; - m.name = buf; - refresh = static_cast(m.dotClock / (m.hTotal * m.vTotal)); - m.nameLength = static_cast(snprintf(buf, sizeof(buf), "%dx%d_%d", hactive, vactive, refresh)); - if (m.nameLength > sizeof(buf)) { - m.nameLength = sizeof(buf); - } + // m.name gets set after we potentially limit the Hz down below if ((data[17] & 0x18) == 0x18) { // Digital Separate if (data[17] & 0x04) { @@ -467,13 +464,8 @@ void XPrivate::addMissingModesFromDtd(XRRScreenResources *res, RROutput outputId m.modeFlags |= RR_Interlace; } RRMode modeId = 0; - // More special case B/S: So, X11 mysteriously ignores a couple of resolutions, sometimes. - // Curiously, this happens with a Philips TV, but not an LG TV. EDID dump looks very similar - // on both. More curiously, in Xorg.log, the first time the modelines for the Philips TV get dumped, - // the 4k resolution is missing, even though it's in the EDID dump from right before those lines. - // Then the xserver logs the modelines for the Philips TV a couple more times, and every time the 4k - // resolution is in the list. Just not the first time. However, the resolutions never get added to - // the TV. + // Kernel might have wrongly identified a DP++ adapter as type 1, limiting TMDS to 165MHz, we ignore this and + // hope for the best. if (m.dotClock > maxClockMhz * 1000000) { for (int mode = 0; mode < res->nmode; ++mode) { if (res->modes[mode].width == m.width && res->modes[mode].height == m.height && res->modes[mode].dotClock <= maxClockMhz * 1000000) { @@ -494,6 +486,13 @@ void XPrivate::addMissingModesFromDtd(XRRScreenResources *res, RROutput outputId qDebug() << "Capping to" << refresh << "Hz, " << (m.dotClock / 1000000) << "MHz"; } } + // Now set name + m.name = buf; + refresh = static_cast(m.dotClock / (m.hTotal * m.vTotal)); + m.nameLength = static_cast(snprintf(buf, sizeof(buf), "%dx%d_%d", hactive, vactive, refresh)); + if (m.nameLength > sizeof(buf)) { + m.nameLength = sizeof(buf); + } // See if we should add this mode if (modeId == 0) { for (int mode = 0; mode < res->nmode; ++mode) { @@ -505,13 +504,13 @@ void XPrivate::addMissingModesFromDtd(XRRScreenResources *res, RROutput outputId } } if (modeId == 0) { - qDebug() << "Creating" << m.name << "for output" << outputId << m.width << "x" << m.height << "@" << (m.dotClock / 1000000); + qDebug() << "Creating" << m.name << "for output" << outputId << m.width << "x" << m.height << "@" << (m.dotClock / 1000000) << "MHz"; qDebug() << m.hSyncStart << m.hSyncEnd << m.hTotal; qDebug() << m.vSyncStart << m.vSyncEnd << m.vTotal; modeId = XRRCreateMode(_display, DefaultRootWindow(_display), &m); } if (modeId != 0) { - qDebug() << "Adding mode for output" << outputId << m.width << "x" << m.height << "@" << (m.dotClock / 1000000); + qDebug() << "Adding mode for output" << outputId << m.width << "x" << m.height << "@" << (m.dotClock / 1000000) << "MHz"; XRRAddOutputMode(_display, outputId, modeId); } else { qDebug() << "Failed to add" << buf << "to" << outputId << "- mode not found/created"; -- cgit v1.2.3-55-g7522