diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 7d5c4159e0..006a0af029 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -24,9 +24,12 @@ #define INTEL_TYPE_GROUP_MASK 0xf0 #define INTEL_TYPE_7xx 0x01 #define INTEL_TYPE_8xx 0x02 -#define INTEL_TYPE_9xx 0x03 +#define INTEL_TYPE_9xx 0x04 #define INTEL_TYPE_83x 0x10 #define INTEL_TYPE_85x 0x20 +#define INTEL_TYPE_915 0x10 +#define INTEL_TYPE_945 0x20 +#define INTEL_TYPE_965 0x40 #define DEVICE_NAME "intel_extreme" #define INTEL_ACCELERANT_NAME "intel_extreme.accelerant" @@ -220,9 +223,12 @@ struct intel_free_graphics_memory { #define DISPLAY_PLL_2X_CLOCK (1UL << 30) #define DISPLAY_PLL_SYNC_LOCK_ENABLED (1UL << 29) #define DISPLAY_PLL_NO_VGA_CONTROL (1UL << 28) +#define DISPLAY_PLL_MODE_ANALOG (1UL << 26) +#define DISPLAY_PLL_DIVIDE_HIGH (1UL << 24) #define DISPLAY_PLL_DIVIDE_4X (1UL << 23) -#define DISPLAY_PLL_POST_DIVISOR_MASK 0x001f0000 -#define DISPLAY_PLL_POST_DIVISOR_SHIFT 16 +#define DISPLAY_PLL_POST1_DIVISOR_MASK 0x001f0000 +#define DISPLAY_PLL_9xx_POST1_DIVISOR_MASK 0x00ff0000 +#define DISPLAY_PLL_POST1_DIVISOR_SHIFT 16 #define DISPLAY_PLL_DIVISOR_1 (1UL << 8) #define DISPLAY_PLL_N_DIVISOR_MASK 0x001f0000 #define DISPLAY_PLL_M1_DIVISOR_MASK 0x00001f00 @@ -230,6 +236,7 @@ struct intel_free_graphics_memory { #define DISPLAY_PLL_N_DIVISOR_SHIFT 16 #define DISPLAY_PLL_M1_DIVISOR_SHIFT 8 #define DISPLAY_PLL_M2_DIVISOR_SHIFT 0 +#define DISPLAY_PLL_PULSE_PHASE_SHIFT 9 #define INTEL_DISPLAY_A_ANALOG_PORT 0x61100 #define DISPLAY_MONITOR_PORT_ENABLED (1UL << 31) diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 1f7cd744a5..20ff78631b 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -1,7 +1,10 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * + * Support for i915 chipset and up based on the X driver, + * Copyright 2006 Intel Corporation. + * * Authors: * Axel Dörfler, axeld@pinc-software.de */ @@ -11,6 +14,7 @@ #include "accelerant.h" #include "utility.h" +#include #include #include @@ -29,6 +33,40 @@ extern "C" void _sPrintf(const char *format, ...); (B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS | B_DPMS | B_SUPPORTS_OVERLAYS) +struct display_registers { + uint32 pll; + uint32 divisors; + uint32 control; + uint32 pipe_config; + uint32 horiz_total; + uint32 horiz_blank; + uint32 horiz_sync; + uint32 vert_total; + uint32 vert_blank; + uint32 vert_sync; + uint32 size; + uint32 stride; + uint32 position; + uint32 pipe_source; +}; + +struct pll_divisors { + uint32 post; + uint32 post1; + uint32 post2; + bool post2_high; + uint32 n; + uint32 m; + uint32 m1; + uint32 m2; +}; + +struct pll_limits { + pll_divisors min; + pll_divisors max; + float min_post2_frequency; +}; + static const display_mode kBaseModeList[] = { {{25175, 640, 656, 752, 800, 350, 387, 389, 449, B_POSITIVE_HSYNC}, B_CMAP8, 640, 350, 0, 0, MODE_FLAGS}, /* 640x350 - www.epanorama.net/documents/pc/vga_timing.html) */ {{25175, 640, 656, 752, 800, 400, 412, 414, 449, B_POSITIVE_VSYNC}, B_CMAP8, 640, 400, 0, 0, MODE_FLAGS}, /* 640x400 - www.epanorama.net/documents/pc/vga_timing.html) */ @@ -69,10 +107,10 @@ static const uint32 kNumBaseModes = sizeof(kBaseModeList) / sizeof(display_mode) static const uint32 kMaxNumModes = kNumBaseModes * 4; -/** Creates the initial mode list of the primary accelerant. - * It's called from intel_init_accelerant(). - */ - +/*! + Creates the initial mode list of the primary accelerant. + It's called from intel_init_accelerant(). +*/ status_t create_mode_list(void) { @@ -119,30 +157,95 @@ wait_for_vblank(void) static void -compute_pll_divisors(const display_mode ¤t, uint32 &postDivisor, - uint32 &nDivisor, uint32 &m1Divisor, uint32 &m2Divisor) +get_pll_limits(pll_limits &limits) +{ + // Note, the limits are taken from the X driver; they have not yet been tested + + if ((gInfo->shared_info->device_type & INTEL_TYPE_9xx) != 0) { + // TODO: support LVDS output limits as well + static const pll_limits kLimits = { + // p, p1, p2, high, n, m, m1, m2 + { 5, 1, 5, false, 5, 70, 12, 7}, // min + { 80, 8, 10, true, 10, 120, 22, 11}, // max + 200000 + }; + limits = kLimits; + } else { + // TODO: support LVDS output limits as well + static const pll_limits kLimits = { + // p, p1, p2, high, n, m, m1, m2 + { 4, 2, 2, false, 5, 96, 20, 8}, + {128, 33, 4, true, 18, 140, 28, 18}, + 165000 + }; + limits = kLimits; + } + + TRACE(("PLL limits, min: p %lu (p1 %lu, p2 %lu), n %lu, m %lu (m1 %lu, m2 %lu)\n", + limits.min.post, limits.min.post1, limits.min.post2, limits.min.n, + limits.min.m, limits.min.m1, limits.min.m2)); + TRACE(("PLL limits, max: p %lu (p1 %lu, p2 %lu), n %lu, m %lu (m1 %lu, m2 %lu)\n", + limits.max.post, limits.max.post1, limits.max.post2, limits.max.n, + limits.max.m, limits.max.m1, limits.max.m2)); +} + + +static bool +valid_pll_divisors(const pll_divisors& divisors, const pll_limits& limits) +{ + pll_info &info = gInfo->shared_info->pll_info; + uint32 vco = info.reference_frequency * divisors.m / divisors.n; + uint32 frequency = vco / divisors.post; + + if (divisors.post < limits.min.post || divisors.post > limits.max.post + || divisors.m < limits.min.m || divisors.m > limits.max.m + || frequency < info.min_frequency || frequency > info.max_frequency) + return false; + + return true; +} + + +static void +compute_pll_divisors(const display_mode ¤t, pll_divisors& divisors) { float requestedPixelClock = current.timing.pixel_clock / 1000.0f; float referenceClock = gInfo->shared_info->pll_info.reference_frequency / 1000.0f; + pll_limits limits; + get_pll_limits(limits); TRACE(("required MHz: %g\n", requestedPixelClock)); + if (current.timing.pixel_clock < limits.min_post2_frequency) { + divisors.post2 = limits.min.post2; + divisors.post2_high = limits.min.post2_high; + } else { + divisors.post2 = limits.max.post2; + divisors.post2_high = limits.max.post2_high; + } + float best = requestedPixelClock; - uint32 bestP = 0, bestN = 0, bestM = 0; + pll_divisors bestDivisors; - // Note, the limits are taken from the X driver; they have not yet been tested + for (divisors.post1 = limits.min.post1; divisors.post1 <= limits.max.post1; + divisors.post1++) { + for (divisors.n = limits.min.n; divisors.n <= limits.max.n; divisors.n++) { + 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++) { + divisors.m = 5 * divisors.m1 + divisors.m2; + divisors.post = divisors.post1 * divisors.post2; - for (uint32 p = 3; p < 31; p++) { - for (uint32 n = 3; n < 16; n++) { - for (uint32 m1 = 6; m1 < 26; m1++) { - for (uint32 m2 = 6; m2 < 16; m2++) { - uint32 m = m1 * 5 + m2; - float error = fabs(requestedPixelClock - ((referenceClock * m) / n) / (p*4)); + if (!valid_pll_divisors(divisors, limits)) + continue; + + float error = fabs(requestedPixelClock + - ((referenceClock * divisors.m) / divisors.n) / divisors.post); if (error < best) { best = error; - bestP = p; - bestN = n; - bestM = m; + bestDivisors = divisors; + if (error == 0) break; } @@ -151,19 +254,12 @@ compute_pll_divisors(const display_mode ¤t, uint32 &postDivisor, } } - postDivisor = bestP; - nDivisor = bestN; + divisors = bestDivisors; - TRACE(("found: %g MHz (p = %lu, n = %lu, m = %lu (m1 = %lu, m2 = %lu)\n", - ((referenceClock * bestM) / bestN) / (bestP*4), bestP, bestN, bestM, - m1Divisor, m2Divisor)); - - m1Divisor = bestM / 5; - m2Divisor = bestM % 5; - while (m2Divisor < 6) { - m1Divisor--; - m2Divisor += 5; - } + TRACE(("found: %g MHz, p = %lu (p1 = %lu, p2 = %lu), n = %lu, m = %lu (m1 = %lu, m2 = %lu)\n", + ((referenceClock * divisors.m) / divisors.n) / divisors.post, + divisors.post, divisors.post1, divisors.post2, divisors.n, + divisors.m, divisors.m1, divisors.m2)); } @@ -216,7 +312,8 @@ status_t intel_get_mode_list(display_mode *modeList) { TRACE(("intel_get_mode_info()\n")); - memcpy(modeList, gInfo->mode_list, gInfo->shared_info->mode_count * sizeof(display_mode)); + memcpy(modeList, gInfo->mode_list, + gInfo->shared_info->mode_count * sizeof(display_mode)); return B_OK; } @@ -256,14 +353,34 @@ intel_set_display_mode(display_mode *mode) if (mode == NULL || intel_propose_display_mode(&target, mode, mode)) return B_BAD_VALUE; + uint32 colorMode, bytesPerRow, bitsPerPixel; + get_color_space_format(target, colorMode, bytesPerRow, bitsPerPixel); + +debug_printf("new resolution: %ux%ux%lu\n", target.timing.h_display, target.timing.v_display, bitsPerPixel); +#if 0 +static bool first = true; +if (first) { + int fd = open("/boot/home/ie_.regs", O_CREAT | O_WRONLY, 0644); + if (fd >= 0) { + for (int32 i = 0; i < 0x80000; i += 16) { + char line[512]; + int length = sprintf(line, "%05lx: %08lx %08lx %08lx %08lx\n", + i, read32(i), read32(i + 4), read32(i + 8), read32(i + 12)); + write(fd, line, length); + } + close(fd); + sync(); + } + first = false; +} +#endif + //return B_ERROR; + intel_shared_info &sharedInfo = *gInfo->shared_info; Autolock locker(sharedInfo.accelerant_lock); set_display_power_mode(B_DPMS_OFF); - uint32 colorMode, bytesPerRow, bitsPerPixel; - get_color_space_format(target, colorMode, bytesPerRow, bitsPerPixel); - // free old and allocate new frame buffer in graphics memory intel_free_memory(gInfo->frame_buffer_handle); @@ -312,8 +429,8 @@ intel_set_display_mode(display_mode *mode) | ((target.timing.flags & B_POSITIVE_HSYNC) != 0 ? DISPLAY_MONITOR_POSITIVE_HSYNC : 0) | ((target.timing.flags & B_POSITIVE_VSYNC) != 0 ? DISPLAY_MONITOR_POSITIVE_VSYNC : 0)); - uint32 postDivisor, nDivisor, m1Divisor, m2Divisor; - compute_pll_divisors(target, postDivisor, nDivisor, m1Divisor, m2Divisor); + pll_divisors divisors; + compute_pll_divisors(target, divisors); // switch divisor register with every mode change (not required) uint32 divisorRegister; @@ -323,13 +440,41 @@ intel_set_display_mode(display_mode *mode) divisorRegister = INTEL_DISPLAY_A_PLL_DIVISOR_0; write32(divisorRegister, - (((nDivisor - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT) & DISPLAY_PLL_N_DIVISOR_MASK) - | (((m1Divisor - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT) & DISPLAY_PLL_M1_DIVISOR_MASK) - | (((m2Divisor - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT) & DISPLAY_PLL_M2_DIVISOR_MASK)); + (((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 & INTEL_TYPE_9xx) != 0) { +// 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; + + pll |= DISPLAY_PLL_MODE_ANALOG; + + if ((gInfo->shared_info->device_type & INTEL_TYPE_GROUP_MASK) == INTEL_TYPE_965) + pll |= 6 << DISPLAY_PLL_PULSE_PHASE_SHIFT; + } else { + if (divisors.post2_high) + pll |= DISPLAY_PLL_DIVIDE_4X; + pll |= DISPLAY_PLL_2X_CLOCK; + pll |= (((divisors.post1 - 2) << DISPLAY_PLL_POST1_DIVISOR_SHIFT) + & DISPLAY_PLL_POST1_DIVISOR_MASK); + } + + pll |= (divisorRegister == INTEL_DISPLAY_A_PLL_DIVISOR_1 ? DISPLAY_PLL_DIVISOR_1 : 0); + + debug_printf("PLL is %#lx, write: %#lx\n", read32(INTEL_DISPLAY_A_PLL), pll); + write32(INTEL_DISPLAY_A_PLL, pll); +#if 0 write32(INTEL_DISPLAY_A_PLL, DISPLAY_PLL_ENABLED | DISPLAY_PLL_2X_CLOCK | DISPLAY_PLL_NO_VGA_CONTROL | DISPLAY_PLL_DIVIDE_4X - | (((postDivisor - 2) << DISPLAY_PLL_POST_DIVISOR_SHIFT) & DISPLAY_PLL_POST_DIVISOR_MASK) + | (((divisors.post1 - 2) << DISPLAY_PLL_POST1_DIVISOR_SHIFT) & DISPLAY_PLL_POST1_DIVISOR_MASK) | (divisorRegister == INTEL_DISPLAY_A_PLL_DIVISOR_1 ? DISPLAY_PLL_DIVISOR_1 : 0)); +#endif } // These two have to be set for display B, too - this obviously means @@ -366,20 +511,6 @@ intel_set_display_mode(display_mode *mode) sharedInfo.current_mode = target; sharedInfo.bits_per_pixel = bitsPerPixel; -#if 0 -int fd = open("/boot/home/ie.regs", O_CREAT | O_WRONLY, 0644); -if (fd >= 0) { - for (int32 i = 0; i < 0x80000; i += 16) { - char line[512]; - int length = sprintf(line, "%05lx: %08lx %08lx %08lx %08lx\n", - i, read32(i), read32(i + 4), read32(i + 8), read32(i + 12)); - write(fd, line, length); - } - close(fd); - sync(); -} -#endif - return B_OK; } @@ -388,7 +519,96 @@ status_t intel_get_display_mode(display_mode *_currentMode) { TRACE(("intel_get_display_mode()\n")); - *_currentMode = gInfo->shared_info->current_mode; + + display_mode &mode = *_currentMode; + + uint32 pll = read32(INTEL_DISPLAY_A_PLL); + uint32 pllDivisor = read32((pll & DISPLAY_PLL_DIVISOR_1) != 0 + ? INTEL_DISPLAY_A_PLL_DIVISOR_1 : INTEL_DISPLAY_A_PLL_DIVISOR_0); + + 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; + + pll_limits limits; + get_pll_limits(limits); + + if ((gInfo->shared_info->device_type & INTEL_TYPE_9xx) != 0) { + divisors.post1 = (pll & DISPLAY_PLL_9xx_POST1_DIVISOR_MASK) + >> DISPLAY_PLL_POST1_DIVISOR_SHIFT; + + if ((pll & DISPLAY_PLL_DIVIDE_HIGH) != 0) + divisors.post2 = limits.max.post2; + else + divisors.post2 = limits.min.post2; + } else { + // 8xx + divisors.post1 = (pll & DISPLAY_PLL_POST1_DIVISOR_MASK) + >> DISPLAY_PLL_POST1_DIVISOR_SHIFT; + + if ((pll & DISPLAY_PLL_DIVIDE_4X) != 0) + divisors.post2 = limits.max.post2; + else + divisors.post2 = limits.min.post2; + } + + divisors.m = 5 * divisors.m1 + divisors.m2; + divisors.post = divisors.post1 * divisors.post2; + + float referenceClock = gInfo->shared_info->pll_info.reference_frequency / 1000.0f; + float pixelClock = ((referenceClock * divisors.m) / divisors.n) / divisors.post; + + // timing + + mode.timing.pixel_clock = uint32(pixelClock * 1000); + mode.timing.flags = 0; + + uint32 value = read32(INTEL_DISPLAY_A_HTOTAL); + mode.timing.h_total = (value >> 16) + 1; + mode.timing.h_display = (value & 0xffff) + 1; + + value = read32(INTEL_DISPLAY_A_HSYNC); + mode.timing.h_sync_end = (value >> 16) + 1; + mode.timing.h_sync_start = (value & 0xffff) + 1; + + value = read32(INTEL_DISPLAY_A_VTOTAL); + mode.timing.v_total = (value >> 16) + 1; + mode.timing.v_display = (value & 0xffff) + 1; + + value = read32(INTEL_DISPLAY_A_VSYNC); + mode.timing.v_sync_end = (value >> 16) + 1; + mode.timing.v_sync_start = (value & 0xffff) + 1; + + // image size and color space + + value = read32(INTEL_DISPLAY_A_IMAGE_SIZE); + mode.virtual_width = (value >> 16) + 1; + mode.virtual_height = (value & 0xffff) + 1; + + value = read32(INTEL_DISPLAY_A_CONTROL); + switch (value & DISPLAY_CONTROL_COLOR_MASK) { + case DISPLAY_CONTROL_RGB32: + default: + mode.space = B_RGB32; + break; + case DISPLAY_CONTROL_RGB16: + mode.space = B_RGB16; + break; + case DISPLAY_CONTROL_RGB15: + mode.space = B_RGB15; + break; + case DISPLAY_CONTROL_CMAP8: + mode.space = B_CMAP8; + break; + } + + mode.h_display_start = 0; + mode.v_display_start = 0; + mode.flags = 0; return B_OK; } diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp index 2fc79a43b8..5f1c0323bd 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/device.cpp @@ -57,7 +57,7 @@ device_hooks gDeviceHooks = { static status_t -checkDeviceInfo(struct intel_info *info) +check_device_info(struct intel_info *info) { if (!info || info->cookie_magic != INTEL_COOKIE_MAGIC) return B_BAD_VALUE; @@ -66,6 +66,38 @@ checkDeviceInfo(struct intel_info *info) } +static int +getset_register(int argc, char **argv) +{ + if (argc < 2 || argc > 3) { + kprintf("usage: %s [set-to-value]\n", argv[0]); + return 0; + } + + uint32 reg = parse_expression(argv[1]); + uint32 value = 0; + bool set = argc == 3; + if (set) + value = parse_expression(argv[2]); + + kprintf("intel_extreme register %#lx\n", reg); + + intel_info &info = *gDeviceInfo[0]; + uint32 oldValue = read32(info.registers + reg); + + kprintf(" %svalue: %#lx (%lu)\n", set ? "old " : "", oldValue, oldValue); + + if (set) { + write32(info.registers + reg, value); + + value = read32(info.registers + reg); + kprintf(" new value: %#lx (%lu)\n", value, value); + } + + return 0; +} + + // #pragma mark - Device Hooks @@ -94,10 +126,15 @@ device_open(const char *name, uint32 /*flags*/, void **_cookie) status_t status = B_OK; + // TODO: the second open will succeed even though the first one failed! if (info->open_count++ == 0) { // this device has been opened for the first time, so // we allocate needed resources and initialize the structure status = intel_extreme_init(*info); + if (status == B_OK) { + add_debugger_command("ie_reg", getset_register, + "dumps or sets the specified intel_extreme register"); + } } release_lock(&gLock); @@ -112,11 +149,10 @@ device_close(void *data) TRACE((DEVICE_NAME ": close\n")); struct intel_info *info; - if (checkDeviceInfo(info = (intel_info *)data) != B_OK) + if (check_device_info(info = (intel_info *)data) != B_OK) return B_BAD_VALUE; info->cookie_magic = INTEL_FREE_COOKIE_MAGIC; - return B_OK; } @@ -135,6 +171,7 @@ device_free(void *data) if (info->open_count-- == 1) { // release info structure info->cookie_magic = 0; + remove_debugger_command("ie_reg", getset_register); intel_extreme_uninit(*info); } @@ -149,7 +186,7 @@ device_ioctl(void *data, uint32 op, void *buffer, size_t bufferLength) { struct intel_info *info; - if (checkDeviceInfo(info = (intel_info *)data) != B_OK) + if (check_device_info(info = (intel_info *)data) != B_OK) return B_BAD_VALUE; switch (op) { 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 9ec8b377bf..24fa5e4e02 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -49,6 +49,7 @@ const struct supported_device { {0x2592, INTEL_TYPE_9xx, "i915GM"}, {0x2772, INTEL_TYPE_9xx, "i945G"}, {0x27a2, INTEL_TYPE_9xx, "i945GM"}, + {0x29a2, INTEL_TYPE_9xx | INTEL_TYPE_965, "i965G"} #endif }; diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index 549742c442..2ee7da038b 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -418,14 +418,14 @@ intel_extreme_init(intel_info &info) info.shared_info->frame_buffer_offset = 0; info.shared_info->dpms_mode = B_DPMS_ON; - if (info.device_type == INTEL_TYPE_9xx) { + if ((info.device_type & INTEL_TYPE_9xx) != 0) { info.shared_info->pll_info.reference_frequency = 96000; // 96 kHz info.shared_info->pll_info.max_frequency = 400000; // 400 MHz RAM DAC speed - info.shared_info->pll_info.min_frequency = 20000; // 20 MHz (not tested) + info.shared_info->pll_info.min_frequency = 20000; // 20 MHz } else { info.shared_info->pll_info.reference_frequency = 48000; // 48 kHz info.shared_info->pll_info.max_frequency = 350000; // 350 MHz RAM DAC speed - info.shared_info->pll_info.min_frequency = 25000; // 25 MHz (not tested) + info.shared_info->pll_info.min_frequency = 25000; // 25 MHz } info.shared_info->pll_info.divisor_register = INTEL_DISPLAY_A_PLL_DIVISOR_0;