1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2019 Intel Corporation 4 */ 5 6 #include <linux/delay.h> 7 #include <linux/pci.h> 8 #include <linux/vgaarb.h> 9 10 #include <drm/drm_device.h> 11 #include <drm/drm_print.h> 12 #include <drm/intel/i915_drm.h> 13 #include <video/vga.h> 14 15 #include "intel_de.h" 16 #include "intel_display.h" 17 #include "intel_display_types.h" 18 #include "intel_vga.h" 19 #include "intel_vga_regs.h" 20 21 static i915_reg_t intel_vga_cntrl_reg(struct intel_display *display) 22 { 23 if (display->platform.valleyview || display->platform.cherryview) 24 return VLV_VGACNTRL; 25 else if (DISPLAY_VER(display) >= 5) 26 return CPU_VGACNTRL; 27 else 28 return VGACNTRL; 29 } 30 31 static bool has_vga_pipe_sel(struct intel_display *display) 32 { 33 if (display->platform.i845g || 34 display->platform.i865g) 35 return false; 36 37 if (display->platform.valleyview || 38 display->platform.cherryview) 39 return true; 40 41 return DISPLAY_VER(display) < 7; 42 } 43 44 /* Disable the VGA plane that we never use */ 45 void intel_vga_disable(struct intel_display *display) 46 { 47 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 48 i915_reg_t vga_reg = intel_vga_cntrl_reg(display); 49 enum pipe pipe; 50 u32 tmp; 51 u8 sr1; 52 53 tmp = intel_de_read(display, vga_reg); 54 if (tmp & VGA_DISP_DISABLE) 55 return; 56 57 if (display->platform.cherryview) 58 pipe = REG_FIELD_GET(VGA_PIPE_SEL_MASK_CHV, tmp); 59 else if (has_vga_pipe_sel(display)) 60 pipe = REG_FIELD_GET(VGA_PIPE_SEL_MASK, tmp); 61 else 62 pipe = PIPE_A; 63 64 drm_dbg_kms(display->drm, "Disabling VGA plane on pipe %c\n", 65 pipe_name(pipe)); 66 67 /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */ 68 vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); 69 outb(0x01, VGA_SEQ_I); 70 sr1 = inb(VGA_SEQ_D); 71 outb(sr1 | VGA_SR01_SCREEN_OFF, VGA_SEQ_D); 72 vga_put(pdev, VGA_RSRC_LEGACY_IO); 73 udelay(300); 74 75 intel_de_write(display, vga_reg, VGA_DISP_DISABLE); 76 intel_de_posting_read(display, vga_reg); 77 } 78 79 void intel_vga_reset_io_mem(struct intel_display *display) 80 { 81 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 82 83 /* 84 * After we re-enable the power well, if we touch VGA register 0x3d5 85 * we'll get unclaimed register interrupts. This stops after we write 86 * anything to the VGA MSR register. The vgacon module uses this 87 * register all the time, so if we unbind our driver and, as a 88 * consequence, bind vgacon, we'll get stuck in an infinite loop at 89 * console_unlock(). So make here we touch the VGA MSR register, making 90 * sure vgacon can keep working normally without triggering interrupts 91 * and error messages. 92 */ 93 vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); 94 outb(inb(VGA_MIS_R), VGA_MIS_W); 95 vga_put(pdev, VGA_RSRC_LEGACY_IO); 96 } 97 98 static int intel_gmch_vga_set_state(struct intel_display *display, bool enable_decode) 99 { 100 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 101 unsigned int reg = DISPLAY_VER(display) >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL; 102 u16 gmch_ctrl; 103 104 if (pci_bus_read_config_word(pdev->bus, PCI_DEVFN(0, 0), reg, &gmch_ctrl)) { 105 drm_err(display->drm, "failed to read control word\n"); 106 return -EIO; 107 } 108 109 if (!!(gmch_ctrl & INTEL_GMCH_VGA_DISABLE) == !enable_decode) 110 return 0; 111 112 if (enable_decode) 113 gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; 114 else 115 gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; 116 117 if (pci_bus_write_config_word(pdev->bus, PCI_DEVFN(0, 0), reg, gmch_ctrl)) { 118 drm_err(display->drm, "failed to write control word\n"); 119 return -EIO; 120 } 121 122 return 0; 123 } 124 125 static unsigned int intel_gmch_vga_set_decode(struct pci_dev *pdev, bool enable_decode) 126 { 127 struct intel_display *display = to_intel_display(pdev); 128 129 intel_gmch_vga_set_state(display, enable_decode); 130 131 if (enable_decode) 132 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | 133 VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 134 else 135 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 136 } 137 138 int intel_vga_register(struct intel_display *display) 139 { 140 141 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 142 int ret; 143 144 /* 145 * If we have > 1 VGA cards, then we need to arbitrate access to the 146 * common VGA resources. 147 * 148 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), 149 * then we do not take part in VGA arbitration and the 150 * vga_client_register() fails with -ENODEV. 151 */ 152 ret = vga_client_register(pdev, intel_gmch_vga_set_decode); 153 if (ret && ret != -ENODEV) 154 return ret; 155 156 return 0; 157 } 158 159 void intel_vga_unregister(struct intel_display *display) 160 { 161 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 162 163 vga_client_unregister(pdev); 164 } 165