/*
*/
/*
* Copyright (c) 2006, 2013, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*
*/
#include "drmP.h"
#include "drm.h"
#include "drm_dp_helper.h"
#include "i915_drm.h"
#include "i915_drv.h"
#include "intel_bios.h"
static int panel_type;
static void *
{
int index = 0;
/* skip to first section */
/* walk the sections looking for section_id */
index++;
index += 2;
if (current_id == section_id)
index += current_size;
}
return NULL;
}
static u16
get_blocksize(void *p)
{
block_size = *block_ptr;
return block_size;
}
static void
const struct lvds_dvo_timing *dvo_timing)
{
if (dvo_timing->hsync_positive)
else
if (dvo_timing->vsync_positive)
else
}
static bool
const struct lvds_dvo_timing *b)
{
if (a->hactive_hi != b->hactive_hi ||
a->hactive_lo != b->hactive_lo)
return false;
if (a->hsync_off_hi != b->hsync_off_hi ||
a->hsync_off_lo != b->hsync_off_lo)
return false;
if (a->hsync_pulse_width != b->hsync_pulse_width)
return false;
return false;
if (a->vactive_hi != b->vactive_hi ||
a->vactive_lo != b->vactive_lo)
return false;
return false;
if (a->vsync_pulse_width != b->vsync_pulse_width)
return false;
return false;
return true;
}
static const struct lvds_dvo_timing *
const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs,
int index)
{
/*
* the size of fp_timing varies on the different platform.
* So calculate the DVO timing relative offset in LVDS data
* entry to get the DVO timing entry
*/
int lfp_data_size =
int dvo_timing_offset =
}
/* get lvds_fp_timing entry
* this function may return NULL if the corresponding entry is invalid
*/
static const struct lvds_fp_timing *
const struct bdb_lvds_lfp_data *data,
const struct bdb_lvds_lfp_data_ptrs *ptrs,
int index)
{
/* LINTED */
/* LINTED */
return NULL;
return NULL;
}
/* Try to find integrated panel data */
static void
struct bdb_header *bdb)
{
int i, downclock;
if (!lvds_options)
return;
return;
if (!lvds_lfp_data)
return;
if (!lvds_lfp_data_ptrs)
return;
if (!panel_fixed_mode)
return;
DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
/*
* enumerate the LVDS panel timing info entry in VBT to check whether
* the LVDS downclock is found.
*/
for (i = 0; i < 16; i++) {
i);
}
DRM_DEBUG_KMS("LVDS downclock is found in VBT. "
"Normal Clock %dKHz, downclock %dKHz\n",
}
if (fp_timing) {
/* check the resolution, just to be sure */
DRM_DEBUG_KMS("VBT initial LVDS value %x\n",
}
}
}
/* Try to find sdvo panel data */
static void
struct bdb_header *bdb)
{
int index;
if (index == -2) {
DRM_DEBUG_KMS("Ignore SDVO panel mode from BIOS VBT tables.\n");
return;
}
if (index == -1) {
if (!sdvo_lvds_options)
return;
}
if (!dvo_timing)
return;
if (!panel_fixed_mode)
return;
DRM_DEBUG_KMS("Found SDVO panel mode in BIOS VBT tables:\n");
}
bool alternate)
{
case 2:
case 3:
case 4:
default:
}
}
static void
struct bdb_header *bdb)
{
if (general) {
DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support"
" %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode"
" %d fdi_rx_polarity_inverted %d\n",
}
}
static void
struct bdb_header *bdb)
{
if (general) {
if (block_size >= sizeof(*general)) {
} else {
DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
}
}
}
static void
struct bdb_header *bdb)
{
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
*/
/* different child dev size . Ignore it */
DRM_DEBUG_KMS("different child size is found. Invalid.\n");
return;
}
/* get the block size of general definitions */
/* get the number of child device */
sizeof(*p_child);
count = 0;
for (i = 0; i < child_device_num; i++) {
if (!p_child->device_type) {
/* skip the device block if device type is invalid */
continue;
}
/*
* If the slave address is neither 0x70 nor 0x72,
* it is not a SDVO device. Skip it.
*/
continue;
}
/* skip the incorrect SDVO port */
DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
continue;
}
DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
" %s port\n",
"SDVOB" : "SDVOC");
if (!p_mapping->initialized) {
DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",
} else {
DRM_DEBUG_KMS("Maybe one SDVO port is shared by "
"two SDVO device.\n");
}
if (p_child->slave2_addr) {
/* Maybe this is a SDVO device with multiple inputs */
/* And the mapping info is not added */
DRM_DEBUG_KMS("there exists the slave2_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;
}
static void
struct bdb_header *bdb)
{
if (!driver)
return;
if (SUPPORTS_EDP(dev) &&
if (driver->dual_frequency)
dev_priv->render_reclock_avail = true;
}
static void
{
if (!edp) {
DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
return;
}
case EDP_18BPP:
break;
case EDP_24BPP:
break;
case EDP_30BPP:
break;
}
/* Get the eDP sequencing and link info */
switch (edp_link_params->lanes) {
case 0:
break;
case 1:
break;
case 3:
default:
break;
}
switch (edp_link_params->preemphasis) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
}
switch (edp_link_params->vswing) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
}
}
static void
struct bdb_header *bdb)
{
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
*/
/* different child dev size . Ignore it */
DRM_DEBUG_KMS("different child size is found. Invalid.\n");
return;
}
/* get the block size of general definitions */
/* get the number of child device */
sizeof(*p_child);
count = 0;
/* get the number of child device that is present */
for (i = 0; i < child_device_num; 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;
}
DRM_DEBUG_KMS("No memory space for child device\n");
return;
}
count = 0;
for (i = 0; i < child_device_num; i++) {
if (!p_child->device_type) {
/* skip the device block if device type is invalid */
continue;
}
count++;
sizeof(*p_child));
}
return;
}
static void
{
/* LFP panel data */
/* SDVO panel data */
/* general features */
/* Default to using SSC */
}
/**
* 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.
*
* Returns 0 on success, nonzero on failure.
*/
int
{
if (HAS_PCH_NOP(dev))
return -ENODEV;
/* XXX Should this validation be moved to intel_opregion.c? */
DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n",
} else
}
int i;
if (!bios)
return -1;
/* Scour memory looking for the VBT signature */
for (i = 0; i + 4 < size; i++) {
break;
}
}
if (!vbt) {
DRM_ERROR("VBT signature missing\n");
return -1;
}
}
/* Grab useful general definitions */
if (bios)
return 0;
}
/* Ensure that vital registers have been initialised, even if the BIOS
* is absent or just failing to do its job.
*/
{
if (!HAS_PCH_SPLIT(dev) &&
/* Set T2 to 40ms and T5 to 200ms */
/* Set T3 to 35ms and Tx to 200ms */
}
}