Ticket #6202: intel_extreme_atom.patch

File intel_extreme_atom.patch, 11.2 KB (added by brecht, 13 years ago)

fixes some bugs in the PLL code

  • src/add-ons/kernel/busses/agp_gart/intel_gart.cpp

     
    7171
    7272    {0x2e30, 0x2e32, INTEL_TYPE_GM45, "GMA_X4500_VGA"},
    7373    {0x2a40, 0x2a42, INTEL_TYPE_GM45, "GM45"},
     74   
     75    {0xa000, 0xa001, INTEL_TYPE_IGDG, "Atom_Dx10"},
     76    {0xa010, 0xa011, INTEL_TYPE_IGDGM, "Atom_N4x0"},
    7477};
    7578
    7679struct intel_info {
     
    140143                gttSize = 512 << 10;
    141144                break;
    142145        }
    143     } else if (info.type == INTEL_TYPE_G33) {
     146    } else if (info.type == INTEL_TYPE_G33
     147               || (info.type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_IGD) {
    144148        switch (memoryConfig & G33_GTT_MASK) {
    145149            case G33_GTT_1M:
    146150                gttSize = 1 << 20;
  • src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp

     
    5959
    6060    {0x2e32, INTEL_TYPE_GM45, "GMA_X4500_VGA"},
    6161    {0x2a42, INTEL_TYPE_GM45, "GM45"},
     62
     63    {0xa001, INTEL_TYPE_IGDG, "Atom_Dx10"},
     64    {0xa011, INTEL_TYPE_IGDGM, "Atom_N4x0"},
    6265};
    6366
    6467int32 api_version = B_CUR_DRIVER_API_VERSION;
  • src/add-ons/accelerants/intel_extreme/mode.cpp

     
    234234    // tested
    235235
    236236    if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_G4x)) {
    237         // single LVDS output
    238         // NOTE: not sure these will work with CRT displays
     237        // TODO: support LVDS output limits as well
    239238        static const pll_limits kLimits = {
    240239            // p, p1, p2, high,   n,   m, m1, m2
    241             { 28,  2, 14, false,  1, 104, 17,  5},  // min
    242             {112,  8,  0, true,   3, 138, 23, 11},  // max
    243             200000, 1750000, 3500000
     240            { 10,  1, 10, false,  1, 104, 17,  5},  // min
     241            { 30,  3, 10, true,   4, 138, 23, 11},  // max
     242            270000, 1750000, 3500000
    244243        };
    245244        limits = kLimits;
     245    } else if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
     246        // TODO: support LVDS output limits as well
     247        // m1 is reserved and must be 0
     248        static const pll_limits kLimits = {
     249            // p, p1, p2, high,   n,   m, m1,  m2
     250            {  5,  1, 10, false,  3,   2,  0,   2}, // min
     251            { 80,  8,  5, true,   6, 256,  0, 256}, // max
     252            200000, 1700000, 3500000
     253        };
     254        limits = kLimits;
    246255    } else if (gInfo->shared_info->device_type.InFamily(INTEL_TYPE_9xx)) {
    247256        // TODO: support LVDS output limits as well
    248257        // (Update: Output limits are adjusted in the computation (post2=7/14))
     
    323332    float best = requestedPixelClock;
    324333    pll_divisors bestDivisors;
    325334
     335    bool is_igd = gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD);
    326336    for (divisors.m1 = limits.min.m1; divisors.m1 <= limits.max.m1; divisors.m1++) {
    327         for (divisors.m2 = limits.min.m2; divisors.m2 < divisors.m1
    328                 && divisors.m2 <= limits.max.m2; divisors.m2++) {
     337        for (divisors.m2 = limits.min.m2; divisors.m2 <= limits.max.m2
     338                && ((divisors.m2 < divisors.m1) || is_igd); divisors.m2++) {
    329339            for (divisors.n = limits.min.n; divisors.n <= limits.max.n;
    330340                    divisors.n++) {
    331341                for (divisors.post1 = limits.min.post1;
     
    397407    }
    398408
    399409    pll_divisors divisors;
    400     divisors.m1 = (pllDivisor & DISPLAY_PLL_M1_DIVISOR_MASK)
    401         >> DISPLAY_PLL_M1_DIVISOR_SHIFT;
    402     divisors.m2 = (pllDivisor & DISPLAY_PLL_M2_DIVISOR_MASK)
    403         >> DISPLAY_PLL_M2_DIVISOR_SHIFT;
    404     divisors.n = (pllDivisor & DISPLAY_PLL_N_DIVISOR_MASK)
    405         >> DISPLAY_PLL_N_DIVISOR_SHIFT;
     410    if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
     411        divisors.m1 = 0;
     412        divisors.m2 = (pllDivisor & DISPLAY_PLL_M2_DIVISOR_MASK_IGD)
     413            >> DISPLAY_PLL_M2_DIVISOR_SHIFT;
     414        divisors.n = ((pllDivisor & DISPLAY_PLL_N_DIVISOR_MASK_IGD)
     415            >> DISPLAY_PLL_N_DIVISOR_SHIFT) - 1;
     416    } else {
     417        divisors.m1 = (pllDivisor & DISPLAY_PLL_M1_DIVISOR_MASK)
     418            >> DISPLAY_PLL_M1_DIVISOR_SHIFT;
     419        divisors.m2 = (pllDivisor & DISPLAY_PLL_M2_DIVISOR_MASK)
     420            >> DISPLAY_PLL_M2_DIVISOR_SHIFT;
     421        divisors.n = (pllDivisor & DISPLAY_PLL_N_DIVISOR_MASK)
     422            >> DISPLAY_PLL_N_DIVISOR_SHIFT;     
     423    }
    406424
    407425    pll_limits limits;
    408426    get_pll_limits(limits);
    409427
    410428    if (gInfo->shared_info->device_type.InFamily(INTEL_TYPE_9xx)) {
    411         divisors.post1 = (pll & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK)
    412             >> DISPLAY_PLL_POST1_DIVISOR_SHIFT;
     429        if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
     430            divisors.post1 = (pll & DISPLAY_PLL_IGD_POST1_DIVISOR_MASK)
     431                >> DISPLAY_PLL_POST1_DIVISOR_SHIFT_IGD;         
     432        } else {
     433            divisors.post1 = (pll & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK)
     434                >> DISPLAY_PLL_POST1_DIVISOR_SHIFT;
     435        }
    413436
    414437        if (pllRegister == INTEL_DISPLAY_B_PLL
    415438            && !gInfo->shared_info->device_type.InGroup(INTEL_TYPE_96x)) {
     
    725748        }
    726749
    727750        // Compute bitmask from p1 value
    728         dpll |= (1 << (divisors.post1 - 1)) << DISPLAY_PLL_POST1_DIVISOR_SHIFT;
     751        if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
     752            dpll |= (1 << (divisors.post1 - 1)) << DISPLAY_PLL_POST1_DIVISOR_SHIFT_IGD;
     753        } else {
     754            dpll |= (1 << (divisors.post1 - 1)) << DISPLAY_PLL_POST1_DIVISOR_SHIFT;
     755        }
    729756        switch (divisors.post2) {
    730757            case 5:
    731758            case 7:
     
    739766            // (I don't know how to detect that)
    740767
    741768        if ((dpll & DISPLAY_PLL_ENABLED) != 0) {
    742             write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
    743                 (((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
    744                     & DISPLAY_PLL_N_DIVISOR_MASK)
    745                 | (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
    746                     & DISPLAY_PLL_M1_DIVISOR_MASK)
    747                 | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
    748                     & DISPLAY_PLL_M2_DIVISOR_MASK));
     769            if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
     770                write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
     771                    (((1 << divisors.n) << DISPLAY_PLL_N_DIVISOR_SHIFT)
     772                        & DISPLAY_PLL_N_DIVISOR_MASK_IGD)
     773                    | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
     774                        & DISPLAY_PLL_M2_DIVISOR_MASK_IGD));
     775            } else {
     776                write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
     777                    (((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
     778                        & DISPLAY_PLL_N_DIVISOR_MASK)
     779                    | (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
     780                        & DISPLAY_PLL_M1_DIVISOR_MASK)
     781                    | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
     782                        & DISPLAY_PLL_M2_DIVISOR_MASK));               
     783            }
    749784            write32(INTEL_DISPLAY_B_PLL, dpll & ~DISPLAY_PLL_ENABLED);
    750785            read32(INTEL_DISPLAY_B_PLL);
    751786            spin(150);
     
    771806        write32(INTEL_DISPLAY_LVDS_PORT, lvds);
    772807        read32(INTEL_DISPLAY_LVDS_PORT);
    773808
    774         write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
    775             (((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
    776                 & DISPLAY_PLL_N_DIVISOR_MASK)
    777             | (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
    778                 & DISPLAY_PLL_M1_DIVISOR_MASK)
    779             | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
    780                 & DISPLAY_PLL_M2_DIVISOR_MASK));
     809        if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
     810            write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
     811                (((1 << divisors.n) << DISPLAY_PLL_N_DIVISOR_SHIFT)
     812                    & DISPLAY_PLL_N_DIVISOR_MASK_IGD)
     813                | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
     814                    & DISPLAY_PLL_M2_DIVISOR_MASK_IGD));
     815        } else {
     816            write32(INTEL_DISPLAY_B_PLL_DIVISOR_0,
     817                (((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
     818                    & DISPLAY_PLL_N_DIVISOR_MASK)
     819                | (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
     820                    & DISPLAY_PLL_M1_DIVISOR_MASK)
     821                | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
     822                    & DISPLAY_PLL_M2_DIVISOR_MASK));   
     823        }
    781824
    782825        write32(INTEL_DISPLAY_B_PLL, dpll);
    783826        read32(INTEL_DISPLAY_B_PLL);
     
    904947        pll_divisors divisors;
    905948        compute_pll_divisors(target, divisors, false);
    906949
    907         write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
    908             (((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
    909                 & DISPLAY_PLL_N_DIVISOR_MASK)
    910             | (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
    911                 & DISPLAY_PLL_M1_DIVISOR_MASK)
    912             | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
    913                 & DISPLAY_PLL_M2_DIVISOR_MASK));
     950        if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
     951            write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
     952                (((1 << divisors.n) << DISPLAY_PLL_N_DIVISOR_SHIFT)
     953                    & DISPLAY_PLL_N_DIVISOR_MASK_IGD)
     954                | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
     955                    & DISPLAY_PLL_M2_DIVISOR_MASK_IGD));
     956        } else {
     957            write32(INTEL_DISPLAY_A_PLL_DIVISOR_0,
     958                (((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT)
     959                    & DISPLAY_PLL_N_DIVISOR_MASK)
     960                | (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT)
     961                    & DISPLAY_PLL_M1_DIVISOR_MASK)
     962                | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT)
     963                    & DISPLAY_PLL_M2_DIVISOR_MASK));
     964        }
    914965
    915966        uint32 pll = DISPLAY_PLL_ENABLED | DISPLAY_PLL_NO_VGA_CONTROL;
    916967        if (gInfo->shared_info->device_type.InFamily(INTEL_TYPE_9xx)) {
    917             pll |= ((1 << (divisors.post1 - 1))
    918                     << DISPLAY_PLL_POST1_DIVISOR_SHIFT)
    919                 & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
    920 //          pll |= ((divisors.post1 - 1) << DISPLAY_PLL_POST1_DIVISOR_SHIFT)
    921 //              & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
     968            if (gInfo->shared_info->device_type.InGroup(INTEL_TYPE_IGD)) {
     969                pll |= ((1 << (divisors.post1 - 1))
     970                        << DISPLAY_PLL_POST1_DIVISOR_SHIFT_IGD)
     971                    & DISPLAY_PLL_IGD_POST1_DIVISOR_MASK;
     972            } else {
     973                pll |= ((1 << (divisors.post1 - 1))
     974                        << DISPLAY_PLL_POST1_DIVISOR_SHIFT)
     975                    & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
     976//              pll |= ((divisors.post1 - 1) << DISPLAY_PLL_POST1_DIVISOR_SHIFT)
     977//                  & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK;
     978            }
    922979            if (divisors.post2_high)
    923980                pll |= DISPLAY_PLL_DIVIDE_HIGH;
    924981
  • headers/private/graphics/intel_extreme/intel_extreme.h

     
    3333#define INTEL_TYPE_96x          (INTEL_TYPE_9xx | 0x0100)
    3434#define INTEL_TYPE_Gxx          (INTEL_TYPE_9xx | 0x0200)
    3535#define INTEL_TYPE_G4x          (INTEL_TYPE_9xx | 0x0400)
     36#define INTEL_TYPE_IGD          (INTEL_TYPE_9xx | 0x0800)
    3637// models
    3738#define INTEL_TYPE_MOBILE       0x0008
    3839#define INTEL_TYPE_915          (INTEL_TYPE_91x)
     
    4344#define INTEL_TYPE_G33          (INTEL_TYPE_Gxx)
    4445#define INTEL_TYPE_G45          (INTEL_TYPE_G4x)
    4546#define INTEL_TYPE_GM45         (INTEL_TYPE_G4x | INTEL_TYPE_MOBILE)
     47#define INTEL_TYPE_IGDG         (INTEL_TYPE_IGD)
     48#define INTEL_TYPE_IGDGM        (INTEL_TYPE_IGD | INTEL_TYPE_MOBILE)
    4649
    4750#define DEVICE_NAME             "intel_extreme"
    4851#define INTEL_ACCELERANT_NAME   "intel_extreme.accelerant"
     
    301304#define DISPLAY_PLL_POST1_DIVIDE_2      (1UL << 21)
    302305#define DISPLAY_PLL_POST1_DIVISOR_MASK  0x001f0000
    303306#define DISPLAY_PLL_9xx_POST1_DIVISOR_MASK  0x00ff0000
     307#define DISPLAY_PLL_IGD_POST1_DIVISOR_MASK  0x00ff8000
    304308#define DISPLAY_PLL_POST1_DIVISOR_SHIFT 16
     309#define DISPLAY_PLL_POST1_DIVISOR_SHIFT_IGD 15
    305310#define DISPLAY_PLL_DIVISOR_1           (1UL << 8)
    306311#define DISPLAY_PLL_N_DIVISOR_MASK      0x001f0000
     312#define DISPLAY_PLL_N_DIVISOR_MASK_IGD  0x00ff0000
    307313#define DISPLAY_PLL_M1_DIVISOR_MASK     0x00001f00
    308314#define DISPLAY_PLL_M2_DIVISOR_MASK     0x0000001f
     315#define DISPLAY_PLL_M2_DIVISOR_MASK_IGD 0x000000ff
    309316#define DISPLAY_PLL_N_DIVISOR_SHIFT     16
    310317#define DISPLAY_PLL_M1_DIVISOR_SHIFT    8
    311318#define DISPLAY_PLL_M2_DIVISOR_SHIFT    0