Ticket #3846: 0001-Intel_extreme-i855g-support-3846.patch

File 0001-Intel_extreme-i855g-support-3846.patch, 18.6 KB (added by pulkomandy, 11 years ago)

Patch from github rebased on current sources.

  • headers/private/graphics/intel_extreme/intel_extreme.h

    From 5819a94c7a7e6ecf4a529b56d0ca0892af135fd7 Mon Sep 17 00:00:00 2001
    From: Adrien Destugues <pulkomandy@pulkomandy.tk>
    Date: Fri, 17 Jan 2014 10:55:03 +0100
    Subject: [PATCH] Intel_extreme i855g support (#3846)
    
    Convert proposed patch into git more suitable git format and rebase
    against latest version of driver.
    https://github.com/druga/haiku-stuff/tree/master/intel_extreme
    ---
     .../private/graphics/intel_extreme/intel_extreme.h |   3 +
     src/add-ons/accelerants/intel_extreme/mode.cpp     | 122 ++++++---
     .../kernel/drivers/graphics/intel_extreme/Jamfile  |   1 +
     .../kernel/drivers/graphics/intel_extreme/bios.cpp | 298 +++++++++++++++++++++
     .../graphics/intel_extreme/intel_extreme.cpp       |   6 +
     5 files changed, 399 insertions(+), 31 deletions(-)
     create mode 100644 src/add-ons/kernel/drivers/graphics/intel_extreme/bios.cpp
    
    diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h
    index b8e969f..7c4c957 100644
    a b struct intel_shared_info {  
    173173    addr_t          frame_buffer;
    174174    uint32          frame_buffer_offset;
    175175
     176    bool            got_vbt;
     177    bool            single_head_locked;
     178
    176179    struct lock     accelerant_lock;
    177180    struct lock     engine_lock;
    178181
  • 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 00182b8..f484863 100644
    a b struct pll_limits {  
    7474};
    7575
    7676
     77static struct display_mode_hook {
     78    bool active;
     79    display_mode *dm;
     80    struct {
     81        uint16 width;
     82        uint16 height;
     83        uint16 space;
     84    } mode;
     85} display_mode_hook;
     86
     87
     88static void mode_fill_missing_bits(display_mode *, uint32);
     89
     90
    7791static status_t
    7892get_i2c_signals(void* cookie, int* _clock, int* _data)
    7993{
    compute_pll_divisors(const display_mode &current, pll_divisors& divisors,  
    283297
    284298
    285299static void
     300mode_fill_missing_bits(display_mode *mode, uint32 cntrl)
     301{
     302    uint32 value = read32(cntrl);
     303
     304    switch (value & DISPLAY_CONTROL_COLOR_MASK) {
     305        case DISPLAY_CONTROL_RGB32:
     306        default:
     307            mode->space = B_RGB32;
     308            break;
     309        case DISPLAY_CONTROL_RGB16:
     310            mode->space = B_RGB16;
     311            break;
     312        case DISPLAY_CONTROL_RGB15:
     313            mode->space = B_RGB15;
     314            break;
     315        case DISPLAY_CONTROL_CMAP8:
     316            mode->space = B_CMAP8;
     317            break;
     318    }
     319
     320    mode->flags = B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS | B_DPMS;
     321}
     322
     323
     324static void
    286325retrieve_current_mode(display_mode& mode, uint32 pllRegister)
    287326{
    288327    uint32 pll = read32(pllRegister);
    retrieve_current_mode(display_mode& mode, uint32 pllRegister)  
    411450    if (mode.virtual_height < mode.timing.v_display)
    412451        mode.virtual_height = mode.timing.v_display;
    413452
    414     value = read32(controlRegister);
    415     switch (value & DISPLAY_CONTROL_COLOR_MASK) {
    416         case DISPLAY_CONTROL_RGB32:
    417         default:
    418             mode.space = B_RGB32;
    419             break;
    420         case DISPLAY_CONTROL_RGB16:
    421             mode.space = B_RGB16;
    422             break;
    423         case DISPLAY_CONTROL_RGB15:
    424             mode.space = B_RGB15;
    425             break;
    426         case DISPLAY_CONTROL_CMAP8:
    427             mode.space = B_CMAP8;
    428             break;
    429     }
     453    mode_fill_missing_bits(&mode, controlRegister);
    430454
    431455    mode.h_display_start = 0;
    432456    mode.v_display_start = 0;
    433     mode.flags = B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS
    434         | B_DPMS;
    435457    if (gInfo->overlay_registers != NULL) {
    436458        mode.flags |= B_SUPPORTS_OVERLAYS;
    437459    }
    set_frame_buffer_base()  
    535557    uint32 baseRegister;
    536558    uint32 surfaceRegister;
    537559
    538     if (gInfo->head_mode & HEAD_MODE_A_ANALOG) {
    539         baseRegister = INTEL_DISPLAY_A_BASE;
    540         surfaceRegister = INTEL_DISPLAY_A_SURFACE;
    541     } else {
     560    if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) {
    542561        baseRegister = INTEL_DISPLAY_B_BASE;
    543562        surfaceRegister = INTEL_DISPLAY_B_SURFACE;
     563    } else {
     564        baseRegister = INTEL_DISPLAY_A_BASE;
     565        surfaceRegister = INTEL_DISPLAY_A_SURFACE;
    544566    }
    545567
    546568    if (sharedInfo.device_type.InGroup(INTEL_TYPE_96x)
    create_mode_list(void)  
    578600    if (error == B_OK) {
    579601        edid_dump(&gInfo->edid_info);
    580602        gInfo->has_edid = true;
     603        if (gInfo->shared_info->single_head_locked)
     604            gInfo->head_mode = HEAD_MODE_A_ANALOG;
    581605    } else {
    582606        TRACE("getting EDID on port A (analog) failed : %s. "
    583607            "Trying on port C (lvds)\n", strerror(error));
    create_mode_list(void)  
    593617            // We could not read any EDID info. Fallback to creating a list with
    594618            // only the mode set up by the BIOS.
    595619            // TODO: support lower modes via scaling and windowing
    596             if ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
    597                     && (gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0) {
     620            if (((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
     621                    && (gInfo->head_mode & HEAD_MODE_A_ANALOG) == 0)
     622                    || ((gInfo->head_mode & HEAD_MODE_LVDS_PANEL) != 0
     623                    && gInfo->shared_info->got_vbt)) {
    598624                size_t size = (sizeof(display_mode) + B_PAGE_SIZE - 1)
    599625                    & ~(B_PAGE_SIZE - 1);
    600626
    create_mode_list(void)  
    605631                if (area < B_OK)
    606632                    return area;
    607633
    608                 memcpy(list, &gInfo->lvds_panel_mode, sizeof(display_mode));
     634                // Prefer information dumped directly from VBT, as the BIOS
     635                // one may have display scaling, but only do this if the VBT
     636                // resolution is higher than the BIOS one.
     637                if (gInfo->shared_info->got_vbt
     638                    && gInfo->shared_info->current_mode.virtual_width
     639                        >= gInfo->lvds_panel_mode.virtual_width
     640                    && gInfo->shared_info->current_mode.virtual_height
     641                        >= gInfo->lvds_panel_mode.virtual_height) {
     642                    memcpy(list, &gInfo->shared_info->current_mode,
     643                        sizeof(display_mode));
     644                    mode_fill_missing_bits(list, INTEL_DISPLAY_B_CONTROL);
     645                } else {
     646                    memcpy(list, &gInfo->lvds_panel_mode,
     647                        sizeof(display_mode));
     648
     649                    if (gInfo->shared_info->got_vbt)
     650                        TRACE("intel_extreme: ignoring VBT mode.");
     651                }
     652
     653                // We can also make this the default resolution, if the user
     654                // didn't pick one yet.
     655                display_mode_hook.active = true;
     656                display_mode_hook.dm = list;
    609657
    610658                gInfo->mode_list_area = area;
    611659                gInfo->mode_list = list;
    intel_propose_display_mode(display_mode* target, const display_mode* low,  
    717765status_t
    718766intel_set_display_mode(display_mode* mode)
    719767{
    720     TRACE("%s(%" B_PRIu16 "x%" B_PRIu16 ")\n", __func__,
    721         mode->virtual_width, mode->virtual_height);
     768    if (display_mode_hook.active) {
     769        mode = display_mode_hook.dm;
     770        display_mode_hook.active = false;
     771    }
    722772
    723773    if (mode == NULL)
    724774        return B_BAD_VALUE;
    725775
     776    TRACE("%s(%" B_PRIu16 "x%" B_PRIu16 ")\n", __func__,
     777        mode->virtual_width, mode->virtual_height);
     778
    726779    display_mode target = *mode;
    727780
    728781    // TODO: it may be acceptable to continue when using panel fitting or
    intel_set_display_mode(display_mode* mode)  
    736789    uint32 colorMode, bytesPerRow, bitsPerPixel;
    737790    get_color_space_format(target, colorMode, bytesPerRow, bitsPerPixel);
    738791
    739     // TODO: do not go further if the mode is identical to the current one.
    740     // This would avoid the screen being off when switching workspaces when they
    741     // have the same resolution.
     792    // avoid screen being off when switching workspaces when they have the same
     793    // resolution.
     794    if (target.virtual_width == display_mode_hook.mode.width
     795        && target.virtual_height == display_mode_hook.mode.height
     796        && target.space == display_mode_hook.mode.space)
     797        return B_OK;
    742798
    743799#if 0
    744 static bool first = true;
     800static bool first = tru;
    745801if (first) {
    746802    int fd = open("/boot/home/ie_.regs", O_CREAT | O_WRONLY, 0644);
    747803    if (fd >= 0) {
    if (first) {  
    11741230    sharedInfo.current_mode = target;
    11751231    sharedInfo.bits_per_pixel = bitsPerPixel;
    11761232
     1233    display_mode_hook.mode.width = target.virtual_width;
     1234    display_mode_hook.mode.height = target.virtual_height;
     1235    display_mode_hook.mode.space = target.space;
     1236
    11771237    return B_OK;
    11781238}
    11791239
  • src/add-ons/kernel/drivers/graphics/intel_extreme/Jamfile

    diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/Jamfile b/src/add-ons/kernel/drivers/graphics/intel_extreme/Jamfile
    index 95bad2c..8ac97c6 100644
    a b UsePrivateHeaders graphics kernel ;  
    88UsePrivateHeaders shared ;
    99
    1010KernelAddon intel_extreme :
     11    bios.cpp
    1112    driver.cpp
    1213    device.cpp
    1314    intel_extreme.cpp
  • new file src/add-ons/kernel/drivers/graphics/intel_extreme/bios.cpp

    diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/bios.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/bios.cpp
    new file mode 100644
    index 0000000..f629928
    - +  
     1/* Written by Artem Falcon <lomka@gero.in> */
     2
     3#include <KernelExport.h>
     4#include "intel_extreme.h"
     5#include <string.h>
     6
     7#define TRACE_BIOS 1
     8#ifdef TRACE_BIOS
     9#       define TRACE(x) dprintf x
     10#else
     11#   define TRACE(x) ;
     12#endif
     13
     14/* for moving into intel_extreme_private.h */
     15#define VBIOS 0xc0000
     16#define INTEL_VBIOS_SIZE (64 * 1024) /* XXX */
     17
     18#define INTEL_BIOS_16(_addr) (vbios.memory[_addr] | \
     19        (vbios.memory[_addr + 1] << 8))
     20/* */
     21
     22/* subject of including into private/graphics/common/edid* */
     23#define _PIXEL_CLOCK_MHZ(x) (x[0] + (x[1] << 8)) / 100
     24
     25#define _PIXEL_CLOCK(x) (x[0] + (x[1] << 8)) * 10000
     26#define _H_ACTIVE(x) (x[2] + ((x[4] & 0xF0) << 4))
     27#define _H_BLANK(x) (x[3] + ((x[4] & 0x0F) << 8))
     28#define _H_SYNC_OFF(x) (x[8] + ((x[11] & 0xC0) << 2))
     29#define _H_SYNC_WIDTH(x) (x[9] + ((x[11] & 0x30) << 4))
     30#define _V_ACTIVE(x) (x[5] + ((x[7] & 0xF0) << 4))
     31#define _V_BLANK(x) (x[6] + ((x[7] & 0x0F) << 8))
     32#define _V_SYNC_OFF(x) ((x[10] >> 4) + ((x[11] & 0x0C) << 2))
     33#define _V_SYNC_WIDTH(x) ((x[10] & 0x0F) + ((x[11] & 0x03) << 4))
     34/* */
     35
     36struct vbt_header {
     37        uint8 signature[20];
     38        uint16 version;
     39        uint16 header_size;
     40        uint16 vbt_size;
     41        uint8 vbt_checksum;
     42        uint8 reserved0;
     43        uint32 bdb_offset;
     44        uint32 aim_offset[4];
     45} __attribute__((packed));
     46
     47struct bdb_header {
     48    uint8 signature[16];
     49    uint16 version;
     50    uint16 header_size;
     51    uint16 bdb_size;
     52    /* cutted */
     53} __attribute__((packed));
     54
     55struct lvds_bdb1 {
     56    uint8 id;
     57    uint16 size;
     58    uint8 panel_type;
     59    uint8 reserved0;
     60    uint16 caps;
     61} __attribute__((packed));
     62
     63struct lvds_bdb2_entry {
     64    uint16 lfp_info_offset;
     65    uint8 lfp_info_size;
     66    uint16 lfp_edid_dtd_offset;
     67    uint8 lfp_edid_dtd_size;
     68    uint16 lfp_edid_pid_offset;
     69    uint8 lfp_edid_pid_size;
     70} __attribute__((packed));
     71
     72struct lvds_bdb2 {
     73    uint8 id;
     74    uint16 size;
     75    uint8 table_size; /* unapproved */
     76    struct lvds_bdb2_entry panels[16];
     77} __attribute__((packed));
     78
     79struct lvds_bdb2_lfp_info {
     80    uint16 x_res;
     81    uint16 y_res;
     82    uint32 lvds_reg;
     83    uint32 lvds_reg_val;
     84    uint32 pp_on_reg;
     85    uint32 pp_on_reg_val;
     86    uint32 pp_off_reg;
     87    uint32 pp_off_reg_val;
     88    uint32 pp_cycle_reg;
     89    uint32 pp_cycle_reg_val;
     90    uint32 pfit_reg;
     91    uint32 pfit_reg_val;
     92    uint16 terminator;
     93} __attribute__((packed));
     94
     95static struct vbios {
     96    area_id area;
     97    uint8* memory;
     98    display_mode *shared_info;
     99    struct {
     100        uint16 hsync_start;
     101        uint16 hsync_end;
     102        uint16 hsync_total;
     103        uint16 vsync_start;
     104        uint16 vsync_end;
     105        uint16 vsync_total;
     106    } timings_common;
     107} vbios;
     108
     109static inline bool unmap_bios(area_id area, uint8* mem) {
     110        delete_area(area);
     111        mem = NULL;
     112
     113    return false;
     114}
     115
     116/* TO-DO: move to accelerant code, if possible */
     117
     118/* this is reimplementation, Haiku uses BIOS call and gets most
     119 * current panel info, we're, otherwise, digging in VBIOS memory
     120 * and parsing VBT tables to get native panel timings. This will
     121 * allow to get non-updated, PROM-programmed timings info when
     122 * compensation mode is off on your machine */
     123static bool
     124get_bios(void)
     125{
     126    int vbt_offset;
     127    struct vbt_header *vbt;
     128
     129    /* !!!DANGER!!!: mapping of BIOS using legacy location for now,
     130     * hence, if panel mode will be set using info from VBT, it will
     131     * be taken from primary card's VBIOS */
     132    vbios.area = map_physical_memory("VBIOS mapping",
     133        VBIOS, INTEL_VBIOS_SIZE, B_ANY_KERNEL_ADDRESS,
     134        B_READ_AREA, (void**)&(vbios.memory));
     135
     136    if (vbios.area < 0)
     137        return false;
     138
     139    TRACE((DEVICE_NAME ": mapping VBIOS: 0x%x -> %p\n",
     140        VBIOS, vbios.memory));
     141
     142    vbt_offset = INTEL_BIOS_16(0x1a);
     143    if (vbt_offset >= INTEL_VBIOS_SIZE) {
     144        TRACE(("intel_extreme: bad VBT offset : 0x%x\n",
     145            vbt_offset));
     146        return unmap_bios(vbios.area, vbios.memory);
     147    }
     148
     149    vbt = (struct vbt_header *)(vbios.memory + vbt_offset);
     150    if (memcmp(vbt->signature, "$VBT", 4) != 0) {
     151        TRACE(("intel_extreme: bad VBT signature: %20s\n",
     152            vbt->signature));
     153        return unmap_bios(vbios.area, vbios.memory);
     154    }
     155
     156    return true;
     157}
     158
     159static bool feed_shared_info(uint8* data)
     160{
     161    bool bogus = false;
     162
     163    /* handle bogus h/vtotal values, if got such */
     164    if (vbios.timings_common.hsync_end > vbios.timings_common.hsync_total) {
     165        vbios.timings_common.hsync_total =
     166            vbios.timings_common.hsync_end + 1;
     167        bogus = true;
     168        TRACE(("intel_extreme: got bogus htotal. Fixing\n"));
     169    }
     170    if (vbios.timings_common.vsync_end > vbios.timings_common.vsync_total) {
     171        vbios.timings_common.vsync_total =
     172            vbios.timings_common.vsync_end + 1;
     173        bogus = true;
     174        TRACE(("intel_extreme: got bogus vtotal. Fixing\n"));
     175    }
     176    /* */
     177    if (bogus)
     178        TRACE(("intel_extreme: adjusted LFP modeline: x%d Hz,\t%d "
     179            "%d %d %d %d   %d %d %d %d\n",
     180                _PIXEL_CLOCK(data) / (
     181                    (_H_ACTIVE(data) + _H_BLANK(data))
     182                      * (_V_ACTIVE(data) + _V_BLANK(data))
     183                    ),
     184                _PIXEL_CLOCK_MHZ(data),
     185                _H_ACTIVE(data), vbios.timings_common.hsync_start,
     186                vbios.timings_common.hsync_end, vbios.timings_common.hsync_total,
     187                _V_ACTIVE(data), vbios.timings_common.vsync_start,
     188                vbios.timings_common.vsync_end, vbios.timings_common.vsync_total
     189        ));
     190
     191    /* TO-DO: add retrieved info to edid info struct, not fixed mode struct */
     192   
     193    /* struct display_timing is not packed, so we're end setting of every single elm of it */
     194    vbios.shared_info->timing.pixel_clock = _PIXEL_CLOCK(data) / 1000;
     195    vbios.shared_info->timing.h_display = vbios.shared_info->virtual_width = _H_ACTIVE(data);
     196    vbios.shared_info->timing.h_sync_start = vbios.timings_common.hsync_start;
     197    vbios.shared_info->timing.h_sync_end = vbios.timings_common.hsync_end;
     198    vbios.shared_info->timing.h_total = vbios.timings_common.hsync_total;
     199    vbios.shared_info->timing.v_display = vbios.shared_info->virtual_height = _V_ACTIVE(data);
     200    vbios.shared_info->timing.v_sync_start = vbios.timings_common.vsync_start;
     201    vbios.shared_info->timing.v_sync_end = vbios.timings_common.vsync_end;
     202    vbios.shared_info->timing.v_total = vbios.timings_common.vsync_total;
     203
     204    unmap_bios(vbios.area, vbios.memory);
     205    return true;
     206}
     207
     208bool get_lvds_mode_from_bios(display_mode *shared_info)
     209{
     210    struct vbt_header *vbt;
     211    struct bdb_header *bdb;
     212    int vbt_offset, bdb_offset, bdb_block_offset, block_size;
     213    int panel_type = -1;
     214
     215        if (!get_bios())
     216                return false;
     217
     218    vbt_offset = INTEL_BIOS_16(0x1a);
     219    vbt = (struct vbt_header *)(vbios.memory + vbt_offset);
     220    bdb_offset = vbt_offset + vbt->bdb_offset;
     221   
     222    bdb = (struct bdb_header *)(vbios.memory + bdb_offset);
     223    if (memcmp(bdb->signature, "BIOS_DATA_BLOCK ", 16) != 0) {
     224        TRACE(("intel_extreme: bad BDB signature\n"));
     225        return unmap_bios(vbios.area, vbios.memory);
     226    }
     227
     228    TRACE(("intel_extreme: parsing BDB blocks\n"));
     229    for (bdb_block_offset = bdb->header_size; bdb_block_offset < bdb->bdb_size;
     230        bdb_block_offset += block_size) {
     231        int start = bdb_offset + bdb_block_offset;
     232        int id;
     233        struct lvds_bdb1 *lvds1;
     234        struct lvds_bdb2 *lvds2;
     235        struct lvds_bdb2_lfp_info *lvds2_lfp_info;
     236        uint8_t *timing_data;
     237
     238        id = vbios.memory[start];
     239        block_size = INTEL_BIOS_16(start + 1) + 3;
     240        //TRACE(("intel_extreme: found BDB block type %d\n", id));
     241        switch (id) {
     242            case 40:
     243                lvds1 = (struct lvds_bdb1 *)(vbios.memory + start);
     244                panel_type = lvds1->panel_type;
     245            break;
     246            case 41:
     247                if (panel_type == -1)
     248                    break;
     249                lvds2 = (struct lvds_bdb2 *)(vbios.memory + start);
     250                lvds2_lfp_info = (struct lvds_bdb2_lfp_info *)
     251                    (vbios.memory + bdb_offset +
     252                    lvds2->panels[panel_type].lfp_info_offset);
     253                /* found bad one terminator */
     254                if (lvds2_lfp_info->terminator != 0xffff) {
     255                    return unmap_bios(vbios.area, vbios.memory);
     256                }
     257                timing_data = vbios.memory + bdb_offset +
     258                    lvds2->panels[panel_type].lfp_edid_dtd_offset;
     259                TRACE(("intel_extreme: found LFP of size %d x %d "
     260                    "in BIOS VBT tables\n",
     261                    lvds2_lfp_info->x_res, lvds2_lfp_info->y_res));
     262
     263                vbios.timings_common.hsync_start = _H_ACTIVE(timing_data) +
     264                    _H_SYNC_OFF(timing_data);
     265                vbios.timings_common.hsync_end = vbios.timings_common.hsync_start
     266                    + _H_SYNC_WIDTH(timing_data);
     267                vbios.timings_common.hsync_total = _H_ACTIVE(timing_data) +
     268                    _H_BLANK(timing_data);
     269                vbios.timings_common.vsync_start = _V_ACTIVE(timing_data) +
     270                    _V_SYNC_OFF(timing_data);
     271                vbios.timings_common.vsync_end = vbios.timings_common.vsync_start
     272                                        + _V_SYNC_WIDTH(timing_data);
     273                vbios.timings_common.vsync_total = _V_ACTIVE(timing_data) +
     274                                        _V_BLANK(timing_data);
     275
     276                /* Xfree86 compatible modeline */
     277                /*TRACE(("intel_extreme: LFP modeline: x%d Hz,\t%d "
     278                    "%d %d %d %d   %d %d %d %d\n",
     279                    _PIXEL_CLOCK(timing_data) / (
     280                        (_H_ACTIVE(timing_data) + _H_BLANK(timing_data))
     281                          * (_V_ACTIVE(timing_data) + _V_BLANK(timing_data))
     282                        ),
     283                    _PIXEL_CLOCK_MHZ(timing_data),
     284                    _H_ACTIVE(timing_data), vbios.timings_common.hsync_start,
     285                    vbios.timings_common.hsync_end, vbios.timings_common.hsync_total,
     286                    _V_ACTIVE(timing_data), vbios.timings_common.vsync_start,
     287                    vbios.timings_common.vsync_end, vbios.timings_common.vsync_total
     288                ));*/
     289
     290                vbios.shared_info = shared_info;
     291                return feed_shared_info(timing_data);
     292            break;
     293        }
     294    }
     295
     296    unmap_bios(vbios.area, vbios.memory);
     297        return true;
     298}
  • src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp

    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 9c087b7..5adb4b3 100644
    a b intel_extreme_init(intel_info &info)  
    333333    info.shared_info->frame_buffer = 0;
    334334    info.shared_info->dpms_mode = B_DPMS_ON;
    335335
     336    info.shared_info->got_vbt = get_lvds_mode_from_bios(
     337        &info.shared_info->current_mode);
     338    /* at least 855gm can't drive more than one head at time */
     339    if (info.device_type.InFamily(INTEL_TYPE_8xx))
     340        info.shared_info->single_head_locked = 1;
     341
    336342    if (info.device_type.InFamily(INTEL_TYPE_9xx)) {
    337343        info.shared_info->pll_info.reference_frequency = 96000; // 96 kHz
    338344        info.shared_info->pll_info.max_frequency = 400000;