staticvoid *find_section(struct bdb_header *bdb, int section_id)
{
u8 *base = (u8 *)bdb; int index = 0;
u16 total, current_size;
u8 current_id;
/* skip to first section */
index += bdb->header_size;
total = bdb->bdb_size;
/* walk the sections looking for section_id */ while (index < total) {
current_id = *(base + index);
index++;
current_size = *((u16 *)(base + index));
index += 2; if (current_id == section_id) return base + index;
index += current_size;
}
p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); if (!p_defs) {
DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n"); return;
} /* judge whether the size of child device meets the requirements. * If the child device size obtained from general definition block * is different with sizeof(struct child_device_config), skip the * parsing of sdvo device info
*/ if (p_defs->child_dev_size != sizeof(*p_child)) { /* different child dev size . Ignore it */
DRM_DEBUG_KMS("different child size is found. Invalid.\n"); return;
} /* get the block size of general definitions */
block_size = get_blocksize(p_defs); /* get the number of child device */
child_device_num = (block_size - sizeof(*p_defs)) / sizeof(*p_child);
count = 0; for (i = 0; i < child_device_num; i++) {
p_child = &(p_defs->devices[i]); if (!p_child->device_type) { /* skip the device block if device type is invalid */ continue;
} if (p_child->target_addr != TARGET_ADDR1 &&
p_child->target_addr != TARGET_ADDR2) { /* * If the target address is neither 0x70 nor 0x72, * it is not a SDVO device. Skip it.
*/ continue;
} if (p_child->dvo_port != DEVICE_PORT_DVOB &&
p_child->dvo_port != DEVICE_PORT_DVOC) { /* skip the incorrect SDVO port */
DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n"); continue;
}
DRM_DEBUG_KMS("the SDVO device with target addr %2x is found on" " %s port\n",
p_child->target_addr,
(p_child->dvo_port == DEVICE_PORT_DVOB) ? "SDVOB" : "SDVOC");
p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]); if (!p_mapping->initialized) {
p_mapping->dvo_port = p_child->dvo_port;
p_mapping->target_addr = p_child->target_addr;
p_mapping->dvo_wiring = p_child->dvo_wiring;
p_mapping->ddc_pin = p_child->ddc_pin;
p_mapping->i2c_pin = p_child->i2c_pin;
p_mapping->initialized = 1;
DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
p_mapping->dvo_port,
p_mapping->target_addr,
p_mapping->dvo_wiring,
p_mapping->ddc_pin,
p_mapping->i2c_pin);
} else {
DRM_DEBUG_KMS("Maybe one SDVO port is shared by " "two SDVO device.\n");
} if (p_child->target2_addr) { /* Maybe this is a SDVO device with multiple inputs */ /* And the mapping info is not added */
DRM_DEBUG_KMS("there exists the target2_addr. Maybe this" " is a SDVO device with multiple inputs.\n");
}
count++;
}
if (!count) { /* No SDVO device info is found */
DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");
} return;
}
p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); if (!p_defs) {
DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); return;
} /* judge whether the size of child device meets the requirements. * If the child device size obtained from general definition block * is different with sizeof(struct child_device_config), skip the * parsing of sdvo device info
*/ if (p_defs->child_dev_size != sizeof(*p_child)) { /* different child dev size . Ignore it */
DRM_DEBUG_KMS("different child size is found. Invalid.\n"); return;
} /* get the block size of general definitions */
block_size = get_blocksize(p_defs); /* get the number of child device */
child_device_num = (block_size - sizeof(*p_defs)) / sizeof(*p_child);
count = 0; /* get the number of child devices that are present */ for (i = 0; i < child_device_num; i++) {
p_child = &(p_defs->devices[i]); if (!p_child->device_type) { /* skip the device block if device type is invalid */ continue;
}
count++;
} if (!count) {
DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); return;
}
dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); if (!dev_priv->child_dev) {
DRM_DEBUG_KMS("No memory space for child devices\n"); return;
}
dev_priv->child_dev_num = count;
count = 0; for (i = 0; i < child_device_num; i++) {
p_child = &(p_defs->devices[i]); if (!p_child->device_type) { /* skip the device block if device type is invalid */ continue;
}
child_dev_ptr = dev_priv->child_dev + count;
count++;
memcpy((void *)child_dev_ptr, (void *)p_child, sizeof(*p_child));
} return;
}
/** * psb_intel_init_bios - initialize VBIOS settings & find VBT * @dev: DRM device * * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers * to appropriate values. * * VBT existence is a sanity check that is relied on by other i830_bios.c code. * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may * feed an updated VBT back through that, compared to what we'll fetch using * this method of groping around in the BIOS data. * * Returns 0 on success, nonzero on failure.
*/ int psb_intel_init_bios(struct drm_device *dev)
{ struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct pci_dev *pdev = to_pci_dev(dev->dev); struct vbt_header *vbt = NULL; struct bdb_header *bdb = NULL;
u8 __iomem *bios = NULL;
size_t size; int i;
dev_priv->panel_type = 0xff;
/* XXX Should this validation be moved to intel_opregion.c? */ if (dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) {
DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n",
vbt->signature);
bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset);
} else
dev_priv->opregion.vbt = NULL;
}
if (bdb == NULL) {
bios = pci_map_rom(pdev, &size); if (!bios) return -1;
/* Scour memory looking for the VBT signature */ for (i = 0; i + 4 < size; i++) { if (!memcmp(bios + i, "$VBT", 4)) {
vbt = (struct vbt_header *)(bios + i); break;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.