1 /* $NetBSD: intel_vga.c,v 1.4 2021/12/19 11:49:11 riastradh Exp $ */ 2 3 // SPDX-License-Identifier: MIT 4 /* 5 * Copyright 2019 Intel Corporation 6 */ 7 8 #include <sys/cdefs.h> 9 __KERNEL_RCSID(0, "$NetBSD: intel_vga.c,v 1.4 2021/12/19 11:49:11 riastradh Exp $"); 10 11 #include <linux/pci.h> 12 #include <linux/vgaarb.h> 13 14 #include <drm/i915_drm.h> 15 16 #include "i915_drv.h" 17 #include "intel_vga.h" 18 19 static i915_reg_t intel_vga_cntrl_reg(struct drm_i915_private *i915) 20 { 21 if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) 22 return VLV_VGACNTRL; 23 else if (INTEL_GEN(i915) >= 5) 24 return CPU_VGACNTRL; 25 else 26 return VGACNTRL; 27 } 28 29 /* Disable the VGA plane that we never use */ 30 void intel_vga_disable(struct drm_i915_private *dev_priv) 31 { 32 struct pci_dev *pdev = dev_priv->drm.pdev; 33 i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv); 34 u8 sr1; 35 36 #ifdef __NetBSD__ 37 { 38 const bus_addr_t vgabase = 0x3c0; 39 const bus_space_tag_t iot = pdev->pd_pa.pa_iot; 40 bus_space_handle_t ioh; 41 int error; 42 43 error = bus_space_map(iot, vgabase, 0x10, 0, &ioh); 44 if (error) { 45 aprint_error_dev(pdev->pd_dev, 46 "unable to map VGA registers: %d\n", error); 47 } else { 48 BUILD_BUG_ON(!(vgabase <= VGA_SR_INDEX)); 49 BUILD_BUG_ON(!(vgabase <= VGA_SR_DATA)); 50 bus_space_write_1(iot, ioh, VGA_SR_INDEX - vgabase, SR01); 51 sr1 = bus_space_read_1(iot, ioh, VGA_SR_DATA - vgabase); 52 bus_space_write_1(iot, ioh, VGA_SR_DATA - vgabase, 53 (sr1 | __BIT(5))); 54 bus_space_unmap(iot, ioh, 0x10); 55 } 56 } 57 #else 58 /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */ 59 vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); 60 outb(SR01, VGA_SR_INDEX); 61 sr1 = inb(VGA_SR_DATA); 62 outb(sr1 | 1 << 5, VGA_SR_DATA); 63 vga_put(pdev, VGA_RSRC_LEGACY_IO); 64 #endif 65 udelay(300); 66 67 I915_WRITE(vga_reg, VGA_DISP_DISABLE); 68 POSTING_READ(vga_reg); 69 } 70 71 void intel_vga_redisable_power_on(struct drm_i915_private *dev_priv) 72 { 73 i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv); 74 75 if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) { 76 DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); 77 intel_vga_disable(dev_priv); 78 } 79 } 80 81 void intel_vga_redisable(struct drm_i915_private *i915) 82 { 83 intel_wakeref_t wakeref; 84 85 /* 86 * This function can be called both from intel_modeset_setup_hw_state or 87 * at a very early point in our resume sequence, where the power well 88 * structures are not yet restored. Since this function is at a very 89 * paranoid "someone might have enabled VGA while we were not looking" 90 * level, just check if the power well is enabled instead of trying to 91 * follow the "don't touch the power well if we don't need it" policy 92 * the rest of the driver uses. 93 */ 94 wakeref = intel_display_power_get_if_enabled(i915, POWER_DOMAIN_VGA); 95 if (!wakeref) 96 return; 97 98 intel_vga_redisable_power_on(i915); 99 100 intel_display_power_put(i915, POWER_DOMAIN_VGA, wakeref); 101 } 102 103 void intel_vga_reset_io_mem(struct drm_i915_private *i915) 104 { 105 struct pci_dev *pdev = i915->drm.pdev; 106 107 /* 108 * After we re-enable the power well, if we touch VGA register 0x3d5 109 * we'll get unclaimed register interrupts. This stops after we write 110 * anything to the VGA MSR register. The vgacon module uses this 111 * register all the time, so if we unbind our driver and, as a 112 * consequence, bind vgacon, we'll get stuck in an infinite loop at 113 * console_unlock(). So make here we touch the VGA MSR register, making 114 * sure vgacon can keep working normally without triggering interrupts 115 * and error messages. 116 */ 117 #ifdef __NetBSD__ 118 { 119 const bus_addr_t vgabase = 0x3c0; 120 const bus_space_tag_t iot = pdev->pd_pa.pa_iot; 121 bus_space_handle_t ioh; 122 int error; 123 124 error = bus_space_map(iot, vgabase, 0x10, 0, &ioh); 125 if (error) { 126 aprint_error_dev(pdev->pd_dev, 127 "unable to map VGA registers: %d\n", error); 128 } else { 129 BUILD_BUG_ON(!(vgabase <= VGA_MSR_READ)); 130 BUILD_BUG_ON(!(vgabase <= VGA_MSR_WRITE)); 131 bus_space_write_1(iot, ioh, VGA_MSR_WRITE, 132 bus_space_read_1(iot, ioh, VGA_MSR_READ)); 133 bus_space_unmap(iot, ioh, 0x10); 134 } 135 } 136 #else 137 vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); 138 outb(inb(VGA_MSR_READ), VGA_MSR_WRITE); 139 vga_put(pdev, VGA_RSRC_LEGACY_IO); 140 #endif 141 } 142 143 #ifndef __NetBSD__ 144 static int 145 intel_vga_set_state(struct drm_i915_private *i915, bool enable_decode) 146 { 147 unsigned int reg = INTEL_GEN(i915) >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL; 148 u16 gmch_ctrl; 149 150 if (pci_read_config_word(i915->bridge_dev, reg, &gmch_ctrl)) { 151 DRM_ERROR("failed to read control word\n"); 152 return -EIO; 153 } 154 155 if (!!(gmch_ctrl & INTEL_GMCH_VGA_DISABLE) == !enable_decode) 156 return 0; 157 158 if (enable_decode) 159 gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; 160 else 161 gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; 162 163 if (pci_write_config_word(i915->bridge_dev, reg, gmch_ctrl)) { 164 DRM_ERROR("failed to write control word\n"); 165 return -EIO; 166 } 167 168 return 0; 169 } 170 171 static unsigned int 172 intel_vga_set_decode(void *cookie, bool enable_decode) 173 { 174 struct drm_i915_private *i915 = cookie; 175 176 intel_vga_set_state(i915, enable_decode); 177 178 if (enable_decode) 179 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | 180 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 181 else 182 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 183 } 184 #endif /* __NetBSD__ */ 185 186 int intel_vga_register(struct drm_i915_private *i915) 187 { 188 #ifndef __NetBSD__ 189 struct pci_dev *pdev = i915->drm.pdev; 190 int ret; 191 192 /* 193 * If we have > 1 VGA cards, then we need to arbitrate access to the 194 * common VGA resources. 195 * 196 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), 197 * then we do not take part in VGA arbitration and the 198 * vga_client_register() fails with -ENODEV. 199 */ 200 ret = vga_client_register(pdev, i915, NULL, intel_vga_set_decode); 201 if (ret && ret != -ENODEV) 202 return ret; 203 #endif 204 205 return 0; 206 } 207 208 void intel_vga_unregister(struct drm_i915_private *i915) 209 { 210 #ifndef __NetBSD__ 211 struct pci_dev *pdev = i915->drm.pdev; 212 213 vga_client_register(pdev, NULL, NULL, NULL); 214 #endif /* __NetBSD__ */ 215 } 216