Ticket #5221: intel_extreme.diff

File intel_extreme.diff, 3.9 KB (added by kallisti5, 11 years ago)

Probe all GPIO pins, rev 1

  • 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
    index f9bf68f..8a7760e 100644
    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 status_t
    7884get_i2c_signals(void* cookie, int* _clock, int* _data)
    set_frame_buffer_base()  
    164170status_t
    165171create_mode_list(void)
    166172{
    167     i2c_bus bus;
    168     bus.cookie = (void*)INTEL_I2C_IO_A;
    169     bus.set_signals = &set_i2c_signals;
    170     bus.get_signals = &get_i2c_signals;
    171     ddc2_init_timing(&bus);
    172 
    173     status_t error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL);
    174     if (error == B_OK) {
     173    // TODO: We may want to choose different GPIO pin maps
     174    // for different generations of cards... not sure
     175    const gpio_map gpioPinMap[] = {
     176        {"ssc", INTEL_I2C_IO_B, 0},
     177        {"vga", INTEL_I2C_IO_A, HEAD_MODE_A_ANALOG},
     178        {"lvds", INTEL_I2C_IO_C, HEAD_MODE_LVDS_PANEL},
     179        {"dpc", INTEL_I2C_IO_D, 0},
     180        {"dpb", INTEL_I2C_IO_E, 0},
     181        {"dpd", INTEL_I2C_IO_F, 0},
     182    };
     183
     184    // TODO: We may want to do extra validation on gpio validOn
     185    // vs the HEAD_MODE_ in head_mode
     186    for (uint32 i = 0; i < sizeof(gpioPinMap)
     187        / sizeof(gpioPinMap[0]); i++) {
     188
     189        i2c_bus bus;
     190        bus.cookie = (void*)gpioPinMap[i].pin;
     191        bus.set_signals = &set_i2c_signals;
     192        bus.get_signals = &get_i2c_signals;
     193        ddc2_init_timing(&bus);
     194
     195        status_t result = ddc2_read_edid1(&bus, &gInfo->edid_info,
     196            NULL, NULL);
     197
     198        if (result != B_OK)
     199            continue;
     200
     201        TRACE("found edid data on gpio '%s'\n",
     202            gpioPinMap[i].name);
    175203        edid_dump(&gInfo->edid_info);
    176204        gInfo->has_edid = true;
    177     } else {
    178         TRACE("getting EDID on port A (analog) failed : %s. "
    179             "Trying on port C (lvds)\n", strerror(error));
    180         bus.cookie = (void*)INTEL_I2C_IO_C;
    181         error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL);
    182         if (error == B_OK) {
    183             edid_dump(&gInfo->edid_info);
    184             gInfo->has_edid = true;
    185         } else {
    186             TRACE("getting EDID on port C failed : %s\n",
    187                 strerror(error));
    188 
    189             // We could not read any EDID info. Fallback to creating a list with
    190             // only the mode set up by the BIOS.
    191             // TODO: support lower modes via scaling and windowing
    192             if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
    193                     && (gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0) {
    194                 size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1)
    195                     & ~(B_PAGE_SIZE - 1);
    196 
    197                 display_mode* list;
    198                 area_id area = create_area("intel extreme modes",
    199                     (void**)&list, B_ANY_ADDRESS, size, B_NO_LOCK,
    200                     B_READ_AREA | B_WRITE_AREA);
    201                 if (area < B_OK)
    202                     return area;
    203 
    204                 memcpy(list, &gInfo->lvds_panel_mode, sizeof(display_mode));
    205 
    206                 gInfo->mode_list_area = area;
    207                 gInfo->mode_list = list;
    208                 gInfo->shared_info->mode_list_area = gInfo->mode_list_area;
    209                 gInfo->shared_info->mode_count = 1;
    210                 return B_OK;
    211             }
     205
     206        // TODO: We may want to probe multiple GPIO pins here
     207        // someday and store valid ones for multi-head support.
     208        // For now, we break on the first valid one.
     209        break;
     210    }
     211
     212    if (!gInfo->has_edid) {
     213        // We could not read any EDID info.
     214        if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
     215            && (gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0) {
     216            // If LVDS, fallback to lvds_panel_mode
     217            size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1)
     218                & ~(B_PAGE_SIZE - 1);
     219
     220            display_mode* list;
     221            area_id area = create_area("intel extreme modes",
     222                (void**)&list, B_ANY_ADDRESS, size, B_NO_LOCK,
     223                B_READ_AREA | B_WRITE_AREA);
     224            if (area < B_OK)
     225                return area;
     226
     227            memcpy(list, &gInfo->lvds_panel_mode, sizeof(display_mode));
     228
     229            gInfo->mode_list_area = area;
     230            gInfo->mode_list = list;
     231            gInfo->shared_info->mode_list_area = gInfo->mode_list_area;
     232            gInfo->shared_info->mode_count = 1;
     233            return B_OK;
    212234        }
    213235    }
    214236