/*! Creates the initial mode list of the primary accelerant. It's called from intel_init_accelerant(). */ status_t create_mode_list(void) { i2c_bus bus; bus.cookie = (void*)INTEL_I2C_IO_A; bus.set_signals = &set_i2c_signals; bus.get_signals = &get_i2c_signals; ddc2_init_timing(&bus); if (ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL) == B_OK) { edid_dump(&gInfo->edid_info); gInfo->has_edid = true; } else { TRACE(("intel_extreme: getting EDID failed!\n")); } // TODO: support lower modes via scaling and windowing if (gInfo->head_mode & HEAD_MODE_LVDS_PANEL && ((gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0)) { size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); display_mode *list; area_id area = create_area("intel extreme modes", (void **)&list, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (area < B_OK) return area; memcpy(list, &gInfo->lvds_panel_mode, sizeof(display_mode)); gInfo->mode_list_area = area; gInfo->mode_list = list; gInfo->shared_info->mode_list_area = gInfo->mode_list_area; gInfo->shared_info->mode_count = 1; return B_OK; } // Otherwise return the 'real' list of modes display_mode *list; uint32 count = 0; gInfo->mode_list_area = create_display_modes("intel extreme modes", gInfo->has_edid ? &gInfo->edid_info : NULL, NULL, 0, NULL, 0, NULL, &list, &count); if (gInfo->mode_list_area < B_OK) return gInfo->mode_list_area; gInfo->mode_list = list; gInfo->shared_info->mode_list_area = gInfo->mode_list_area; gInfo->shared_info->mode_count = count; return B_OK; }
bool Savage_GetEdidInfo(edid1_info& edidInfo) { // Get the EDID info and return true if successful. SharedInfo& si = *gInfo.sharedInfo; uint32 DDCPort = 0; switch (si.chipType) { case S3_SAVAGE_3D: case S3_SAVAGE_MX: case S3_SUPERSAVAGE: case S3_SAVAGE2000: DDCPort = 0xAA; break; case S3_SAVAGE4: case S3_PROSAVAGE: case S3_TWISTER: case S3_PROSAVAGE_DDR: DDCPort = 0xB1; break; } i2c_bus bus; bus.cookie = (void*)DDCPort; bus.set_signals = &SetI2CSignals; bus.get_signals = &GetI2CSignals; ddc2_init_timing(&bus); uint8 tmp = ReadCrtcReg(DDCPort); WriteCrtcReg(DDCPort, tmp | 0x13); bool bResult = (ddc2_read_edid1(&bus, &edidInfo, NULL, NULL) == B_OK); WriteCrtcReg(DDCPort, tmp); return bResult; }
/*! Creates the initial mode list of the primary accelerant. It's called from intel_init_accelerant(). */ status_t create_mode_list(void) { i2c_bus bus; bus.cookie = (void*)INTEL_I2C_IO_A; bus.set_signals = &set_i2c_signals; bus.get_signals = &get_i2c_signals; ddc2_init_timing(&bus); status_t error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL); if (error == B_OK) { edid_dump(&gInfo->edid_info); gInfo->has_edid = true; } else { TRACE(("intel_extreme: getting EDID on port A (analog) failed : %s. " "Trying on port C (lvds)\n", strerror(error))); bus.cookie = (void*)INTEL_I2C_IO_C; error = ddc2_read_edid1(&bus, &gInfo->edid_info, NULL, NULL); if (error == B_OK) { edid_dump(&gInfo->edid_info); gInfo->has_edid = true; } else { TRACE(("intel_extreme: getting EDID on port C failed : %s\n", strerror(error))); // We could not read any EDID info. Fallback to creating a list with // only the mode set up by the BIOS. // TODO: support lower modes via scaling and windowing if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0 && (gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0) { size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); display_mode* list; area_id area = create_area("intel extreme modes", (void**)&list, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if (area < B_OK) return area; memcpy(list, &gInfo->lvds_panel_mode, sizeof(display_mode)); gInfo->mode_list_area = area; gInfo->mode_list = list; gInfo->shared_info->mode_list_area = gInfo->mode_list_area; gInfo->shared_info->mode_count = 1; return B_OK; } } } // Otherwise return the 'real' list of modes display_mode* list; uint32 count = 0; gInfo->mode_list_area = create_display_modes("intel extreme modes", gInfo->has_edid ? &gInfo->edid_info : NULL, NULL, 0, NULL, 0, NULL, &list, &count); if (gInfo->mode_list_area < B_OK) return gInfo->mode_list_area; gInfo->mode_list = list; gInfo->shared_info->mode_list_area = gInfo->mode_list_area; gInfo->shared_info->mode_count = count; return B_OK; }