diff options
Diffstat (limited to 'sys/dev/drm2/i915/intel_bios.c')
-rw-r--r-- | sys/dev/drm2/i915/intel_bios.c | 94 |
1 files changed, 53 insertions, 41 deletions
diff --git a/sys/dev/drm2/i915/intel_bios.c b/sys/dev/drm2/i915/intel_bios.c index 0499794..f528766 100644 --- a/sys/dev/drm2/i915/intel_bios.c +++ b/sys/dev/drm2/i915/intel_bios.c @@ -23,10 +23,12 @@ * Authors: * Eric Anholt <eric@anholt.net> * - * $FreeBSD$ */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <dev/drm2/drmP.h> -#include <dev/drm2/drm.h> #include <dev/drm2/drm_dp_helper.h> #include <dev/drm2/i915/i915_drm.h> #include <dev/drm2/i915/i915_drv.h> @@ -169,8 +171,7 @@ get_lvds_dvo_timing(const struct bdb_lvds_lfp_data *lvds_lfp_data, int dvo_timing_offset = lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset - lvds_lfp_data_ptrs->ptr[0].fp_timing_offset; - const char *entry = (const char *)lvds_lfp_data->data + - lfp_data_size * index; + const char *entry = (const char *)lvds_lfp_data->data + lfp_data_size * index; return (const struct lvds_dvo_timing *)(entry + dvo_timing_offset); } @@ -188,7 +189,7 @@ get_lvds_fp_timing(const struct bdb_header *bdb, u16 data_size = ((const u16 *)data)[-1]; /* stored in header */ size_t ofs; - if (index >= DRM_ARRAY_SIZE(ptrs->ptr)) + if (index >= ARRAY_SIZE(ptrs->ptr)) return NULL; ofs = ptrs->ptr[index].fp_timing_offset; if (ofs < data_ofs || @@ -234,8 +235,9 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, lvds_lfp_data_ptrs, lvds_options->panel_type); - panel_fixed_mode = malloc(sizeof(*panel_fixed_mode), DRM_MEM_KMS, - M_WAITOK | M_ZERO); + panel_fixed_mode = malloc(sizeof(*panel_fixed_mode), DRM_MEM_KMS, M_WAITOK | M_ZERO); + if (!panel_fixed_mode) + return; fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing); @@ -263,9 +265,9 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, if (downclock < panel_dvo_timing->clock && i915_lvds_downclock) { dev_priv->lvds_downclock_avail = 1; dev_priv->lvds_downclock = downclock * 10; - DRM_DEBUG("LVDS downclock is found in VBT. " + DRM_DEBUG_KMS("LVDS downclock is found in VBT. " "Normal Clock %dKHz, downclock %dKHz\n", - panel_fixed_mode->clock, 10 * downclock); + panel_fixed_mode->clock, 10*downclock); } fp_timing = get_lvds_fp_timing(bdb, lvds_lfp_data, @@ -311,8 +313,9 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv, if (!dvo_timing) return; - panel_fixed_mode = malloc(sizeof(*panel_fixed_mode), DRM_MEM_KMS, - M_WAITOK | M_ZERO); + panel_fixed_mode = malloc(sizeof(*panel_fixed_mode), DRM_MEM_KMS, M_WAITOK | M_ZERO); + if (!panel_fixed_mode) + return; fill_detail_timing_data(panel_fixed_mode, dvo_timing + index); @@ -351,12 +354,14 @@ parse_general_features(struct drm_i915_private *dev_priv, dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, general->ssc_freq); dev_priv->display_clock_mode = general->display_clock_mode; - 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\n", + dev_priv->fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted; + 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", dev_priv->int_tv_support, dev_priv->int_crt_support, dev_priv->lvds_use_ssc, dev_priv->lvds_ssc_freq, - dev_priv->display_clock_mode); + dev_priv->display_clock_mode, + dev_priv->fdi_rx_polarity_inverted); } } @@ -499,12 +504,8 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) edp = find_section(bdb, BDB_EDP); if (!edp) { - if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) { - DRM_DEBUG_KMS("No eDP BDB found but eDP panel " - "supported, assume %dbpp panel color " - "depth.\n", - dev_priv->edp.bpp); - } + if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) + DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n"); return; } @@ -613,8 +614,11 @@ parse_device_mapping(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); return; } - dev_priv->child_dev = malloc(sizeof(*p_child) * count, DRM_MEM_KMS, - M_WAITOK | M_ZERO); + dev_priv->child_dev = malloc(count * sizeof(*p_child), DRM_MEM_KMS, M_WAITOK | M_ZERO); + if (!dev_priv->child_dev) { + DRM_DEBUG_KMS("No memory space for child device\n"); + return; + } dev_priv->child_dev_num = count; count = 0; @@ -654,12 +658,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) dev_priv->lvds_use_ssc = 1; dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); - - /* eDP data */ - dev_priv->edp.bpp = 18; } -static int intel_no_opregion_vbt_callback(const struct dmi_system_id *id) +static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) { DRM_DEBUG_KMS("Falling back to manually reading VBT from " "VBIOS ROM for %s\n", @@ -688,12 +689,13 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = { * * Returns 0 on success, nonzero on failure. */ -bool +int intel_parse_bios(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + device_t vga_dev = device_get_parent(dev->dev);; struct bdb_header *bdb = NULL; - u8 *bios; + u8 __iomem *bios = NULL; init_vbt_defaults(dev_priv); @@ -707,20 +709,13 @@ intel_parse_bios(struct drm_device *dev) } else dev_priv->opregion.vbt = NULL; } - bios = NULL; -#if 1 - if (bdb == NULL) { - KIB_NOTYET(); - return (-1); - } -#else if (bdb == NULL) { struct vbt_header *vbt = NULL; size_t size; int i; - bios = pci_map_rom(pdev, &size); + bios = vga_pci_map_bios(vga_dev, &size); if (!bios) return -1; @@ -734,13 +729,12 @@ intel_parse_bios(struct drm_device *dev) if (!vbt) { DRM_DEBUG_DRIVER("VBT signature missing\n"); - pci_unmap_rom(pdev, bios); + vga_pci_unmap_bios(vga_dev, bios); return -1; } bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); } -#endif /* Grab useful general definitions */ parse_general_features(dev_priv, bdb); @@ -752,14 +746,31 @@ intel_parse_bios(struct drm_device *dev) parse_driver_features(dev_priv, bdb); parse_edp(dev_priv, bdb); -#if 0 if (bios) - pci_unmap_rom(pdev, bios); -#endif + vga_pci_unmap_bios(vga_dev, bios); return 0; } +/* + * NOTE Linux<->FreeBSD: + * Apparently, Linux doesn't free those pointers. + * TODO: Report that upstream. + */ +void +intel_free_parsed_bios_data(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + free(dev_priv->lfp_lvds_vbt_mode, DRM_MEM_KMS); + free(dev_priv->sdvo_lvds_vbt_mode, DRM_MEM_KMS); + free(dev_priv->child_dev, DRM_MEM_KMS); + + dev_priv->lfp_lvds_vbt_mode = NULL; + dev_priv->sdvo_lvds_vbt_mode = NULL; + dev_priv->child_dev = NULL; +} + /* Ensure that vital registers have been initialised, even if the BIOS * is absent or just failing to do its job. */ @@ -768,7 +779,8 @@ void intel_setup_bios(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; /* Set the Panel Power On/Off timings if uninitialized. */ - if ((I915_READ(PP_ON_DELAYS) == 0) && (I915_READ(PP_OFF_DELAYS) == 0)) { + if (!HAS_PCH_SPLIT(dev) && + I915_READ(PP_ON_DELAYS) == 0 && I915_READ(PP_OFF_DELAYS) == 0) { /* Set T2 to 40ms and T5 to 200ms */ I915_WRITE(PP_ON_DELAYS, 0x019007d0); |