root/drivers/gpu/drm/gma500/intel_bios.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_section
  2. parse_edp
  3. get_blocksize
  4. fill_detail_timing_data
  5. parse_backlight_data
  6. parse_lfp_panel_data
  7. parse_sdvo_panel_data
  8. parse_general_features
  9. parse_sdvo_device_mapping
  10. parse_driver_features
  11. parse_device_mapping
  12. psb_intel_init_bios
  13. psb_intel_destroy_bios

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2006 Intel Corporation
   4  *
   5  * Authors:
   6  *    Eric Anholt <eric@anholt.net>
   7  */
   8 #include <drm/drm.h>
   9 #include <drm/drm_dp_helper.h>
  10 
  11 #include "intel_bios.h"
  12 #include "psb_drv.h"
  13 #include "psb_intel_drv.h"
  14 #include "psb_intel_reg.h"
  15 
  16 #define SLAVE_ADDR1     0x70
  17 #define SLAVE_ADDR2     0x72
  18 
  19 static void *find_section(struct bdb_header *bdb, int section_id)
  20 {
  21         u8 *base = (u8 *)bdb;
  22         int index = 0;
  23         u16 total, current_size;
  24         u8 current_id;
  25 
  26         /* skip to first section */
  27         index += bdb->header_size;
  28         total = bdb->bdb_size;
  29 
  30         /* walk the sections looking for section_id */
  31         while (index < total) {
  32                 current_id = *(base + index);
  33                 index++;
  34                 current_size = *((u16 *)(base + index));
  35                 index += 2;
  36                 if (current_id == section_id)
  37                         return base + index;
  38                 index += current_size;
  39         }
  40 
  41         return NULL;
  42 }
  43 
  44 static void
  45 parse_edp(struct drm_psb_private *dev_priv, struct bdb_header *bdb)
  46 {
  47         struct bdb_edp *edp;
  48         struct edp_power_seq *edp_pps;
  49         struct edp_link_params *edp_link_params;
  50         uint8_t panel_type;
  51 
  52         edp = find_section(bdb, BDB_EDP);
  53         
  54         dev_priv->edp.bpp = 18;
  55         if (!edp) {
  56                 if (dev_priv->edp.support) {
  57                         DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported, assume %dbpp panel color depth.\n",
  58                                       dev_priv->edp.bpp);
  59                 }
  60                 return;
  61         }
  62 
  63         panel_type = dev_priv->panel_type;
  64         switch ((edp->color_depth >> (panel_type * 2)) & 3) {
  65         case EDP_18BPP:
  66                 dev_priv->edp.bpp = 18;
  67                 break;
  68         case EDP_24BPP:
  69                 dev_priv->edp.bpp = 24;
  70                 break;
  71         case EDP_30BPP:
  72                 dev_priv->edp.bpp = 30;
  73                 break;
  74         }
  75 
  76         /* Get the eDP sequencing and link info */
  77         edp_pps = &edp->power_seqs[panel_type];
  78         edp_link_params = &edp->link_params[panel_type];
  79 
  80         dev_priv->edp.pps = *edp_pps;
  81 
  82         DRM_DEBUG_KMS("EDP timing in vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
  83                                 dev_priv->edp.pps.t1_t3, dev_priv->edp.pps.t8, 
  84                                 dev_priv->edp.pps.t9, dev_priv->edp.pps.t10,
  85                                 dev_priv->edp.pps.t11_t12);
  86 
  87         dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
  88                 DP_LINK_BW_1_62;
  89         switch (edp_link_params->lanes) {
  90         case 0:
  91                 dev_priv->edp.lanes = 1;
  92                 break;
  93         case 1:
  94                 dev_priv->edp.lanes = 2;
  95                 break;
  96         case 3:
  97         default:
  98                 dev_priv->edp.lanes = 4;
  99                 break;
 100         }
 101         DRM_DEBUG_KMS("VBT reports EDP: Lane_count %d, Lane_rate %d, Bpp %d\n",
 102                         dev_priv->edp.lanes, dev_priv->edp.rate, dev_priv->edp.bpp);
 103 
 104         switch (edp_link_params->preemphasis) {
 105         case 0:
 106                 dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0;
 107                 break;
 108         case 1:
 109                 dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1;
 110                 break;
 111         case 2:
 112                 dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2;
 113                 break;
 114         case 3:
 115                 dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3;
 116                 break;
 117         }
 118         switch (edp_link_params->vswing) {
 119         case 0:
 120                 dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
 121                 break;
 122         case 1:
 123                 dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1;
 124                 break;
 125         case 2:
 126                 dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 127                 break;
 128         case 3:
 129                 dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 130                 break;
 131         }
 132         DRM_DEBUG_KMS("VBT reports EDP: VSwing  %d, Preemph %d\n",
 133                         dev_priv->edp.vswing, dev_priv->edp.preemphasis);
 134 }
 135 
 136 static u16
 137 get_blocksize(void *p)
 138 {
 139         u16 *block_ptr, block_size;
 140 
 141         block_ptr = (u16 *)((char *)p - 2);
 142         block_size = *block_ptr;
 143         return block_size;
 144 }
 145 
 146 static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
 147                         struct lvds_dvo_timing *dvo_timing)
 148 {
 149         panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
 150                 dvo_timing->hactive_lo;
 151         panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
 152                 ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
 153         panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
 154                 dvo_timing->hsync_pulse_width;
 155         panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
 156                 ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
 157 
 158         panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
 159                 dvo_timing->vactive_lo;
 160         panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
 161                 dvo_timing->vsync_off;
 162         panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
 163                 dvo_timing->vsync_pulse_width;
 164         panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
 165                 ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
 166         panel_fixed_mode->clock = dvo_timing->clock * 10;
 167         panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
 168 
 169         if (dvo_timing->hsync_positive)
 170                 panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;
 171         else
 172                 panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;
 173 
 174         if (dvo_timing->vsync_positive)
 175                 panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;
 176         else
 177                 panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;
 178 
 179         /* Some VBTs have bogus h/vtotal values */
 180         if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
 181                 panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
 182         if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
 183                 panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
 184 
 185         drm_mode_set_name(panel_fixed_mode);
 186 }
 187 
 188 static void parse_backlight_data(struct drm_psb_private *dev_priv,
 189                                 struct bdb_header *bdb)
 190 {
 191         struct bdb_lvds_backlight *vbt_lvds_bl = NULL;
 192         struct bdb_lvds_backlight *lvds_bl;
 193         u8 p_type = 0;
 194         void *bl_start = NULL;
 195         struct bdb_lvds_options *lvds_opts
 196                                 = find_section(bdb, BDB_LVDS_OPTIONS);
 197 
 198         dev_priv->lvds_bl = NULL;
 199 
 200         if (lvds_opts)
 201                 p_type = lvds_opts->panel_type;
 202         else
 203                 return;
 204 
 205         bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
 206         vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;
 207 
 208         lvds_bl = kmemdup(vbt_lvds_bl, sizeof(*vbt_lvds_bl), GFP_KERNEL);
 209         if (!lvds_bl) {
 210                 dev_err(dev_priv->dev->dev, "out of memory for backlight data\n");
 211                 return;
 212         }
 213         dev_priv->lvds_bl = lvds_bl;
 214 }
 215 
 216 /* Try to find integrated panel data */
 217 static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
 218                             struct bdb_header *bdb)
 219 {
 220         struct bdb_lvds_options *lvds_options;
 221         struct bdb_lvds_lfp_data *lvds_lfp_data;
 222         struct bdb_lvds_lfp_data_entry *entry;
 223         struct lvds_dvo_timing *dvo_timing;
 224         struct drm_display_mode *panel_fixed_mode;
 225 
 226         /* Defaults if we can't find VBT info */
 227         dev_priv->lvds_dither = 0;
 228         dev_priv->lvds_vbt = 0;
 229 
 230         lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
 231         if (!lvds_options)
 232                 return;
 233 
 234         dev_priv->lvds_dither = lvds_options->pixel_dither;
 235         dev_priv->panel_type = lvds_options->panel_type;
 236 
 237         if (lvds_options->panel_type == 0xff)
 238                 return;
 239 
 240         lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
 241         if (!lvds_lfp_data)
 242                 return;
 243 
 244 
 245         entry = &lvds_lfp_data->data[lvds_options->panel_type];
 246         dvo_timing = &entry->dvo_timing;
 247 
 248         panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode),
 249                                       GFP_KERNEL);
 250         if (panel_fixed_mode == NULL) {
 251                 dev_err(dev_priv->dev->dev, "out of memory for fixed panel mode\n");
 252                 return;
 253         }
 254 
 255         dev_priv->lvds_vbt = 1;
 256         fill_detail_timing_data(panel_fixed_mode, dvo_timing);
 257 
 258         if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {
 259                 dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
 260                 drm_mode_debug_printmodeline(panel_fixed_mode);
 261         } else {
 262                 dev_dbg(dev_priv->dev->dev, "ignoring invalid LVDS VBT\n");
 263                 dev_priv->lvds_vbt = 0;
 264                 kfree(panel_fixed_mode);
 265         }
 266         return;
 267 }
 268 
 269 /* Try to find sdvo panel data */
 270 static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv,
 271                       struct bdb_header *bdb)
 272 {
 273         struct bdb_sdvo_lvds_options *sdvo_lvds_options;
 274         struct lvds_dvo_timing *dvo_timing;
 275         struct drm_display_mode *panel_fixed_mode;
 276 
 277         dev_priv->sdvo_lvds_vbt_mode = NULL;
 278 
 279         sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
 280         if (!sdvo_lvds_options)
 281                 return;
 282 
 283         dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
 284         if (!dvo_timing)
 285                 return;
 286 
 287         panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
 288 
 289         if (!panel_fixed_mode)
 290                 return;
 291 
 292         fill_detail_timing_data(panel_fixed_mode,
 293                         dvo_timing + sdvo_lvds_options->panel_type);
 294 
 295         dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
 296 
 297         return;
 298 }
 299 
 300 static void parse_general_features(struct drm_psb_private *dev_priv,
 301                        struct bdb_header *bdb)
 302 {
 303         struct bdb_general_features *general;
 304 
 305         /* Set sensible defaults in case we can't find the general block */
 306         dev_priv->int_tv_support = 1;
 307         dev_priv->int_crt_support = 1;
 308 
 309         general = find_section(bdb, BDB_GENERAL_FEATURES);
 310         if (general) {
 311                 dev_priv->int_tv_support = general->int_tv_support;
 312                 dev_priv->int_crt_support = general->int_crt_support;
 313                 dev_priv->lvds_use_ssc = general->enable_ssc;
 314 
 315                 if (dev_priv->lvds_use_ssc) {
 316                         dev_priv->lvds_ssc_freq
 317                                 = general->ssc_freq ? 100 : 96;
 318                 }
 319         }
 320 }
 321 
 322 static void
 323 parse_sdvo_device_mapping(struct drm_psb_private *dev_priv,
 324                           struct bdb_header *bdb)
 325 {
 326         struct sdvo_device_mapping *p_mapping;
 327         struct bdb_general_definitions *p_defs;
 328         struct child_device_config *p_child;
 329         int i, child_device_num, count;
 330         u16     block_size;
 331 
 332         p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
 333         if (!p_defs) {
 334                 DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");
 335                 return;
 336         }
 337         /* judge whether the size of child device meets the requirements.
 338          * If the child device size obtained from general definition block
 339          * is different with sizeof(struct child_device_config), skip the
 340          * parsing of sdvo device info
 341          */
 342         if (p_defs->child_dev_size != sizeof(*p_child)) {
 343                 /* different child dev size . Ignore it */
 344                 DRM_DEBUG_KMS("different child size is found. Invalid.\n");
 345                 return;
 346         }
 347         /* get the block size of general definitions */
 348         block_size = get_blocksize(p_defs);
 349         /* get the number of child device */
 350         child_device_num = (block_size - sizeof(*p_defs)) /
 351                                 sizeof(*p_child);
 352         count = 0;
 353         for (i = 0; i < child_device_num; i++) {
 354                 p_child = &(p_defs->devices[i]);
 355                 if (!p_child->device_type) {
 356                         /* skip the device block if device type is invalid */
 357                         continue;
 358                 }
 359                 if (p_child->slave_addr != SLAVE_ADDR1 &&
 360                         p_child->slave_addr != SLAVE_ADDR2) {
 361                         /*
 362                          * If the slave address is neither 0x70 nor 0x72,
 363                          * it is not a SDVO device. Skip it.
 364                          */
 365                         continue;
 366                 }
 367                 if (p_child->dvo_port != DEVICE_PORT_DVOB &&
 368                         p_child->dvo_port != DEVICE_PORT_DVOC) {
 369                         /* skip the incorrect SDVO port */
 370                         DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
 371                         continue;
 372                 }
 373                 DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
 374                                 " %s port\n",
 375                                 p_child->slave_addr,
 376                                 (p_child->dvo_port == DEVICE_PORT_DVOB) ?
 377                                         "SDVOB" : "SDVOC");
 378                 p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);
 379                 if (!p_mapping->initialized) {
 380                         p_mapping->dvo_port = p_child->dvo_port;
 381                         p_mapping->slave_addr = p_child->slave_addr;
 382                         p_mapping->dvo_wiring = p_child->dvo_wiring;
 383                         p_mapping->ddc_pin = p_child->ddc_pin;
 384                         p_mapping->i2c_pin = p_child->i2c_pin;
 385                         p_mapping->initialized = 1;
 386                         DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
 387                                       p_mapping->dvo_port,
 388                                       p_mapping->slave_addr,
 389                                       p_mapping->dvo_wiring,
 390                                       p_mapping->ddc_pin,
 391                                       p_mapping->i2c_pin);
 392                 } else {
 393                         DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
 394                                          "two SDVO device.\n");
 395                 }
 396                 if (p_child->slave2_addr) {
 397                         /* Maybe this is a SDVO device with multiple inputs */
 398                         /* And the mapping info is not added */
 399                         DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this"
 400                                 " is a SDVO device with multiple inputs.\n");
 401                 }
 402                 count++;
 403         }
 404 
 405         if (!count) {
 406                 /* No SDVO device info is found */
 407                 DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
 408         }
 409         return;
 410 }
 411 
 412 
 413 static void
 414 parse_driver_features(struct drm_psb_private *dev_priv,
 415                       struct bdb_header *bdb)
 416 {
 417         struct bdb_driver_features *driver;
 418 
 419         driver = find_section(bdb, BDB_DRIVER_FEATURES);
 420         if (!driver)
 421                 return;
 422 
 423         if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
 424                 dev_priv->edp.support = 1;
 425 
 426         dev_priv->lvds_enabled_in_vbt = driver->lvds_config != 0;
 427         DRM_DEBUG_KMS("LVDS VBT config bits: 0x%x\n", driver->lvds_config);
 428 
 429         /* This bit means to use 96Mhz for DPLL_A or not */
 430         if (driver->primary_lfp_id)
 431                 dev_priv->dplla_96mhz = true;
 432         else
 433                 dev_priv->dplla_96mhz = false;
 434 }
 435 
 436 static void
 437 parse_device_mapping(struct drm_psb_private *dev_priv,
 438                        struct bdb_header *bdb)
 439 {
 440         struct bdb_general_definitions *p_defs;
 441         struct child_device_config *p_child, *child_dev_ptr;
 442         int i, child_device_num, count;
 443         u16     block_size;
 444 
 445         p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
 446         if (!p_defs) {
 447                 DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");
 448                 return;
 449         }
 450         /* judge whether the size of child device meets the requirements.
 451          * If the child device size obtained from general definition block
 452          * is different with sizeof(struct child_device_config), skip the
 453          * parsing of sdvo device info
 454          */
 455         if (p_defs->child_dev_size != sizeof(*p_child)) {
 456                 /* different child dev size . Ignore it */
 457                 DRM_DEBUG_KMS("different child size is found. Invalid.\n");
 458                 return;
 459         }
 460         /* get the block size of general definitions */
 461         block_size = get_blocksize(p_defs);
 462         /* get the number of child device */
 463         child_device_num = (block_size - sizeof(*p_defs)) /
 464                                 sizeof(*p_child);
 465         count = 0;
 466         /* get the number of child devices that are present */
 467         for (i = 0; i < child_device_num; i++) {
 468                 p_child = &(p_defs->devices[i]);
 469                 if (!p_child->device_type) {
 470                         /* skip the device block if device type is invalid */
 471                         continue;
 472                 }
 473                 count++;
 474         }
 475         if (!count) {
 476                 DRM_DEBUG_KMS("no child dev is parsed from VBT\n");
 477                 return;
 478         }
 479         dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL);
 480         if (!dev_priv->child_dev) {
 481                 DRM_DEBUG_KMS("No memory space for child devices\n");
 482                 return;
 483         }
 484 
 485         dev_priv->child_dev_num = count;
 486         count = 0;
 487         for (i = 0; i < child_device_num; i++) {
 488                 p_child = &(p_defs->devices[i]);
 489                 if (!p_child->device_type) {
 490                         /* skip the device block if device type is invalid */
 491                         continue;
 492                 }
 493                 child_dev_ptr = dev_priv->child_dev + count;
 494                 count++;
 495                 memcpy((void *)child_dev_ptr, (void *)p_child,
 496                                         sizeof(*p_child));
 497         }
 498         return;
 499 }
 500 
 501 
 502 /**
 503  * psb_intel_init_bios - initialize VBIOS settings & find VBT
 504  * @dev: DRM device
 505  *
 506  * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers
 507  * to appropriate values.
 508  *
 509  * VBT existence is a sanity check that is relied on by other i830_bios.c code.
 510  * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
 511  * feed an updated VBT back through that, compared to what we'll fetch using
 512  * this method of groping around in the BIOS data.
 513  *
 514  * Returns 0 on success, nonzero on failure.
 515  */
 516 int psb_intel_init_bios(struct drm_device *dev)
 517 {
 518         struct drm_psb_private *dev_priv = dev->dev_private;
 519         struct pci_dev *pdev = dev->pdev;
 520         struct vbt_header *vbt = NULL;
 521         struct bdb_header *bdb = NULL;
 522         u8 __iomem *bios = NULL;
 523         size_t size;
 524         int i;
 525 
 526 
 527         dev_priv->panel_type = 0xff;
 528 
 529         /* XXX Should this validation be moved to intel_opregion.c? */
 530         if (dev_priv->opregion.vbt) {
 531                 struct vbt_header *vbt = dev_priv->opregion.vbt;
 532                 if (memcmp(vbt->signature, "$VBT", 4) == 0) {
 533                         DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n",
 534                                          vbt->signature);
 535                         bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset);
 536                 } else
 537                         dev_priv->opregion.vbt = NULL;
 538         }
 539 
 540         if (bdb == NULL) {
 541                 bios = pci_map_rom(pdev, &size);
 542                 if (!bios)
 543                         return -1;
 544 
 545                 /* Scour memory looking for the VBT signature */
 546                 for (i = 0; i + 4 < size; i++) {
 547                         if (!memcmp(bios + i, "$VBT", 4)) {
 548                                 vbt = (struct vbt_header *)(bios + i);
 549                                 break;
 550                         }
 551                 }
 552 
 553                 if (!vbt) {
 554                         dev_err(dev->dev, "VBT signature missing\n");
 555                         pci_unmap_rom(pdev, bios);
 556                         return -1;
 557                 }
 558                 bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
 559         }
 560 
 561         /* Grab useful general dxefinitions */
 562         parse_general_features(dev_priv, bdb);
 563         parse_driver_features(dev_priv, bdb);
 564         parse_lfp_panel_data(dev_priv, bdb);
 565         parse_sdvo_panel_data(dev_priv, bdb);
 566         parse_sdvo_device_mapping(dev_priv, bdb);
 567         parse_device_mapping(dev_priv, bdb);
 568         parse_backlight_data(dev_priv, bdb);
 569         parse_edp(dev_priv, bdb);
 570 
 571         if (bios)
 572                 pci_unmap_rom(pdev, bios);
 573 
 574         return 0;
 575 }
 576 
 577 /**
 578  * Destroy and free VBT data
 579  */
 580 void psb_intel_destroy_bios(struct drm_device *dev)
 581 {
 582         struct drm_psb_private *dev_priv = dev->dev_private;
 583 
 584         kfree(dev_priv->sdvo_lvds_vbt_mode);
 585         kfree(dev_priv->lfp_lvds_vbt_mode);
 586         kfree(dev_priv->lvds_bl);
 587 }

/* [<][>][^][v][top][bottom][index][help] */