linux/drivers/gpu/drm/i915/display/intel_vga.c
<<
>>
Prefs
   1// SPDX-License-Identifier: MIT
   2/*
   3 * Copyright © 2019 Intel Corporation
   4 */
   5
   6#include <linux/pci.h>
   7#include <linux/vgaarb.h>
   8
   9#include <drm/i915_drm.h>
  10
  11#include "i915_drv.h"
  12#include "intel_de.h"
  13#include "intel_vga.h"
  14
  15static i915_reg_t intel_vga_cntrl_reg(struct drm_i915_private *i915)
  16{
  17        if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
  18                return VLV_VGACNTRL;
  19        else if (INTEL_GEN(i915) >= 5)
  20                return CPU_VGACNTRL;
  21        else
  22                return VGACNTRL;
  23}
  24
  25/* Disable the VGA plane that we never use */
  26void intel_vga_disable(struct drm_i915_private *dev_priv)
  27{
  28        struct pci_dev *pdev = dev_priv->drm.pdev;
  29        i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv);
  30        u8 sr1;
  31
  32        /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
  33        vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
  34        outb(SR01, VGA_SR_INDEX);
  35        sr1 = inb(VGA_SR_DATA);
  36        outb(sr1 | 1 << 5, VGA_SR_DATA);
  37        vga_put(pdev, VGA_RSRC_LEGACY_IO);
  38        udelay(300);
  39
  40        intel_de_write(dev_priv, vga_reg, VGA_DISP_DISABLE);
  41        intel_de_posting_read(dev_priv, vga_reg);
  42}
  43
  44void intel_vga_redisable_power_on(struct drm_i915_private *dev_priv)
  45{
  46        i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv);
  47
  48        if (!(intel_de_read(dev_priv, vga_reg) & VGA_DISP_DISABLE)) {
  49                drm_dbg_kms(&dev_priv->drm,
  50                            "Something enabled VGA plane, disabling it\n");
  51                intel_vga_disable(dev_priv);
  52        }
  53}
  54
  55void intel_vga_redisable(struct drm_i915_private *i915)
  56{
  57        intel_wakeref_t wakeref;
  58
  59        /*
  60         * This function can be called both from intel_modeset_setup_hw_state or
  61         * at a very early point in our resume sequence, where the power well
  62         * structures are not yet restored. Since this function is at a very
  63         * paranoid "someone might have enabled VGA while we were not looking"
  64         * level, just check if the power well is enabled instead of trying to
  65         * follow the "don't touch the power well if we don't need it" policy
  66         * the rest of the driver uses.
  67         */
  68        wakeref = intel_display_power_get_if_enabled(i915, POWER_DOMAIN_VGA);
  69        if (!wakeref)
  70                return;
  71
  72        intel_vga_redisable_power_on(i915);
  73
  74        intel_display_power_put(i915, POWER_DOMAIN_VGA, wakeref);
  75}
  76
  77void intel_vga_reset_io_mem(struct drm_i915_private *i915)
  78{
  79        struct pci_dev *pdev = i915->drm.pdev;
  80
  81        /*
  82         * After we re-enable the power well, if we touch VGA register 0x3d5
  83         * we'll get unclaimed register interrupts. This stops after we write
  84         * anything to the VGA MSR register. The vgacon module uses this
  85         * register all the time, so if we unbind our driver and, as a
  86         * consequence, bind vgacon, we'll get stuck in an infinite loop at
  87         * console_unlock(). So make here we touch the VGA MSR register, making
  88         * sure vgacon can keep working normally without triggering interrupts
  89         * and error messages.
  90         */
  91        vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
  92        outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
  93        vga_put(pdev, VGA_RSRC_LEGACY_IO);
  94}
  95
  96static int
  97intel_vga_set_state(struct drm_i915_private *i915, bool enable_decode)
  98{
  99        unsigned int reg = INTEL_GEN(i915) >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL;
 100        u16 gmch_ctrl;
 101
 102        if (pci_read_config_word(i915->bridge_dev, reg, &gmch_ctrl)) {
 103                drm_err(&i915->drm, "failed to read control word\n");
 104                return -EIO;
 105        }
 106
 107        if (!!(gmch_ctrl & INTEL_GMCH_VGA_DISABLE) == !enable_decode)
 108                return 0;
 109
 110        if (enable_decode)
 111                gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
 112        else
 113                gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
 114
 115        if (pci_write_config_word(i915->bridge_dev, reg, gmch_ctrl)) {
 116                drm_err(&i915->drm, "failed to write control word\n");
 117                return -EIO;
 118        }
 119
 120        return 0;
 121}
 122
 123static unsigned int
 124intel_vga_set_decode(void *cookie, bool enable_decode)
 125{
 126        struct drm_i915_private *i915 = cookie;
 127
 128        intel_vga_set_state(i915, enable_decode);
 129
 130        if (enable_decode)
 131                return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
 132                       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 133        else
 134                return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 135}
 136
 137int intel_vga_register(struct drm_i915_private *i915)
 138{
 139        struct pci_dev *pdev = i915->drm.pdev;
 140        int ret;
 141
 142        /*
 143         * If we have > 1 VGA cards, then we need to arbitrate access to the
 144         * common VGA resources.
 145         *
 146         * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
 147         * then we do not take part in VGA arbitration and the
 148         * vga_client_register() fails with -ENODEV.
 149         */
 150        ret = vga_client_register(pdev, i915, NULL, intel_vga_set_decode);
 151        if (ret && ret != -ENODEV)
 152                return ret;
 153
 154        return 0;
 155}
 156
 157void intel_vga_unregister(struct drm_i915_private *i915)
 158{
 159        struct pci_dev *pdev = i915->drm.pdev;
 160
 161        vga_client_register(pdev, NULL, NULL, NULL);
 162}
 163