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