Ticket #5221: 0001-intel_extreme-probe-all-GPIO-pins.patch

File 0001-intel_extreme-probe-all-GPIO-pins.patch, 6.3 KB (added by jessicah, 6 years ago)

Updated patch against hrev47853

  • src/add-ons/accelerants/intel_extreme/mode.cpp

    From 16a6b5cf15b14cf82b3b472fd93aa1272fada51b Mon Sep 17 00:00:00 2001
    From: Jessica Hamilton <jessica.l.hamilton@gmail.com>
    Date: Sat, 13 Sep 2014 17:21:37 +1200
    Subject: [PATCH] intel_extreme: probe all GPIO pins
    
    ---
     src/add-ons/accelerants/intel_extreme/mode.cpp | 147 ++++++++++++++-----------
     1 file changed, 81 insertions(+), 66 deletions(-)
     mode change 100644 => 100755 src/add-ons/accelerants/intel_extreme/mode.cpp
    
    diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp
    old mode 100644
    new mode 100755
    index ae63f77..15d91a3
    a b struct pll_limits {  
    7373    uint32          max_vco;
    7474};
    7575
     76struct gpio_map {
     77    const char* name;
     78    uint32      pin;
     79    uint32      validOn;
     80};
     81
    7682
    7783static void mode_fill_missing_bits(display_mode *, uint32);
    7884
    set_frame_buffer_base()  
    579585status_t
    580586create_mode_list(void)
    581587{
    582     i2c_bus bus;
    583     bus.cookie = (void*)(addr_t)INTEL_I2C_IO_A;
    584     bus.set_signals = &set_i2c_signals;
    585     bus.get_signals = &get_i2c_signals;
    586     ddc2_init_timing(&bus);
    587 
    588     status_t error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL);
    589     if (error == B_OK) {
     588    // TODO: We may want to choose different GPIO pin maps
     589    // for different generations of cards... not sure
     590    const gpio_map gpioPinMap[] = {
     591        {"ssc", INTEL_I2C_IO_B, 0},
     592        {"vga", INTEL_I2C_IO_A, HEAD_MODE_A_ANALOG},
     593        {"lvds", INTEL_I2C_IO_C, HEAD_MODE_LVDS_PANEL},
     594        {"dpc", INTEL_I2C_IO_D, 0},
     595        {"dpb", INTEL_I2C_IO_E, 0},
     596        {"dpd", INTEL_I2C_IO_F, 0},
     597    };
     598
     599    // TODO: We may want to do extra validation on gpio validOn
     600    // vs the HEAD_MODE_ in head_mode
     601    for (uint32 i = 0; i < sizeof(gpioPinMap) / sizeof(gpioPinMap[0]); i++) {
     602        i2c_bus bus;
     603        bus.cookie = (void*)gpioPinMap[i].pin;
     604        bus.set_signals = &set_i2c_signals;
     605        bus.get_signals = &get_i2c_signals;
     606        ddc2_init_timing(&bus);
     607
     608        status_t result = ddc2_read_edid1(&bus, &gInfo->edid_info,
     609            NULL, NULL);
     610
     611        if (result != B_OK)
     612            continue;
     613
     614        TRACE("found edid data on gpio '%s'\n", gpioPinMap[i].name);
     615
    590616        edid_dump(&gInfo->edid_info);
    591617        gInfo->has_edid = true;
    592618        if (gInfo->shared_info->single_head_locked)
    593619            gInfo->head_mode = HEAD_MODE_A_ANALOG;
    594     } else {
    595         TRACE("getting EDID on port A (analog) failed: %s. "
    596             "Trying on port C (lvds)\n", strerror(error));
    597         bus.cookie = (void*)INTEL_I2C_IO_C;
    598         error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL);
    599         if (error == B_OK) {
    600             edid_dump(&gInfo->edid_info);
    601             gInfo->has_edid = true;
    602         } else if (gInfo->shared_info->has_vesa_edid_info) {
    603             TRACE("getting EDID on port C failed: %s. Use VESA EDID info\n",
    604                 strerror(error));
    605             memcpy(&gInfo->edid_info, &gInfo->shared_info->vesa_edid_info,
    606                 sizeof(edid1_info));
    607             gInfo->has_edid = true;
    608         } else {
    609             TRACE("getting EDID on port C failed: %s\n",
    610                 strerror(error));
    611 
    612             // We could not read any EDID info. Fallback to creating a list with
    613             // only the mode set up by the BIOS.
    614             // TODO: support lower modes via scaling and windowing
    615             if (((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
    616                     && (gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0)
    617                     || ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
    618                     && gInfo->shared_info->got_vbt)) {
    619                 size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1)
    620                     & ~(B_PAGE_SIZE - 1);
    621 
    622                 display_mode* list;
    623                 area_id area = create_area("intel extreme modes",
    624                     (void**)&list, B_ANY_ADDRESS, size, B_NO_LOCK,
    625                     B_READ_AREA | B_WRITE_AREA);
    626                 if (area < B_OK)
    627                     return area;
    628 
    629                 // Prefer information dumped directly from VBT, as the BIOS
    630                 // one may have display scaling, but only do this if the VBT
    631                 // resolution is higher than the BIOS one.
    632                 if (gInfo->shared_info->got_vbt
    633                     && gInfo->shared_info->current_mode.virtual_width
    634                         >= gInfo->lvds_panel_mode.virtual_width
    635                     && gInfo->shared_info->current_mode.virtual_height
    636                         >= gInfo->lvds_panel_mode.virtual_height) {
    637                     memcpy(list, &gInfo->shared_info->current_mode,
    638                         sizeof(display_mode));
    639                     mode_fill_missing_bits(list, INTEL_DISPLAY_B_CONTROL);
    640                 } else {
    641                     memcpy(list, &gInfo->lvds_panel_mode,
    642                         sizeof(display_mode));
    643 
    644                     if (gInfo->shared_info->got_vbt)
    645                         TRACE("intel_extreme: ignoring VBT mode.");
    646                 }
    647620
    648                 gInfo->mode_list_area = area;
    649                 gInfo->mode_list = list;
    650                 gInfo->shared_info->mode_list_area = gInfo->mode_list_area;
    651                 gInfo->shared_info->mode_count = 1;
    652                 return B_OK;
     621        // TODO: We may want to probe multiple GPIO pins here
     622        // someday and store valid ones for multi-head support.
     623        // For now, we break on the first valid one.
     624        break;
     625    }
     626
     627    if (!gInfo->has_edid) {
     628        // We could not read any EDID info. Fallback to creating a list with
     629        // only the mode set up by the BIOS.
     630        // TODO: support lower modes via scaling and windowing
     631        if (((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
     632                && (gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0)
     633                || ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
     634                && gInfo->shared_info->got_vbt)) {
     635            size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1)
     636                & ~(B_PAGE_SIZE - 1);
     637
     638            display_mode* list;
     639            area_id area = create_area("intel extreme modes",
     640                (void**)&list, B_ANY_ADDRESS, size, B_NO_LOCK,
     641                B_READ_AREA | B_WRITE_AREA);
     642            if (area < B_OK)
     643                return area;
     644
     645            // Prefer information dumped directly from VBT, as the BIOS
     646            // one may have display scaling, but only do this if the VBT
     647            // resolution is higher than the BIOS one.
     648            if (gInfo->shared_info->got_vbt
     649                && gInfo->shared_info->current_mode.virtual_width
     650                    >= gInfo->lvds_panel_mode.virtual_width
     651                && gInfo->shared_info->current_mode.virtual_height
     652                    >= gInfo->lvds_panel_mode.virtual_height) {
     653                memcpy(list, &gInfo->shared_info->current_mode,
     654                    sizeof(display_mode));
     655                mode_fill_missing_bits(list, INTEL_DISPLAY_B_CONTROL);
     656            } else {
     657                memcpy(list, &gInfo->lvds_panel_mode,
     658                    sizeof(display_mode));
     659
     660                if (gInfo->shared_info->got_vbt)
     661                    TRACE("intel_extreme: ignoring VBT mode.");
    653662            }
     663
     664            gInfo->mode_list_area = area;
     665            gInfo->mode_list = list;
     666            gInfo->shared_info->mode_list_area = gInfo->mode_list_area;
     667            gInfo->shared_info->mode_count = 1;
     668            return B_OK;
    654669        }
    655670    }
    656671