summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_bios.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_bios.c')
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index cf2560708e03..80c5cc5640c1 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1152,6 +1152,13 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
is_hdmi = is_dvi && (child->common.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0;
is_edp = is_dp && (child->common.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR);
+ if (port == PORT_A && is_dvi) {
+ DRM_DEBUG_KMS("VBT claims port A supports DVI%s, ignoring\n",
+ is_hdmi ? "/HDMI" : "");
+ is_dvi = false;
+ is_hdmi = false;
+ }
+
info->supports_dvi = is_dvi;
info->supports_hdmi = is_hdmi;
info->supports_dp = is_dp;
@@ -1212,7 +1219,7 @@ static void parse_ddi_ports(struct drm_i915_private *dev_priv,
{
enum port port;
- if (!HAS_DDI(dev_priv))
+ if (!HAS_DDI(dev_priv) && !IS_CHERRYVIEW(dev_priv))
return;
if (!dev_priv->vbt.child_dev_num)
@@ -1332,6 +1339,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
return;
}
+/* Common defaults which may be overridden by VBT. */
static void
init_vbt_defaults(struct drm_i915_private *dev_priv)
{
@@ -1368,6 +1376,18 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
&dev_priv->vbt.ddi_port_info[port];
info->hdmi_level_shift = HDMI_LEVEL_SHIFT_UNKNOWN;
+ }
+}
+
+/* Defaults to initialize only if there is no VBT. */
+static void
+init_vbt_missing_defaults(struct drm_i915_private *dev_priv)
+{
+ enum port port;
+
+ for (port = PORT_A; port < I915_MAX_PORTS; port++) {
+ struct ddi_vbt_port_info *info =
+ &dev_priv->vbt.ddi_port_info[port];
info->supports_dvi = (port != PORT_A && port != PORT_E);
info->supports_hdmi = info->supports_dvi;
@@ -1450,36 +1470,35 @@ static const struct vbt_header *find_vbt(void __iomem *bios, size_t size)
* intel_bios_init - find VBT and initialize settings from the BIOS
* @dev_priv: i915 device instance
*
- * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers
- * to appropriate values.
- *
- * Returns 0 on success, nonzero on failure.
+ * Parse and initialize settings from the Video BIOS Tables (VBT). If the VBT
+ * was not found in ACPI OpRegion, try to find it in PCI ROM first. Also
+ * initialize some defaults if the VBT is not present at all.
*/
-int
-intel_bios_init(struct drm_i915_private *dev_priv)
+void intel_bios_init(struct drm_i915_private *dev_priv)
{
struct pci_dev *pdev = dev_priv->drm.pdev;
const struct vbt_header *vbt = dev_priv->opregion.vbt;
const struct bdb_header *bdb;
u8 __iomem *bios = NULL;
- if (HAS_PCH_NOP(dev_priv))
- return -ENODEV;
+ if (HAS_PCH_NOP(dev_priv)) {
+ DRM_DEBUG_KMS("Skipping VBT init due to disabled display.\n");
+ return;
+ }
init_vbt_defaults(dev_priv);
+ /* If the OpRegion does not have VBT, look in PCI ROM. */
if (!vbt) {
size_t size;
bios = pci_map_rom(pdev, &size);
if (!bios)
- return -1;
+ goto out;
vbt = find_vbt(bios, size);
- if (!vbt) {
- pci_unmap_rom(pdev, bios);
- return -1;
- }
+ if (!vbt)
+ goto out;
DRM_DEBUG_KMS("Found valid VBT in PCI ROM\n");
}
@@ -1504,10 +1523,14 @@ intel_bios_init(struct drm_i915_private *dev_priv)
parse_mipi_sequence(dev_priv, bdb);
parse_ddi_ports(dev_priv, bdb);
+out:
+ if (!vbt) {
+ DRM_INFO("Failed to find VBIOS tables (VBT)\n");
+ init_vbt_missing_defaults(dev_priv);
+ }
+
if (bios)
pci_unmap_rom(pdev, bios);
-
- return 0;
}
/**