pll: Cleanup PLL post dividers, add VLV and CHV limits
This commit is contained in:
parent
3cfe299798
commit
e587aa9fa3
@ -216,6 +216,7 @@ Pipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock,
|
||||
if (gInfo->shared_info->device_type.Generation() >= 4
|
||||
|| gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
|
||||
|
||||
// post1 divisor << 1 , 1-8
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_PIN)) {
|
||||
pll |= ((1 << (divisors.post1 - 1))
|
||||
<< DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT)
|
||||
@ -228,16 +229,7 @@ Pipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock,
|
||||
// & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO: ??? LVDS?
|
||||
switch (divisors.post2) {
|
||||
case 5:
|
||||
case 7:
|
||||
pll |= DISPLAY_PLL_DIVIDE_HIGH;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// p2 clock divider. 5 or 7 high
|
||||
if (divisors.post2_high)
|
||||
pll |= DISPLAY_PLL_DIVIDE_HIGH;
|
||||
|
||||
|
@ -44,19 +44,41 @@ get_pll_limits(pll_limits* limits, bool isLVDS)
|
||||
// Note, the limits are taken from the X driver; they have not yet been
|
||||
// tested
|
||||
|
||||
if (gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_SER5)
|
||||
|| gInfo->shared_info->device_type.InFamily(INTEL_FAMILY_SOC0)) {
|
||||
// TODO: support LVDS output limits as well
|
||||
// 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)) {
|
||||
// (Update: Output limits are adjusted in the computation (post2=7/14))
|
||||
// Should move them here!
|
||||
pll_limits kLimits = {
|
||||
// p, p1, p2, high, n, m, m1, m2
|
||||
{ 5, 1, 10, false, 1, 70, 8, 3}, // min
|
||||
@ -71,32 +93,49 @@ get_pll_limits(pll_limits* limits, bool isLVDS)
|
||||
}
|
||||
memcpy(limits, &kLimits, sizeof(pll_limits));
|
||||
} else if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_G4x)) {
|
||||
// TODO: support LVDS output limits as well
|
||||
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)) {
|
||||
// TODO: support LVDS output limits as well
|
||||
// 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, 256}, // max
|
||||
{ 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 {
|
||||
// TODO: support LVDS output limits as well
|
||||
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));
|
||||
}
|
||||
|
||||
@ -171,13 +210,19 @@ compute_pll_divisors(display_mode* current, pll_divisors* divisors,
|
||||
|
||||
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)
|
||||
divisors->post2 = LVDS_POST2_RATE_FAST;
|
||||
else
|
||||
divisors->post2 = LVDS_POST2_RATE_SLOW;
|
||||
== LVDS_CLKB_POWER_UP) {
|
||||
// slow DAC timing
|
||||
divisors->post2 = limits.min.post2;
|
||||
divisors->post2_high = limits.min.post2_high;
|
||||
} else {
|
||||
// fast DAC timing
|
||||
divisors->post2 = limits.max.post2;
|
||||
divisors->post2_high = limits.max.post2_high;
|
||||
}
|
||||
} else {
|
||||
if (current->timing.pixel_clock < limits.min_post2_frequency) {
|
||||
// slow DAC timing
|
||||
|
Loading…
Reference in New Issue
Block a user