xref: /openbmc/linux/drivers/gpu/drm/i915/display/intel_vga.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
14fb87831SJani Nikula // SPDX-License-Identifier: MIT
24fb87831SJani Nikula /*
34fb87831SJani Nikula  * Copyright © 2019 Intel Corporation
44fb87831SJani Nikula  */
54fb87831SJani Nikula 
64fb87831SJani Nikula #include <linux/pci.h>
74fb87831SJani Nikula #include <linux/vgaarb.h>
84fb87831SJani Nikula 
9f0bb41faSJani Nikula #include <video/vga.h>
104fb87831SJani Nikula 
11*eee838e4SJani Nikula #include "soc/intel_gmch.h"
12*eee838e4SJani Nikula 
134fb87831SJani Nikula #include "i915_drv.h"
14801543b2SJani Nikula #include "i915_reg.h"
1570bc7ed9SJani Nikula #include "intel_de.h"
164fb87831SJani Nikula #include "intel_vga.h"
174fb87831SJani Nikula 
intel_vga_cntrl_reg(struct drm_i915_private * i915)184fb87831SJani Nikula static i915_reg_t intel_vga_cntrl_reg(struct drm_i915_private *i915)
194fb87831SJani Nikula {
204fb87831SJani Nikula 	if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
214fb87831SJani Nikula 		return VLV_VGACNTRL;
22005e9537SMatt Roper 	else if (DISPLAY_VER(i915) >= 5)
234fb87831SJani Nikula 		return CPU_VGACNTRL;
244fb87831SJani Nikula 	else
254fb87831SJani Nikula 		return VGACNTRL;
264fb87831SJani Nikula }
274fb87831SJani Nikula 
284fb87831SJani Nikula /* Disable the VGA plane that we never use */
intel_vga_disable(struct drm_i915_private * dev_priv)294fb87831SJani Nikula void intel_vga_disable(struct drm_i915_private *dev_priv)
304fb87831SJani Nikula {
318ff5446aSThomas Zimmermann 	struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
324fb87831SJani Nikula 	i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv);
334fb87831SJani Nikula 	u8 sr1;
344fb87831SJani Nikula 
35a3af0140SEmil Velikov 	if (intel_de_read(dev_priv, vga_reg) & VGA_DISP_DISABLE)
36a3af0140SEmil Velikov 		return;
37a3af0140SEmil Velikov 
384fb87831SJani Nikula 	/* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
394fb87831SJani Nikula 	vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
40f0bb41faSJani Nikula 	outb(0x01, VGA_SEQ_I);
41f0bb41faSJani Nikula 	sr1 = inb(VGA_SEQ_D);
42f0bb41faSJani Nikula 	outb(sr1 | VGA_SR01_SCREEN_OFF, VGA_SEQ_D);
434fb87831SJani Nikula 	vga_put(pdev, VGA_RSRC_LEGACY_IO);
444fb87831SJani Nikula 	udelay(300);
454fb87831SJani Nikula 
4670bc7ed9SJani Nikula 	intel_de_write(dev_priv, vga_reg, VGA_DISP_DISABLE);
4770bc7ed9SJani Nikula 	intel_de_posting_read(dev_priv, vga_reg);
484fb87831SJani Nikula }
494fb87831SJani Nikula 
intel_vga_redisable_power_on(struct drm_i915_private * dev_priv)504fb87831SJani Nikula void intel_vga_redisable_power_on(struct drm_i915_private *dev_priv)
514fb87831SJani Nikula {
524fb87831SJani Nikula 	i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv);
534fb87831SJani Nikula 
5470bc7ed9SJani Nikula 	if (!(intel_de_read(dev_priv, vga_reg) & VGA_DISP_DISABLE)) {
552d733850SWambui Karuga 		drm_dbg_kms(&dev_priv->drm,
562d733850SWambui Karuga 			    "Something enabled VGA plane, disabling it\n");
574fb87831SJani Nikula 		intel_vga_disable(dev_priv);
584fb87831SJani Nikula 	}
594fb87831SJani Nikula }
604fb87831SJani Nikula 
intel_vga_redisable(struct drm_i915_private * i915)614fb87831SJani Nikula void intel_vga_redisable(struct drm_i915_private *i915)
624fb87831SJani Nikula {
634fb87831SJani Nikula 	intel_wakeref_t wakeref;
644fb87831SJani Nikula 
654fb87831SJani Nikula 	/*
664fb87831SJani Nikula 	 * This function can be called both from intel_modeset_setup_hw_state or
674fb87831SJani Nikula 	 * at a very early point in our resume sequence, where the power well
684fb87831SJani Nikula 	 * structures are not yet restored. Since this function is at a very
694fb87831SJani Nikula 	 * paranoid "someone might have enabled VGA while we were not looking"
704fb87831SJani Nikula 	 * level, just check if the power well is enabled instead of trying to
714fb87831SJani Nikula 	 * follow the "don't touch the power well if we don't need it" policy
724fb87831SJani Nikula 	 * the rest of the driver uses.
734fb87831SJani Nikula 	 */
744fb87831SJani Nikula 	wakeref = intel_display_power_get_if_enabled(i915, POWER_DOMAIN_VGA);
754fb87831SJani Nikula 	if (!wakeref)
764fb87831SJani Nikula 		return;
774fb87831SJani Nikula 
784fb87831SJani Nikula 	intel_vga_redisable_power_on(i915);
794fb87831SJani Nikula 
804fb87831SJani Nikula 	intel_display_power_put(i915, POWER_DOMAIN_VGA, wakeref);
814fb87831SJani Nikula }
824fb87831SJani Nikula 
intel_vga_reset_io_mem(struct drm_i915_private * i915)837fd29602SJani Nikula void intel_vga_reset_io_mem(struct drm_i915_private *i915)
844fb87831SJani Nikula {
858ff5446aSThomas Zimmermann 	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
864fb87831SJani Nikula 
874fb87831SJani Nikula 	/*
884fb87831SJani Nikula 	 * After we re-enable the power well, if we touch VGA register 0x3d5
894fb87831SJani Nikula 	 * we'll get unclaimed register interrupts. This stops after we write
904fb87831SJani Nikula 	 * anything to the VGA MSR register. The vgacon module uses this
914fb87831SJani Nikula 	 * register all the time, so if we unbind our driver and, as a
924fb87831SJani Nikula 	 * consequence, bind vgacon, we'll get stuck in an infinite loop at
934fb87831SJani Nikula 	 * console_unlock(). So make here we touch the VGA MSR register, making
944fb87831SJani Nikula 	 * sure vgacon can keep working normally without triggering interrupts
954fb87831SJani Nikula 	 * and error messages.
964fb87831SJani Nikula 	 */
974fb87831SJani Nikula 	vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
98f0bb41faSJani Nikula 	outb(inb(VGA_MIS_R), VGA_MIS_W);
994fb87831SJani Nikula 	vga_put(pdev, VGA_RSRC_LEGACY_IO);
1004fb87831SJani Nikula }
1014fb87831SJani Nikula 
1024fb87831SJani Nikula static unsigned int
intel_vga_set_decode(struct pci_dev * pdev,bool enable_decode)103bf44e8ceSChristoph Hellwig intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
1044fb87831SJani Nikula {
105bf44e8ceSChristoph Hellwig 	struct drm_i915_private *i915 = pdev_to_i915(pdev);
1064fb87831SJani Nikula 
107*eee838e4SJani Nikula 	intel_gmch_vga_set_state(i915, enable_decode);
1084fb87831SJani Nikula 
1094fb87831SJani Nikula 	if (enable_decode)
1104fb87831SJani Nikula 		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
1114fb87831SJani Nikula 		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
1124fb87831SJani Nikula 	else
1134fb87831SJani Nikula 		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
1144fb87831SJani Nikula }
1154fb87831SJani Nikula 
intel_vga_register(struct drm_i915_private * i915)1164fb87831SJani Nikula int intel_vga_register(struct drm_i915_private *i915)
1174fb87831SJani Nikula {
118bf44e8ceSChristoph Hellwig 
1198ff5446aSThomas Zimmermann 	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
1204fb87831SJani Nikula 	int ret;
1214fb87831SJani Nikula 
1224fb87831SJani Nikula 	/*
1234fb87831SJani Nikula 	 * If we have > 1 VGA cards, then we need to arbitrate access to the
1244fb87831SJani Nikula 	 * common VGA resources.
1254fb87831SJani Nikula 	 *
1264fb87831SJani Nikula 	 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
1274fb87831SJani Nikula 	 * then we do not take part in VGA arbitration and the
1284fb87831SJani Nikula 	 * vga_client_register() fails with -ENODEV.
1294fb87831SJani Nikula 	 */
130bf44e8ceSChristoph Hellwig 	ret = vga_client_register(pdev, intel_vga_set_decode);
1314fb87831SJani Nikula 	if (ret && ret != -ENODEV)
1324fb87831SJani Nikula 		return ret;
1334fb87831SJani Nikula 
1344fb87831SJani Nikula 	return 0;
1354fb87831SJani Nikula }
1364fb87831SJani Nikula 
intel_vga_unregister(struct drm_i915_private * i915)1374fb87831SJani Nikula void intel_vga_unregister(struct drm_i915_private *i915)
1384fb87831SJani Nikula {
1398ff5446aSThomas Zimmermann 	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
1404fb87831SJani Nikula 
141b8779475SChristoph Hellwig 	vga_client_unregister(pdev);
1424fb87831SJani Nikula }
143