From 2f4d9fdbab2d62559a66c7fd86535cca9d5b0c13 Mon Sep 17 00:00:00 2001 From: Brecht Machiels Date: Sat, 29 Jan 2011 21:20:00 +0000 Subject: [PATCH] * 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 --- .../graphics/intel_extreme/intel_extreme.h | 7 + .../accelerants/intel_extreme/mode.cpp | 141 ++++++++++++------ .../kernel/busses/agp_gart/intel_gart.cpp | 6 +- .../drivers/graphics/intel_extreme/driver.cpp | 3 + 4 files changed, 114 insertions(+), 43 deletions(-) diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index f16217488b..80f162bec2 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -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 diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index a2fe107463..3facba7e94 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -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; diff --git a/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp b/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp index 49660cf3fb..eae309ee6a 100644 --- a/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp +++ b/src/add-ons/kernel/busses/agp_gart/intel_gart.cpp @@ -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; diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp index 0f9af7acec..9a42c8b813 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp @@ -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;