FILE
intel_vga.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/i915/display/intel_vga.c
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 <video/vga.h> 13 14#include "soc/intel_gmch.h" 15 16#include "intel_de.h" 17#include "intel_display.h" 18#include "intel_vga.h" 19#include "intel_vga_regs.h" 20 21static 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 31static 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 */ 45void 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 79void 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 98int intel_vga_register(struct intel_display *display) 99{ 100 101 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 102 int ret; 103 104 /* 105 * If we have > 1 VGA cards, then we need to arbitrate access to the 106 * common VGA resources. 107 * 108 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), 109 * then we do not take part in VGA arbitration and the 110 * vga_client_register() fails with -ENODEV. 111 */ 112 ret = vga_client_register(pdev, intel_gmch_vga_set_decode); 113 if (ret && ret != -ENODEV) 114 return ret; 115 116 return 0; 117} 118 119void intel_vga_unregister(struct intel_display *display) 120{ 121 struct pci_dev *pdev = to_pci_dev(display->drm->dev); 122 123 vga_client_unregister(pdev); 124}
~/
Read-only file preview.