* added support for the Atom IGD, based on the X driver sources (fixes #6202)
* fixes G4x PLL limits git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40319 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
476bfd22cb
commit
2f4d9fdbab
@ -33,6 +33,7 @@
|
||||
#define INTEL_TYPE_96x (INTEL_TYPE_9xx | 0x0100)
|
||||
#define INTEL_TYPE_Gxx (INTEL_TYPE_9xx | 0x0200)
|
||||
#define INTEL_TYPE_G4x (INTEL_TYPE_9xx | 0x0400)
|
||||
#define INTEL_TYPE_IGD (INTEL_TYPE_9xx | 0x0800)
|
||||
// models
|
||||
#define INTEL_TYPE_MOBILE 0x0008
|
||||
#define INTEL_TYPE_915 (INTEL_TYPE_91x)
|
||||
@ -43,6 +44,8 @@
|
||||
#define INTEL_TYPE_G33 (INTEL_TYPE_Gxx)
|
||||
#define INTEL_TYPE_G45 (INTEL_TYPE_G4x)
|
||||
#define INTEL_TYPE_GM45 (INTEL_TYPE_G4x | INTEL_TYPE_MOBILE)
|
||||
#define INTEL_TYPE_IGDG (INTEL_TYPE_IGD)
|
||||
#define INTEL_TYPE_IGDGM (INTEL_TYPE_IGD | INTEL_TYPE_MOBILE)
|
||||
|
||||
#define DEVICE_NAME "intel_extreme"
|
||||
#define INTEL_ACCELERANT_NAME "intel_extreme.accelerant"
|
||||
@ -301,11 +304,15 @@ struct intel_free_graphics_memory {
|
||||
#define DISPLAY_PLL_POST1_DIVIDE_2 (1UL << 21)
|
||||
#define DISPLAY_PLL_POST1_DIVISOR_MASK 0x001f0000
|
||||
#define DISPLAY_PLL_9xx_POST1_DIVISOR_MASK 0x00ff0000
|
||||
#define DISPLAY_PLL_IGD_POST1_DIVISOR_MASK 0x00ff8000
|
||||
#define DISPLAY_PLL_POST1_DIVISOR_SHIFT 16
|
||||
#define DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT 15
|
||||
#define DISPLAY_PLL_DIVISOR_1 (1UL << 8)
|
||||
#define DISPLAY_PLL_N_DIVISOR_MASK 0x001f0000
|
||||
#define DISPLAY_PLL_IGD_N_DIVISOR_MASK 0x00ff0000
|
||||
#define DISPLAY_PLL_M1_DIVISOR_MASK 0x00001f00
|
||||
#define DISPLAY_PLL_M2_DIVISOR_MASK 0x0000001f
|
||||
#define DISPLAY_PLL_IGD_M2_DIVISOR_MASK 0x000000ff
|
||||
#define DISPLAY_PLL_N_DIVISOR_SHIFT 16
|
||||
#define DISPLAY_PLL_M1_DIVISOR_SHIFT 8
|
||||
#define DISPLAY_PLL_M2_DIVISOR_SHIFT 0
|
||||
|
@ -234,13 +234,22 @@ get_pll_limits(pll_limits &limits)
|
||||
// tested
|
||||
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_G4x)) {
|
||||
// single LVDS output
|
||||
// NOTE: not sure these will work with CRT displays
|
||||
// TODO: support LVDS output limits as well
|
||||
static const pll_limits kLimits = {
|
||||
// p, p1, p2, high, n, m, m1, m2
|
||||
{ 28, 2, 14, false, 1, 104, 17, 5}, // min
|
||||
{112, 8, 0, true, 3, 138, 23, 11}, // max
|
||||
200000, 1750000, 3500000
|
||||
{ 10, 1, 10, false, 1, 104, 17, 5}, // min
|
||||
{ 30, 3, 10, true, 4, 138, 23, 11}, // max
|
||||
270000, 1750000, 3500000
|
||||
};
|
||||
limits = kLimits;
|
||||
} else if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
// TODO: support LVDS output limits as well
|
||||
// m1 is reserved and must be 0
|
||||
static const 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
|
||||
200000, 1700000, 3500000
|
||||
};
|
||||
limits = kLimits;
|
||||
} else if (gInfo->shared_info->device_type.InFamily(INTEL_TYPE_9xx)) {
|
||||
@ -323,9 +332,10 @@ compute_pll_divisors(const display_mode ¤t, pll_divisors& divisors,
|
||||
float best = requestedPixelClock;
|
||||
pll_divisors bestDivisors;
|
||||
|
||||
bool is_igd = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD);
|
||||
for (divisors.m1 = limits.min.m1; divisors.m1 <= limits.max.m1; divisors.m1++) {
|
||||
for (divisors.m2 = limits.min.m2; divisors.m2 < divisors.m1
|
||||
&& divisors.m2 <= limits.max.m2; divisors.m2++) {
|
||||
for (divisors.m2 = limits.min.m2; divisors.m2 <= limits.max.m2
|
||||
&& ((divisors.m2 < divisors.m1) || is_igd); divisors.m2++) {
|
||||
for (divisors.n = limits.min.n; divisors.n <= limits.max.n;
|
||||
divisors.n++) {
|
||||
for (divisors.post1 = limits.min.post1;
|
||||
@ -397,19 +407,32 @@ retrieve_current_mode(display_mode& mode, uint32 pllRegister)
|
||||
}
|
||||
|
||||
pll_divisors divisors;
|
||||
divisors.m1 = (pllDivisor & DISPLAY_PLL_M1_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_M1_DIVISOR_SHIFT;
|
||||
divisors.m2 = (pllDivisor & DISPLAY_PLL_M2_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_M2_DIVISOR_SHIFT;
|
||||
divisors.n = (pllDivisor & DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_N_DIVISOR_SHIFT;
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
divisors.m1 = 0;
|
||||
divisors.m2 = (pllDivisor & DISPLAY_PLL_IGD_M2_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_M2_DIVISOR_SHIFT;
|
||||
divisors.n = ((pllDivisor & DISPLAY_PLL_IGD_N_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_N_DIVISOR_SHIFT) - 1;
|
||||
} else {
|
||||
divisors.m1 = (pllDivisor & DISPLAY_PLL_M1_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_M1_DIVISOR_SHIFT;
|
||||
divisors.m2 = (pllDivisor & DISPLAY_PLL_M2_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_M2_DIVISOR_SHIFT;
|
||||
divisors.n = (pllDivisor & DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_N_DIVISOR_SHIFT;
|
||||
}
|
||||
|
||||
pll_limits limits;
|
||||
get_pll_limits(limits);
|
||||
|
||||
if (gInfo->shared_info->device_type.InFamily(INTEL_TYPE_9xx)) {
|
||||
divisors.post1 = (pll & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_POST1_DIVISOR_SHIFT;
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
divisors.post1 = (pll & DISPLAY_PLL_IGD_POST1_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT;
|
||||
} else {
|
||||
divisors.post1 = (pll & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK)
|
||||
>> DISPLAY_PLL_POST1_DIVISOR_SHIFT;
|
||||
}
|
||||
|
||||
if (pllRegister == INTEL_DISPLAY_B_PLL
|
||||
&& !gInfo->shared_info->device_type.InGroup(INTEL_TYPE_96x)) {
|
||||
@ -725,7 +748,11 @@ if (first) {
|
||||
}
|
||||
|
||||
// Compute bitmask from p1 value
|
||||
dpll |= (1 << (divisors.post1 - 1)) << DISPLAY_PLL_POST1_DIVISOR_SHIFT;
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
dpll |= (1 << (divisors.post1 - 1)) << DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT;
|
||||
} else {
|
||||
dpll |= (1 << (divisors.post1 - 1)) << DISPLAY_PLL_POST1_DIVISOR_SHIFT;
|
||||
}
|
||||
switch (divisors.post2) {
|
||||
case 5:
|
||||
case 7:
|
||||
@ -739,13 +766,21 @@ if (first) {
|
||||
// (I don't know how to detect that)
|
||||
|
||||
if ((dpll & DISPLAY_PLL_ENABLED) != 0) {
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M1_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M2_DIVISOR_MASK));
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
(((1 << divisors.n) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_N_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
|
||||
} else {
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M1_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M2_DIVISOR_MASK));
|
||||
}
|
||||
write32(INTEL_DISPLAY_B_PLL, dpll & ~DISPLAY_PLL_ENABLED);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
spin(150);
|
||||
@ -771,13 +806,21 @@ if (first) {
|
||||
write32(INTEL_DISPLAY_LVDS_PORT, lvds);
|
||||
read32(INTEL_DISPLAY_LVDS_PORT);
|
||||
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M1_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M2_DIVISOR_MASK));
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
(((1 << divisors.n) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_N_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
|
||||
} else {
|
||||
write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M1_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M2_DIVISOR_MASK));
|
||||
}
|
||||
|
||||
write32(INTEL_DISPLAY_B_PLL, dpll);
|
||||
read32(INTEL_DISPLAY_B_PLL);
|
||||
@ -904,21 +947,35 @@ if (first) {
|
||||
pll_divisors divisors;
|
||||
compute_pll_divisors(target, divisors, false);
|
||||
|
||||
write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M1_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M2_DIVISOR_MASK));
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
|
||||
(((1 << divisors.n) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_N_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_M2_DIVISOR_MASK));
|
||||
} else {
|
||||
write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
|
||||
(((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_N_DIVISOR_MASK)
|
||||
| (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M1_DIVISOR_MASK)
|
||||
| (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_M2_DIVISOR_MASK));
|
||||
}
|
||||
|
||||
uint32 pll = DISPLAY_PLL_ENABLED | DISPLAY_PLL_NO_VGA_CONTROL;
|
||||
if (gInfo->shared_info->device_type.InFamily(INTEL_TYPE_9xx)) {
|
||||
pll |= ((1 << (divisors.post1 - 1))
|
||||
<< DISPLAY_PLL_POST1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
|
||||
// pll |= ((divisors.post1 - 1) << DISPLAY_PLL_POST1_DIVISOR_SHIFT)
|
||||
// & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
|
||||
pll |= ((1 << (divisors.post1 - 1))
|
||||
<< DISPLAY_PLL_IGD_POST1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_IGD_POST1_DIVISOR_MASK;
|
||||
} else {
|
||||
pll |= ((1 << (divisors.post1 - 1))
|
||||
<< DISPLAY_PLL_POST1_DIVISOR_SHIFT)
|
||||
& DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
|
||||
// pll |= ((divisors.post1 - 1) << DISPLAY_PLL_POST1_DIVISOR_SHIFT)
|
||||
// & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
|
||||
}
|
||||
if (divisors.post2_high)
|
||||
pll |= DISPLAY_PLL_DIVIDE_HIGH;
|
||||
|
||||
|
@ -71,6 +71,9 @@ const struct supported_device {
|
||||
|
||||
{0x2e30, 0x2e32, INTEL_TYPE_GM45, "GMA_X4500_VGA"},
|
||||
{0x2a40, 0x2a42, INTEL_TYPE_GM45, "GM45"},
|
||||
|
||||
{0xa000, 0xa001, INTEL_TYPE_IGDG, "Atom_Dx10"},
|
||||
{0xa010, 0xa011, INTEL_TYPE_IGDGM, "Atom_N4x0"},
|
||||
};
|
||||
|
||||
struct intel_info {
|
||||
@ -140,7 +143,8 @@ determine_memory_sizes(intel_info &info, size_t >tSize, size_t &stolenSize)
|
||||
gttSize = 512 << 10;
|
||||
break;
|
||||
}
|
||||
} else if (info.type == INTEL_TYPE_G33) {
|
||||
} else if (info.type == INTEL_TYPE_G33
|
||||
|| (info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_IGD) {
|
||||
switch (memoryConfig & G33_GTT_MASK) {
|
||||
case G33_GTT_1M:
|
||||
gttSize = 1 << 20;
|
||||
|
@ -59,6 +59,9 @@ const struct supported_device {
|
||||
|
||||
{0x2e32, INTEL_TYPE_GM45, "GMA_X4500_VGA"},
|
||||
{0x2a42, INTEL_TYPE_GM45, "GM45"},
|
||||
|
||||
{0xa001, INTEL_TYPE_IGDG, "Atom_Dx10"},
|
||||
{0xa011, INTEL_TYPE_IGDGM, "Atom_N4x0"},
|
||||
};
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
Loading…
x
Reference in New Issue
Block a user