[prev in list] [next in list] [prev in thread] [next in thread]
List: haiku-commits
Subject: [haiku-commits] haiku: hrev55666 - src/add-ons/accelerants/intel_extreme headers/private/graphics/in
From: Rudolf Cornelissen <rudhaiku () gmail ! com>
Date: 2021-11-25 20:42:03
Message-ID: 20211125204203.0EE9D3F989 () turing ! freelists ! org
[Download RAW message or body]
hrev55666 adds 1 changeset to branch 'master'
old head: 4500c381d286a19b5ee1cf1196fca135c5fe1d0d
new head: 39e05c7d01484d9aed5438f0b4fef70f4f4728ff
overview: https://git.haiku-os.org/haiku/log/?qt=range&q=39e05c7d0148+%5E4500c381d286
----------------------------------------------------------------------------
39e05c7d0148: intel_extreme: skylake PLL works, all outputs fully functional.
[ Rudolf Cornelissen <rudhaiku@gmail.com> ]
----------------------------------------------------------------------------
Revision: hrev55666
Commit: 39e05c7d01484d9aed5438f0b4fef70f4f4728ff
URL: https://git.haiku-os.org/haiku/commit/?id=39e05c7d0148
Author: Rudolf Cornelissen <rudhaiku@gmail.com>
Date: Thu Nov 25 22:41:48 2021 UTC
----------------------------------------------------------------------------
6 files changed, 112 insertions(+), 28 deletions(-)
.../graphics/intel_extreme/intel_extreme.h | 9 +++
src/add-ons/accelerants/intel_extreme/Pipes.cpp | 67 +++++++++++++++++++-
src/add-ons/accelerants/intel_extreme/Pipes.h | 2 +-
src/add-ons/accelerants/intel_extreme/Ports.cpp | 16 ++---
src/add-ons/accelerants/intel_extreme/Ports.h | 9 ---
src/add-ons/accelerants/intel_extreme/pll.cpp | 37 +++++++++--
----------------------------------------------------------------------------
diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h \
b/headers/private/graphics/intel_extreme/intel_extreme.h index 71ad2b0330..c210dd4044 \
100644
--- a/headers/private/graphics/intel_extreme/intel_extreme.h
+++ b/headers/private/graphics/intel_extreme/intel_extreme.h
@@ -212,6 +212,15 @@ struct DeviceType {
}
};
+enum port_index {
+ INTEL_PORT_ANY, // wildcard for lookup functions
+ INTEL_PORT_A,
+ INTEL_PORT_B,
+ INTEL_PORT_C,
+ INTEL_PORT_D,
+ INTEL_PORT_E
+};
+
enum pch_info {
INTEL_PCH_NONE = 0, // No PCH present
INTEL_PCH_IBX, // Ibexpeak
diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp \
b/src/add-ons/accelerants/intel_extreme/Pipes.cpp index 08280b7194..e1f3b4c4a0 100644
--- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
@@ -463,10 +463,75 @@ Pipe::ConfigureClocks(const pll_divisors& divisors, uint32 \
pixelClock,
void
Pipe::ConfigureClocksSKL(const skl_wrpll_params& wrpll_params, uint32 pixelClock,
- uint32 extraFlags)
+ port_index pllForPort)
{
CALLED();
+ //find our PLL as set by the BIOS
+ uint32 portSel = read32(SKL_DPLL_CTRL2);
+ uint32 pllSel = 0;
+ switch (pllForPort) {
+ case INTEL_PORT_A:
+ pllSel = (portSel & 0x0006) >> 1;
+ break;
+ case INTEL_PORT_B:
+ pllSel = (portSel & 0x0030) >> 4;
+ break;
+ case INTEL_PORT_C:
+ pllSel = (portSel & 0x0180) >> 7;
+ break;
+ case INTEL_PORT_D:
+ pllSel = (portSel & 0x0c00) >> 10;
+ break;
+ case INTEL_PORT_E:
+ pllSel = (portSel & 0x6000) >> 13;
+ break;
+ default:
+ TRACE("No port selected!");
+ return;
+ }
+ TRACE("PLL selected is %" B_PRIx32 "\n", pllSel);
+
+ TRACE("Skylake DPLL_CFGCR1 0x%" B_PRIx32 "\n",
+ read32(SKL_DPLL1_CFGCR1 + (pllSel - 1) * 8));
+ TRACE("Skylake DPLL_CFGCR2 0x%" B_PRIx32 "\n",
+ read32(SKL_DPLL1_CFGCR2 + (pllSel - 1) * 8));
+
+ // only program PLL's that are in non-DP mode (otherwise the linkspeed sets \
refresh) + portSel = read32(SKL_DPLL_CTRL1);
+ if ((portSel & (1 << (pllSel * 6 + 5))) && pllSel) { // DPLL0 might only know DP \
mode + // enable pgm on our PLL in case that's currently disabled
+ write32(SKL_DPLL_CTRL1, portSel | (1 << (pllSel * 6)));
+
+ write32(SKL_DPLL1_CFGCR1 + (pllSel - 1) * 8,
+ 1 << 31 |
+ wrpll_params.dco_fraction << 9 |
+ wrpll_params.dco_integer);
+ write32(SKL_DPLL1_CFGCR2 + (pllSel - 1) * 8,
+ wrpll_params.qdiv_ratio << 8 |
+ wrpll_params.qdiv_mode << 7 |
+ wrpll_params.kdiv << 5 |
+ wrpll_params.pdiv << 2 |
+ wrpll_params.central_freq);
+ read32(SKL_DPLL1_CFGCR1 + (pllSel - 1) * 8);
+ read32(SKL_DPLL1_CFGCR2 + (pllSel - 1) * 8);
+
+ //assuming DPLL0 and 1 are already enabled by the BIOS if in use (LCPLL1,2 regs)
+
+ spin(5);
+ if (read32(SKL_DPLL_STATUS) & (1 << (pllSel * 8))) {
+ TRACE("Programmed PLL; PLL is locked\n");
+ } else {
+ TRACE("Programmed PLL; PLL did not lock\n");
+ }
+ TRACE("Skylake DPLL_CFGCR1 now: 0x%" B_PRIx32 "\n",
+ read32(SKL_DPLL1_CFGCR1 + (pllSel - 1) * 8));
+ TRACE("Skylake DPLL_CFGCR2 now: 0x%" B_PRIx32 "\n",
+ read32(SKL_DPLL1_CFGCR2 + (pllSel - 1) * 8));
+ } else {
+ TRACE("PLL programming not needed, skipping.\n");
+ }
+
TRACE("Skylake DPLL_CTRL1: 0x%" B_PRIx32 "\n", read32(SKL_DPLL_CTRL1));
TRACE("Skylake DPLL_CTRL2: 0x%" B_PRIx32 "\n", read32(SKL_DPLL_CTRL2));
TRACE("Skylake DPLL_STATUS: 0x%" B_PRIx32 "\n", read32(SKL_DPLL_STATUS));
diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.h \
b/src/add-ons/accelerants/intel_extreme/Pipes.h index fcf160b08f..1c69805c4e 100644
--- a/src/add-ons/accelerants/intel_extreme/Pipes.h
+++ b/src/add-ons/accelerants/intel_extreme/Pipes.h
@@ -50,7 +50,7 @@ public:
void ConfigureClocksSKL(
const skl_wrpll_params& wrpll_params,
uint32 pixelClock,
- uint32 extraFlags);
+ port_index pllForPort);
// access to the various parts of the pipe
::FDILink* FDI()
diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp \
b/src/add-ons/accelerants/intel_extreme/Ports.cpp index f09b8f5531..1124b019c1 100644
--- a/src/add-ons/accelerants/intel_extreme/Ports.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp
@@ -1527,16 +1527,6 @@ DigitalDisplayInterface::SetDisplayMode(display_mode* target, \
uint32 colorMode) // Program general pipe config
fPipe->Configure(target);
- //pll_divisors divisors;
- //compute_pll_divisors(&target->timing, &divisors, false);
-
- //uint32 extraPLLFlags = 0;
- //if (gInfo->shared_info->device_type.Generation() >= 3)
- // extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL | DISPLAY_PLL_2X_CLOCK;
-
- // Program pipe PLL's
- //fPipe->ConfigureClocks(divisors, target->timing.pixel_clock, extraPLLFlags);
-
if (gInfo->shared_info->device_type.Generation() <= 8) {
unsigned int r2_out, n2_out, p_out;
hsw_ddi_calculate_wrpll(
@@ -1546,9 +1536,11 @@ DigitalDisplayInterface::SetDisplayMode(display_mode* target, \
uint32 colorMode) skl_wrpll_params wrpll_params;
skl_ddi_calculate_wrpll(
target->timing.pixel_clock * 1000 /* in Hz */,
- gInfo->shared_info->pll_info.reference_frequency,//fixme Hz? kHz?
+ 24000,//gInfo->shared_info->pll_info.reference_frequency, //fixme
&wrpll_params);
- fPipe->ConfigureClocksSKL(wrpll_params, target->timing.pixel_clock, 0);
+ fPipe->ConfigureClocksSKL(wrpll_params,
+ target->timing.pixel_clock,
+ PortIndex());
}
// Program target display mode
diff --git a/src/add-ons/accelerants/intel_extreme/Ports.h \
b/src/add-ons/accelerants/intel_extreme/Ports.h index e69beaf6eb..de4ac1eb1d 100644
--- a/src/add-ons/accelerants/intel_extreme/Ports.h
+++ b/src/add-ons/accelerants/intel_extreme/Ports.h
@@ -32,15 +32,6 @@ enum port_type {
INTEL_PORT_TYPE_HDMI
};
-enum port_index {
- INTEL_PORT_ANY, // wildcard for lookup functions
- INTEL_PORT_A,
- INTEL_PORT_B,
- INTEL_PORT_C,
- INTEL_PORT_D,
- INTEL_PORT_E
-};
-
class Port {
public:
diff --git a/src/add-ons/accelerants/intel_extreme/pll.cpp \
b/src/add-ons/accelerants/intel_extreme/pll.cpp index ed765b6da7..a04e8e4d15 100644
--- a/src/add-ons/accelerants/intel_extreme/pll.cpp
+++ b/src/add-ons/accelerants/intel_extreme/pll.cpp
@@ -591,6 +591,15 @@ refclk_activate_ilk(bool hasPanel)
#define VCO_MIN 2400
#define VCO_MAX 4800
+static uint64 AbsSubtr64(uint64 nr1, uint64 nr2)
+{
+ if (nr1 >= nr2) {
+ return nr1 - nr2;
+ } else {
+ return nr2 - nr1;
+ }
+}
+
struct hsw_wrpll_rnp {
unsigned p, n2, r2;
};
@@ -700,8 +709,8 @@ static void hsw_wrpll_update_rnp(uint64 freq2k, unsigned int \
budget,
*/
a = freq2k * budget * p * r2;
b = freq2k * budget * best->p * best->r2;
- diff = labs((uint64)freq2k * p * r2 - LC_FREQ_2K * n2);
- diff_best = labs((uint64)freq2k * best->p * best->r2 -
+ diff = AbsSubtr64((uint64)freq2k * p * r2, LC_FREQ_2K * n2);
+ diff_best = AbsSubtr64((uint64)freq2k * best->p * best->r2,
LC_FREQ_2K * best->n2);
c = 1000000 * diff;
d = 1000000 * diff_best;
@@ -812,8 +821,8 @@ static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
{
uint64 deviation;
- deviation = ((uint64)10000 * labs(dco_freq - central_freq)
- / (uint64)central_freq);
+ deviation = ((uint64)10000 * AbsSubtr64(dco_freq, central_freq)
+ / central_freq);
/* positive deviation */
if (dco_freq >= central_freq) {
@@ -823,6 +832,11 @@ static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
ctx->central_freq = central_freq;
ctx->dco_freq = dco_freq;
ctx->p = divider;
+
+ TRACE("%s: DCO central frequency %" B_PRIu64 "Hz\n", __func__, central_freq);
+ TRACE("%s: DCO frequency %" B_PRIu64 "Hz\n", __func__, dco_freq);
+ TRACE("%s: positive offset accepted, deviation %" B_PRIu64 "\n",
+ __func__, deviation);
}
/* negative deviation */
} else if (deviation < SKL_DCO_MAX_NDEVIATION &&
@@ -831,6 +845,11 @@ static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
ctx->central_freq = central_freq;
ctx->dco_freq = dco_freq;
ctx->p = divider;
+
+ TRACE("%s: DCO central frequency %" B_PRIu64 "Hz\n", __func__, central_freq);
+ TRACE("%s: DCO frequency %" B_PRIu64 "Hz\n", __func__, dco_freq);
+ TRACE("%s: negative offset accepted, deviation %" B_PRIu64 "\n",
+ __func__, deviation);
}
}
@@ -946,6 +965,10 @@ static void skl_wrpll_params_populate(struct skl_wrpll_params \
*params, params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
dco_freq = p0 * p1 * p2 * afe_clock;
+ TRACE("%s: AFE frequency %" B_PRIu64 "Hz\n", __func__, afe_clock);
+ TRACE("%s: p0: %" B_PRIu32 ", p1: %" B_PRIu32 ", p2: %" B_PRIu32 "\n",
+ __func__, p0,p1,p2);
+ TRACE("%s: DCO frequency %" B_PRIu64 "Hz\n", __func__, dco_freq);
/*
* Intermediate values are in Hz.
@@ -954,8 +977,11 @@ static void skl_wrpll_params_populate(struct skl_wrpll_params \
*params, params->dco_integer = (uint64)dco_freq / ((uint64)ref_clock * 1000);
params->dco_fraction = (
(uint64)dco_freq / ((uint64)ref_clock / 1000) -
- (uint64)params->dco_integer * 1000000 * 0x8000) /
+ (uint64)params->dco_integer * 1000000) * 0x8000 /
1000000;
+
+ TRACE("%s: DCO integer %" B_PRIu32 "\n", __func__, params->dco_integer);
+ TRACE("%s: DCO fraction 0x%" B_PRIx32 "\n", __func__, params->dco_fraction);
}
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -1021,6 +1047,7 @@ skip_remaining_dividers:
TRACE("%s: No valid divider found for %dHz\n", __func__, clock);
return false;
}
+ TRACE("%s: Full devider (p) found is %d\n", __func__, ctx.p);
/*
* gcc incorrectly analyses that these can be used without being
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic