hrev50303 adds 2 changesets to branch 'master'
old head: 95e38537e0e9a86f28e4c39aed6df55e4fb55fd1
new head: a32e8156730975d66634c655655fdf68b56660fc
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=a32e81567309+%5E95e38537e0e9
----------------------------------------------------------------------------
9407ab29c429: intel_extreme: Rework PLL calculation
* More like linux, improved G4x calculations
* Reduce un-needed pll limit complexity
* Improved pll limits on ports based on type
a32e81567309: intel_extreme: Shorten graphics family names
[ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
5 files changed, 331 insertions(+), 171 deletions(-)
src/add-ons/accelerants/intel_extreme/Pipes.cpp | 19 +-
src/add-ons/accelerants/intel_extreme/Ports.cpp | 2 +-
.../accelerants/intel_extreme/accelerant.cpp | 18 +-
src/add-ons/accelerants/intel_extreme/pll.cpp | 453 +++++++++++++------
src/add-ons/accelerants/intel_extreme/pll.h | 10 +-
############################################################################
Commit: 9407ab29c4297af831ac9e6b80768af10fe8a5f4
URL: http://cgit.haiku-os.org/haiku/commit/?id=9407ab29c429
Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date: Tue May 10 04:12:03 2016 UTC
intel_extreme: Rework PLL calculation
* More like linux, improved G4x calculations
* Reduce un-needed pll limit complexity
* Improved pll limits on ports based on type
----------------------------------------------------------------------------
diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp
b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
index 8f272e7..2848d0a 100644
--- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp
@@ -239,7 +239,7 @@ Pipe::ConfigureClocks(const pll_divisors& divisors, uint32
pixelClock,
float refFreq = gInfo->shared_info->pll_info.reference_frequency /
1000.0f;
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_96x)) {
- float adjusted = ((refFreq * divisors.m) / divisors.n) /
divisors.post;
+ float adjusted = ((refFreq * divisors.m) / divisors.n) /
divisors.p;
uint32 pixelMultiply = uint32(adjusted / (pixelClock /
1000.0f));
write32(pllMD, (0 << 24) | ((pixelMultiply - 1) << 8));
}
@@ -273,34 +273,33 @@ Pipe::ConfigureClocks(const pll_divisors& divisors,
uint32 pixelClock,
uint32 pll = DISPLAY_PLL_ENABLED | DISPLAY_PLL_NO_VGA_CONTROL |
extraFlags;
if (gInfo->shared_info->device_type.Generation() >= 3) {
- // post1 divisor << 1 , 1-8
+ // p1 divisor << 1 , 1-8
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
- pll |= ((1 << (divisors.post1 - 1))
+ pll |= ((1 << (divisors.p1 - 1))
<< DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT)
& DISPLAY_PLL_IGD_POST1_DIVISOR_MASK;
} else {
- pll |= ((1 << (divisors.post1 - 1))
+ pll |= ((1 << (divisors.p1 - 1))
<< DISPLAY_PLL_POST1_DIVISOR_SHIFT)
& DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
- // pll |= ((divisors.post1 - 1) <<
DISPLAY_PLL_POST1_DIVISOR_SHIFT)
+ // pll |= ((divisors.p1 - 1) <<
DISPLAY_PLL_POST1_DIVISOR_SHIFT)
// & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
}
- // p2 clock divider. 5 or 7 high
- if (divisors.post2_high)
+ if (divisors.p2 == 5 || divisors.p2 == 7)
pll |= DISPLAY_PLL_DIVIDE_HIGH;
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_96x))
pll |= 6 << DISPLAY_PLL_PULSE_PHASE_SHIFT;
} else {
- if (!divisors.post2_high)
+ if (divisors.p2 != 5 && divisors.p2 != 7)
pll |= DISPLAY_PLL_DIVIDE_4X;
pll |= DISPLAY_PLL_2X_CLOCK;
// TODO: Is this supposed to be
DISPLAY_PLL_IGD_POST1_DIVISOR_MASK??
- if (divisors.post1 > 2) {
- pll |= ((divisors.post1 - 2) <<
DISPLAY_PLL_POST1_DIVISOR_SHIFT)
+ if (divisors.p1 > 2) {
+ pll |= ((divisors.p1 - 2) <<
DISPLAY_PLL_POST1_DIVISOR_SHIFT)
& DISPLAY_PLL_POST1_DIVISOR_MASK;
} else
pll |= DISPLAY_PLL_POST1_DIVIDE_2;
diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp
b/src/add-ons/accelerants/intel_extreme/Ports.cpp
index 7b91200..14e707d 100644
--- a/src/add-ons/accelerants/intel_extreme/Ports.cpp
+++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp
@@ -506,7 +506,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32
colorMode)
// Set the B0-B3 data pairs corresponding to whether we're going to
// set the DPLLs for dual-channel mode or not.
- if (divisors.post2_high) {
+ if (divisors.p2 == 5 || divisors.p2 == 7) {
TRACE("LVDS: dual channel\n");
lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
} else {
diff --git a/src/add-ons/accelerants/intel_extreme/pll.cpp
b/src/add-ons/accelerants/intel_extreme/pll.cpp
index f6126d7..826bcb0 100644
--- a/src/add-ons/accelerants/intel_extreme/pll.cpp
+++ b/src/add-ons/accelerants/intel_extreme/pll.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
+ * Copyright 2006-2016, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -38,117 +38,146 @@
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
-void
-get_pll_limits(pll_limits* limits, bool isLVDS)
+// 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
+ 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
+ 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
+ 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
+ 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
+ 225000, 1760000, 3510000
+};
+
+#if 0
+static pll_limits kLimitsChv = {
+ // p, p1, p2, n, m, m1, m2
+ { 0, 2, 14, 1, 79, 2, 24 << 22}, // min
+ { 0, 4, 1, 1, 127, 2, 175 << 22}, // max
+ 0, 4800000, 6480000
+};
+
+static pll_limits kLimitsVlv = {
+ // p, p1, p2, n, m, m1, m2
+ { 0, 2, 20, 1, 79, 2, 11}, // min
+ { 0, 3, 2, 7, 127, 3, 156}, // max
+ 0, 4000000, 6000000
+};
+
+static pll_limits kLimitsBxt = {
+ // p, p1, p2, n, m, m1, m2
+ { 0, 2, 1, 1, 0, 2, 2 << 22}, // min
+ { 0, 4, 20, 1, 0, 2, 255 << 22}, // max
+ 0, 4800000, 6700000
+};
+#endif
+
+static pll_limits kLimits9xxSdvo = {
+ // p, p1, p2, n, m, m1, m2
+ { 5, 1, 10, 5, 70, 12, 7}, // min
+ { 80, 8, 5, 10, 120, 22, 11}, // max
+ 200000, 1400000, 2800000
+};
+
+static pll_limits kLimits9xxLvds = {
+ // p, p1, p2, n, m, m1, m2
+ { 7, 1, 14, 1, 70, 8, 3}, // min
+ { 98, 8, 7, 6, 120, 18, 7}, // max
+ 112000, 1400000, 2800000
+};
+
+static pll_limits kLimitsG4xSdvo = {
+ // p, p1, p2, n, m, m1, m2
+ { 10, 1, 10, 1, 104, 17, 5}, // min
+ { 30, 3, 10, 4, 138, 23, 11}, // max
+ 270000, 1750000, 3500000
+};
+
+#if 0
+static pll_limits kLimitsG4xHdmi = {
+ // p, p1, p2, n, m, m1, m2
+ { 5, 1, 10, 1, 104, 16, 5}, // min
+ { 80, 8, 5, 4, 138, 23, 11}, // max
+ 165000, 1750000, 3500000
+};
+#endif
+
+static pll_limits kLimitsG4xLvdsSingle = {
+ // p, p1, p2, n, m, m1, m2
+ { 28, 2, 14, 1, 104, 17, 5}, // min
+ { 112, 8, 14, 3, 138, 23, 11}, // max
+ 0, 1750000, 3500000
+};
+
+static pll_limits kLimitsG4xLvdsDual = {
+ // p, p1, p2, n, m, m1, m2
+ { 14, 2, 7, 1, 104, 17, 5}, // min
+ { 42, 6, 7, 3, 138, 23, 11}, // max
+ 0, 1750000, 3500000
+};
+
+static pll_limits kLimitsPinSdvo = {
+ // p, p1, p2, n, m, m1, m2
+ { 5, 1, 10, 3, 2, 0, 0}, // min
+ { 80, 8, 5, 6, 256, 0, 254}, // max
+ 200000, 1700000, 3500000
+};
+
+static pll_limits kLimitsPinLvds = {
+ // p, p1, p2, n, m, m1, m2
+ { 7, 1, 14, 3, 2, 0, 0}, // min
+ {112, 8, 14, 6, 256, 0, 254}, // max
+ 112000, 1700000, 3500000
+};
+
+#if 0
+static pll_limits kLimits = {
+ // p, p1, p2, n, m, m1, m2
+ { 4, 2, 4, 5, 96, 20, 8},
+ {128, 33, 2, 18, 140, 28, 18},
+ 165000, 930000, 1400000
+};
+#endif
+
+
+static bool
+lvds_dual_link(display_mode* current)
{
- // Note, the limits are taken from the X driver; they have not yet been
- // tested
-
- // TODO: Breakout BXT
-
- if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) {
- pll_limits kLimits = {
- // p, p1, p2, high, n, m, m1, m2
- { 5, 2, 14, false, 1, 79, 2, 24 << 22}, // min
- { 80, 4, 1, true, 1, 127, 2, 175 << 22}, // max
- 225000, 4800000, 6480000
- };
- memcpy(limits, &kLimits, sizeof(pll_limits));
- } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) {
- pll_limits kLimits = {
- // p, p1, p2, high, n, m, m1, m2
- { 5, 2, 20, false, 1, 79, 2, 11}, // min
- { 80, 3, 2, true, 7, 127, 3, 156}, // max
- 225000, 4000000, 6000000
- };
- memcpy(limits, &kLimits, sizeof(pll_limits));
- } else if (gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_SER5)
- || gInfo->shared_info->device_type.InGroup(INTEL_GROUP_BXT)) {
- pll_limits kLimits = {
- // p, p1, p2, high, n, m, m1, m2
- { 5, 1, 10, false, 1, 79, 12, 5}, // min
- { 80, 8, 5, true, 5, 127, 22, 9}, // max
- 225000, 1760000, 3510000
- };
- // TODO: validate these LVDS dividers!
- if (isLVDS) {
- kLimits.min.post = 7;
- kLimits.max.post = 98;
- kLimits.min.post2 = 14;
- kLimits.max.post2 = 7;
- }
- memcpy(limits, &kLimits, sizeof(pll_limits));
- } else if (gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_9xx)) {
- pll_limits kLimits = {
- // p, p1, p2, high, n, m, m1, m2
- { 5, 1, 10, false, 1, 70, 8, 3}, // min
- { 80, 8, 5, true, 6, 120, 18, 7}, // max
- 200000, 1400000, 2800000
- };
- if (isLVDS) {
- kLimits.min.post = 7;
- kLimits.max.post = 98;
- kLimits.min.post2 = 14;
- kLimits.max.post2 = 7;
- }
- memcpy(limits, &kLimits, sizeof(pll_limits));
- } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_G4x)) {
- pll_limits kLimits = {
- // p, p1, p2, high, n, m, m1, m2
- { 10, 1, 10, false, 1, 104, 17, 5}, // min
- { 30, 3, 10, true, 4, 138, 23, 11}, // max
- 270000, 1750000, 3500000
- };
- // TODO: validate these LVDS dividers!
- if (isLVDS) {
- kLimits.min.post = 7;
- kLimits.max.post = 98;
- kLimits.min.post2 = 14;
- kLimits.max.post2 = 7;
- }
- memcpy(limits, &kLimits, sizeof(pll_limits));
- } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
- // m1 is reserved and must be 0
- pll_limits kLimits = {
- // p, p1, p2, high, n, m, m1, m2
- { 5, 1, 10, false, 3, 2, 0, 2}, // min
- { 80, 8, 5, true, 6, 256, 0, 254}, // max
- 200000, 1700000, 3500000
- };
- if (isLVDS) {
- kLimits.min.post = 7;
- kLimits.max.post = 112;
- kLimits.min.post2 = 14;
- kLimits.max.post2 = 14;
- }
- memcpy(limits, &kLimits, sizeof(pll_limits));
- } else {
- static pll_limits kLimits = {
- // p, p1, p2, high, n, m, m1, m2
- { 4, 2, 4, false, 5, 96, 20, 8},
- {128, 33, 2, true, 18, 140, 28, 18},
- 165000, 930000, 1400000
- };
- // TODO: Validate these LVDS dividers!
- if (isLVDS) {
- kLimits.min.post = 7;
- kLimits.max.post = 98;
- kLimits.min.post2 = 14;
- kLimits.max.post2 = 7;
- }
- memcpy(limits, &kLimits, sizeof(pll_limits));
- }
+ float requestedPixelClock = current->timing.pixel_clock / 1000.0f;
+ if (requestedPixelClock > 112.999)
+ return true;
- TRACE("PLL limits, min: p %" B_PRId32 " (p1 %" B_PRId32 ", "
- "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
- "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits->min.post,
- limits->min.post1, limits->min.post2, limits->min.n,
limits->min.m,
- limits->min.m1, limits->min.m2);
- TRACE("PLL limits, max: p %" B_PRId32 " (p1 %" B_PRId32 ", "
- "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
- "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits->max.post,
- limits->max.post1, limits->max.post2, limits->max.n,
limits->max.m,
- limits->max.m1, limits->max.m2);
+ // TODO: Force dual link on MacBookPro6,2 MacBookPro8,2 MacBookPro9,1
+
+ return ((read32(INTEL_DIGITAL_LVDS_PORT) & LVDS_CLKB_POWER_MASK)
+ == LVDS_CLKB_POWER_UP);
}
@@ -157,9 +186,9 @@ valid_pll_divisors(pll_divisors* divisors, pll_limits*
limits)
{
pll_info &info = gInfo->shared_info->pll_info;
uint32 vco = info.reference_frequency * divisors->m / divisors->n;
- uint32 frequency = vco / divisors->post;
+ uint32 frequency = vco / divisors->p;
- if (divisors->post < limits->min.post || divisors->post >
limits->max.post
+ if (divisors->p < limits->min.p || divisors->p > limits->max.p
|| divisors->m < limits->min.m || divisors->m > limits->max.m
|| vco < limits->min_vco || vco > limits->max_vco
|| frequency < info.min_frequency || frequency >
info.max_frequency)
@@ -169,6 +198,30 @@ valid_pll_divisors(pll_divisors* divisors, pll_limits*
limits)
}
+static void
+compute_pll_p2(display_mode* current, pll_divisors* divisors,
+ pll_limits* limits, bool isLVDS)
+{
+ if (isLVDS) {
+ if (lvds_dual_link(current)) {
+ // fast DAC timing via 2 channels (dual link LVDS)
+ divisors->p2 = limits->max.p2;
+ } else {
+ // slow DAC timing
+ divisors->p2 = limits->min.p2;
+ }
+ } else {
+ if (current->timing.pixel_clock < limits->dot_limit) {
+ // slow DAC timing
+ divisors->p2 = limits->min.p2;
+ } else {
+ // fast DAC timing
+ divisors->p2 = limits->max.p2;
+ }
+ }
+}
+
+
static uint32
compute_pll_m(pll_divisors* divisors)
{
@@ -194,68 +247,160 @@ compute_pll_m(pll_divisors* divisors)
static uint32
compute_pll_p(pll_divisors* divisors)
{
- return divisors->post1 * divisors->post2;
+ return divisors->p1 * divisors->p2;
}
-void
-compute_pll_divisors(display_mode* current, pll_divisors* divisors,
- bool isLVDS)
+static void
+compute_dpll_g4x(display_mode* current, pll_divisors* divisors, bool isLVDS)
{
float requestedPixelClock = current->timing.pixel_clock / 1000.0f;
float referenceClock
= gInfo->shared_info->pll_info.reference_frequency / 1000.0f;
- pll_limits limits;
- get_pll_limits(&limits, isLVDS);
TRACE("%s: required MHz: %g\n", __func__, requestedPixelClock);
- // Calculate p2
- if (isLVDS) {
- if (requestedPixelClock > 112.999
- || (read32(INTEL_DIGITAL_LVDS_PORT) &
LVDS_CLKB_POWER_MASK)
- == LVDS_CLKB_POWER_UP) {
- // fast DAC timing via 2 channels
- divisors->post2 = limits.max.post2;
- divisors->post2_high = limits.max.post2_high;
- } else {
- // slow DAC timing
- divisors->post2 = limits.min.post2;
- divisors->post2_high = limits.min.post2_high;
- }
+ pll_limits limits;
+ if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_G4x)) {
+ // TODO: Pass port type via video_configuration
+ if (isLVDS) {
+ if (lvds_dual_link(current))
+ memcpy(&limits, &kLimitsG4xLvdsDual,
sizeof(pll_limits));
+ else
+ memcpy(&limits, &kLimitsG4xLvdsSingle,
sizeof(pll_limits));
+ //} else if (type == INTEL_PORT_TYPE_HDMI) {
+ // memcpy(&limits, &kLimitsG4xHdmi, sizeof(pll_limits));
+ } else
+ memcpy(&limits, &kLimitsG4xSdvo, sizeof(pll_limits));
} else {
- if (current->timing.pixel_clock < limits.min_post2_frequency) {
- // slow DAC timing
- divisors->post2 = limits.min.post2;
- divisors->post2_high = limits.min.post2_high;
+ if (isLVDS) {
+ if (lvds_dual_link(current)) {
+ if (referenceClock == 100.0)
+ memcpy(&limits, &kLimitsIlkLvdsDual100,
sizeof(pll_limits));
+ else
+ memcpy(&limits, &kLimitsIlkLvdsDual,
sizeof(pll_limits));
+ } else {
+ if (referenceClock == 100.0) {
+ memcpy(&limits,
&kLimitsIlkLvdsSingle100,
+ sizeof(pll_limits));
+ } else {
+ memcpy(&limits, &kLimitsIlkLvdsSingle,
sizeof(pll_limits));
+ }
+ }
} else {
- // fast DAC timing
- divisors->post2 = limits.max.post2;
- divisors->post2_high = limits.max.post2_high;
+ memcpy(&limits, &kLimitsIlkDac, sizeof(pll_limits));
}
}
+ compute_pll_p2(current, divisors, &limits, isLVDS);
+
+ TRACE("PLL limits, min: p %" B_PRId32 " (p1 %" B_PRId32 ", "
+ "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
+ "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits.min.p,
+ limits.min.p1, limits.min.p2, limits.min.n, limits.min.m,
+ limits.min.m1, limits.min.m2);
+ TRACE("PLL limits, max: p %" B_PRId32 " (p1 %" B_PRId32 ", "
+ "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
+ "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits.max.p,
+ limits.max.p1, limits.max.p2, limits.max.n, limits.max.m,
+ limits.max.m1, limits.max.m2);
+
float best = requestedPixelClock;
pll_divisors bestDivisors;
+ uint32 maxn = limits.max.n;
+ for (divisors->n = limits.min.n; divisors->n <= maxn; 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;
+ divisors->m2--) {
+ for (divisors->p1 = limits.max.p1;
+ divisors->p1 >= limits.max.p1;
divisors->p1--) {
+ divisors->m = compute_pll_m(divisors);
+ divisors->p = compute_pll_p(divisors);
+
+ if (!valid_pll_divisors(divisors,
&limits))
+ continue;
+
+ float error = fabs(requestedPixelClock
+ - ((referenceClock *
divisors->m) / divisors->n)
+ / divisors->p);
+ if (error < best) {
+ best = error;
+ bestDivisors = *divisors;
+ maxn = divisors->n;
+
+ if (error == 0)
+ break;
+ }
+ }
+ }
+ }
+ }
+ *divisors = bestDivisors;
+ TRACE("%s: best MHz: %g (error: %g)\n", __func__,
+ ((referenceClock * divisors->m) / divisors->n) / divisors->p,
+ best);
+}
+
+
+static void
+compute_dpll_9xx(display_mode* current, pll_divisors* divisors, bool isLVDS)
+{
+ float requestedPixelClock = current->timing.pixel_clock / 1000.0f;
+ float referenceClock
+ = gInfo->shared_info->pll_info.reference_frequency / 1000.0f;
+
+ TRACE("%s: required MHz: %g\n", __func__, requestedPixelClock);
+
+ pll_limits limits;
+ if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
+ if (isLVDS)
+ memcpy(&limits, &kLimitsPinLvds, sizeof(pll_limits));
+ else
+ memcpy(&limits, &kLimitsPinSdvo, sizeof(pll_limits));
+ } else {
+ if (isLVDS)
+ memcpy(&limits, &kLimits9xxLvds, sizeof(pll_limits));
+ else
+ memcpy(&limits, &kLimits9xxSdvo, sizeof(pll_limits));
+ }
+
+ compute_pll_p2(current, divisors, &limits, isLVDS);
+
+ TRACE("PLL limits, min: p %" B_PRId32 " (p1 %" B_PRId32 ", "
+ "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
+ "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits.min.p,
+ limits.min.p1, limits.min.p2, limits.min.n, limits.min.m,
+ limits.min.m1, limits.min.m2);
+ TRACE("PLL limits, max: p %" B_PRId32 " (p1 %" B_PRId32 ", "
+ "p2 %" B_PRId32 "), n %" B_PRId32 ", m %" B_PRId32 " "
+ "(m1 %" B_PRId32 ", m2 %" B_PRId32 ")\n", limits.max.p,
+ limits.max.p1, limits.max.p2, limits.max.n, limits.max.m,
+ limits.max.m1, limits.max.m2);
+
bool is_pine = gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN);
+
+ float best = requestedPixelClock;
+ pll_divisors bestDivisors;
+
for (divisors->m1 = limits.min.m1; divisors->m1 <= limits.max.m1;
divisors->m1++) {
for (divisors->m2 = limits.min.m2; divisors->m2 <= limits.max.m2
&& ((divisors->m2 < divisors->m1) || is_pine);
divisors->m2++) {
for (divisors->n = limits.min.n; divisors->n <=
limits.max.n;
divisors->n++) {
- for (divisors->post1 = limits.min.post1;
- divisors->post1 <=
limits.max.post1; divisors->post1++) {
+ for (divisors->p1 = limits.min.p1;
+ divisors->p1 <= limits.max.p1;
divisors->p1++) {
divisors->m = compute_pll_m(divisors);
- divisors->post =
compute_pll_p(divisors);
+ divisors->p = compute_pll_p(divisors);
if (!valid_pll_divisors(divisors,
&limits))
continue;
float error = fabs(requestedPixelClock
- ((referenceClock *
divisors->m) / divisors->n)
- / divisors->post);
+ / divisors->p);
if (error < best) {
best = error;
bestDivisors = *divisors;
@@ -270,10 +415,28 @@ compute_pll_divisors(display_mode* current, pll_divisors*
divisors,
*divisors = bestDivisors;
- TRACE("%s: found: %g MHz, p = %" B_PRId32 " (p1 = %" B_PRId32 ", "
+ TRACE("%s: best MHz: %g (error: %g)\n", __func__,
+ ((referenceClock * divisors->m) / divisors->n) / divisors->p,
+ best);
+}
+
+
+void
+compute_pll_divisors(display_mode* current, pll_divisors* divisors, bool
isLVDS)
+{
+ if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_G4x)
+ || gInfo->shared_info->device_type.HasPlatformControlHub()) {
+ compute_dpll_g4x(current, divisors, isLVDS);
+ } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_CHV)) {
+ // TODO: CherryView
+ } else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_VLV)) {
+ // TODO: VallyView
+ } else
+ compute_dpll_9xx(current, divisors, isLVDS);
+
+ TRACE("%s: found: p = %" B_PRId32 " (p1 = %" B_PRId32 ", "
"p2 = %" B_PRId32 "), n = %" B_PRId32 ", m = %" B_PRId32 " "
"(m1 = %" B_PRId32 ", m2 = %" B_PRId32 ")\n", __func__,
- ((referenceClock * divisors->m) / divisors->n) / divisors->post,
- divisors->post, divisors->post1, divisors->post2, divisors->n,
+ divisors->p, divisors->p1, divisors->p2, divisors->n,
divisors->m, divisors->m1, divisors->m2);
}
diff --git a/src/add-ons/accelerants/intel_extreme/pll.h
b/src/add-ons/accelerants/intel_extreme/pll.h
index 706f97b..2b607ce 100644
--- a/src/add-ons/accelerants/intel_extreme/pll.h
+++ b/src/add-ons/accelerants/intel_extreme/pll.h
@@ -14,10 +14,9 @@
struct pll_divisors {
- uint32 post;
- uint32 post1;
- uint32 post2;
- bool post2_high;
+ uint32 p;
+ uint32 p1;
+ uint32 p2;
uint32 n;
uint32 m;
uint32 m1;
@@ -27,13 +26,12 @@ struct pll_divisors {
struct pll_limits {
pll_divisors min;
pll_divisors max;
- uint32 min_post2_frequency;
+ uint32 dot_limit;
uint32 min_vco;
uint32 max_vco;
};
-void get_pll_limits(pll_limits* limits, bool isLVDS);
bool valid_pll_divisors(pll_divisors* divisors, pll_limits* limits);
void compute_pll_divisors(display_mode* current, pll_divisors* divisors,
bool isLVDS);
############################################################################
Revision: hrev50303
Commit: a32e8156730975d66634c655655fdf68b56660fc
URL: http://cgit.haiku-os.org/haiku/commit/?id=a32e81567309
Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date: Wed May 11 17:35:50 2016 UTC
intel_extreme: Shorten graphics family names
----------------------------------------------------------------------------
diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp
b/src/add-ons/accelerants/intel_extreme/accelerant.cpp
index 6510c86..f2adfe2 100644
--- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp
+++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp
@@ -564,18 +564,18 @@ intel_get_accelerant_device_info(accelerant_device_info*
info)
DeviceType* type = &gInfo->shared_info->device_type;
- if (type->InFamily(INTEL_FAMILY_7xx))
- strcpy(info->name, "Intel Extreme Graphics");
- else if (type->InFamily(INTEL_FAMILY_8xx))
- strcpy(info->name, "Intel Extreme Graphics 2");
+ if (type->InFamily(INTEL_FAMILY_7xx) ||
type->InFamily(INTEL_FAMILY_8xx))
+ strcpy(info->name, "Intel Extreme");
else if (type->InFamily(INTEL_FAMILY_9xx))
- strcpy(info->name, "Intel Graphics Media Accelerator");
- else if (type->InFamily(INTEL_FAMILY_SER5))
- strcpy(info->name, "Intel HD/Iris Graphics");
+ strcpy(info->name, "Intel GMA");
else if (type->InFamily(INTEL_FAMILY_POVR))
- strcpy(info->name, "Intel PowerVR Graphics");
+ strcpy(info->name, "Intel PowerVR");
else if (type->InFamily(INTEL_FAMILY_SOC0))
- strcpy(info->name, "Intel Atom Graphics");
+ strcpy(info->name, "Intel Atom");
+ else if (type->InFamily(INTEL_FAMILY_SER5))
+ strcpy(info->name, "Intel HD/Iris");
+ else
+ strcpy(info->name, "Intel");
strcpy(info->chipset, gInfo->shared_info->device_identifier);
strcpy(info->serial_no, "None");