LCOV - code coverage report
Current view: top level - dev/pci/drm/i915 - intel_gtt.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 123 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org>
       3             :  *
       4             :  * Permission to use, copy, modify, and distribute this software for any
       5             :  * purpose with or without fee is hereby granted, provided that the above
       6             :  * copyright notice and this permission notice appear in all copies.
       7             :  *
       8             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
       9             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      10             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      11             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      12             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      13             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      14             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      15             :  */
      16             : 
      17             : #include "i915_drv.h"
      18             : 
      19             : /* MCH IFP BARs */
      20             : #define I915_IFPADDR    0x60
      21             : #define I965_IFPADDR    0x70
      22             : 
      23             : extern struct cfdriver inteldrm_cd;
      24             : 
      25             : /*
      26             :  * We're intel IGD, bus 0 function 0 dev 0 should be the GMCH, so it should
      27             :  * be Intel
      28             :  */
      29             : int
      30           0 : inteldrm_gmch_match(struct pci_attach_args *pa)
      31             : {
      32           0 :         if (pa->pa_bus == 0 && pa->pa_device == 0 && pa->pa_function == 0 &&
      33           0 :             PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
      34           0 :             PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
      35           0 :             PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST)
      36           0 :                 return (1);
      37           0 :         return (0);
      38           0 : }
      39             : 
      40             : void
      41           0 : i915_alloc_ifp(struct inteldrm_softc *dev_priv, struct pci_attach_args *bpa)
      42             : {
      43           0 :         bus_addr_t      addr;
      44             :         u_int32_t       reg;
      45             : 
      46           0 :         dev_priv->ifp.i9xx.bst = bpa->pa_memt;
      47             : 
      48           0 :         reg = pci_conf_read(bpa->pa_pc, bpa->pa_tag, I915_IFPADDR);
      49           0 :         if (reg & 0x1) {
      50           0 :                 addr = (bus_addr_t)reg;
      51           0 :                 addr &= ~0x1;
      52             :                 /* XXX extents ... need data on whether bioses alloc or not. */
      53           0 :                 if (bus_space_map(bpa->pa_memt, addr, PAGE_SIZE, 0,
      54           0 :                     &dev_priv->ifp.i9xx.bsh) != 0)
      55             :                         goto nope;
      56           0 :                 return;
      57           0 :         } else if (bpa->pa_memex == NULL ||
      58           0 :             extent_alloc_subregion(bpa->pa_memex, 0x100000, 0xffffffff,
      59           0 :             PAGE_SIZE, PAGE_SIZE, 0, 0, 0, &addr) ||
      60           0 :             bus_space_map(bpa->pa_memt, addr, PAGE_SIZE, 0,
      61           0 :             &dev_priv->ifp.i9xx.bsh))
      62             :                 goto nope;
      63             : 
      64           0 :         pci_conf_write(bpa->pa_pc, bpa->pa_tag, I915_IFPADDR, addr | 0x1);
      65             : 
      66           0 :         return;
      67             : 
      68             : nope:
      69           0 :         dev_priv->ifp.i9xx.bsh = 0;
      70           0 :         printf("%s: no ifp\n", dev_priv->sc_dev.dv_xname);
      71           0 : }
      72             : 
      73             : void
      74           0 : i965_alloc_ifp(struct inteldrm_softc *dev_priv, struct pci_attach_args *bpa)
      75             : {
      76           0 :         bus_addr_t      addr;
      77             :         u_int32_t       lo, hi;
      78             : 
      79           0 :         dev_priv->ifp.i9xx.bst = bpa->pa_memt;
      80             : 
      81           0 :         hi = pci_conf_read(bpa->pa_pc, bpa->pa_tag, I965_IFPADDR + 4);
      82           0 :         lo = pci_conf_read(bpa->pa_pc, bpa->pa_tag, I965_IFPADDR);
      83           0 :         if (lo & 0x1) {
      84           0 :                 addr = (((u_int64_t)hi << 32) | lo);
      85           0 :                 addr &= ~0x1;
      86             :                 /* XXX extents ... need data on whether bioses alloc or not. */
      87           0 :                 if (bus_space_map(bpa->pa_memt, addr, PAGE_SIZE, 0,
      88           0 :                     &dev_priv->ifp.i9xx.bsh) != 0)
      89             :                         goto nope;
      90           0 :                 return;
      91           0 :         } else if (bpa->pa_memex == NULL ||
      92           0 :             extent_alloc_subregion(bpa->pa_memex, 0x100000, 0xffffffff,
      93           0 :             PAGE_SIZE, PAGE_SIZE, 0, 0, 0, &addr) ||
      94           0 :             bus_space_map(bpa->pa_memt, addr, PAGE_SIZE, 0,
      95           0 :             &dev_priv->ifp.i9xx.bsh))
      96             :                 goto nope;
      97             : 
      98           0 :         pci_conf_write(bpa->pa_pc, bpa->pa_tag, I965_IFPADDR + 4,
      99           0 :             upper_32_bits(addr));
     100           0 :         pci_conf_write(bpa->pa_pc, bpa->pa_tag, I965_IFPADDR,
     101           0 :             (addr & 0xffffffff) | 0x1);
     102             : 
     103           0 :         return;
     104             : 
     105             : nope:
     106           0 :         dev_priv->ifp.i9xx.bsh = 0;
     107           0 :         printf("%s: no ifp\n", dev_priv->sc_dev.dv_xname);
     108           0 : }
     109             : 
     110             : void
     111           0 : intel_gtt_chipset_setup(struct drm_device *dev)
     112             : {
     113           0 :         struct inteldrm_softc *dev_priv = dev->dev_private;
     114           0 :         struct pci_attach_args bpa;
     115             : 
     116           0 :         if (INTEL_INFO(dev_priv->dev)->gen >= 6)
     117           0 :                 return;
     118             : 
     119           0 :         if (pci_find_device(&bpa, inteldrm_gmch_match) == 0) {
     120           0 :                 printf("%s: can't find GMCH\n",
     121           0 :                     dev_priv->sc_dev.dv_xname);
     122           0 :                 return;
     123             :         }
     124             : 
     125             :         /* Set up the IFP for chipset flushing */
     126           0 :         if (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) ||
     127           0 :             IS_I945GM(dev)) {
     128           0 :                 i915_alloc_ifp(dev_priv, &bpa);
     129           0 :         } else if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev)) {
     130           0 :                 i965_alloc_ifp(dev_priv, &bpa);
     131           0 :         } else {
     132           0 :                 int nsegs;
     133             :                 /*
     134             :                  * I8XX has no flush page mechanism, we fake it by writing until
     135             :                  * the cache is empty. allocate a page to scribble on
     136             :                  */
     137           0 :                 dev_priv->ifp.i8xx.kva = NULL;
     138           0 :                 if (bus_dmamem_alloc(dev_priv->dmat, PAGE_SIZE, 0, 0,
     139           0 :                     &dev_priv->ifp.i8xx.seg, 1, &nsegs, BUS_DMA_WAITOK) == 0) {
     140           0 :                         if (bus_dmamem_map(dev_priv->dmat, &dev_priv->ifp.i8xx.seg,
     141           0 :                             1, PAGE_SIZE, &dev_priv->ifp.i8xx.kva, 0) != 0) {
     142           0 :                                 bus_dmamem_free(dev_priv->dmat,
     143             :                                     &dev_priv->ifp.i8xx.seg, nsegs);
     144           0 :                                 dev_priv->ifp.i8xx.kva = NULL;
     145           0 :                         }
     146             :                 }
     147           0 :         }
     148           0 : }
     149             : 
     150             : int
     151           0 : intel_enable_gtt()
     152             : {
     153           0 :         struct inteldrm_softc *dev_priv = (void *)inteldrm_cd.cd_devs[0];
     154             : 
     155           0 :         intel_gtt_chipset_setup(dev_priv->dev);
     156           0 :         return 1;
     157             : }
     158             : 
     159             : int
     160           0 : intel_gmch_probe(struct pci_dev *bridge_dev, struct pci_dev *gpu_pdev,
     161             :     void *bridge)
     162             : {
     163           0 :         return 1;
     164             : }
     165             : 
     166             : void
     167           0 : intel_gtt_get(u64 *gtt_total, size_t *stolen_size,
     168             :     phys_addr_t *mappable_base, u64 *mappable_end)
     169             : {
     170           0 :         struct inteldrm_softc *dev_priv = (void *)inteldrm_cd.cd_devs[0];
     171           0 :         struct agp_info *ai = &dev_priv->dev->agp->info;
     172             :         
     173           0 :         *gtt_total = ai->ai_aperture_size;
     174           0 :         *stolen_size = 0;
     175           0 :         *mappable_base = ai->ai_aperture_base;
     176           0 :         *mappable_end = ai->ai_aperture_size;
     177           0 : }
     178             : 
     179             : void
     180           0 : intel_gtt_chipset_flush(void)
     181             : {
     182           0 :         struct inteldrm_softc *dev_priv = (void *)inteldrm_cd.cd_devs[0];
     183             : 
     184             :         /*
     185             :          * Write to this flush page flushes the chipset write cache.
     186             :          * The write will return when it is done.
     187             :          */
     188           0 :         if (INTEL_INFO(dev_priv->dev)->gen >= 3) {
     189           0 :             if (dev_priv->ifp.i9xx.bsh != 0)
     190           0 :                 bus_space_write_4(dev_priv->ifp.i9xx.bst,
     191             :                     dev_priv->ifp.i9xx.bsh, 0, 1);
     192             :         } else {
     193             :                 int i;
     194             : 
     195           0 :                 wbinvd();
     196             : 
     197             : #define I830_HIC        0x70
     198             : 
     199           0 :                 I915_WRITE(I830_HIC, (I915_READ(I830_HIC) | (1<<31)));
     200           0 :                 for (i = 1000; i; i--) {
     201           0 :                         if (!(I915_READ(I830_HIC) & (1<<31)))
     202             :                                 break;
     203           0 :                         delay(100);
     204             :                 }
     205             : 
     206             :         }
     207           0 : }
     208             : 
     209             : void
     210           0 : intel_gmch_remove(void)
     211             : {
     212           0 : }
     213             : 
     214             : void
     215           0 : intel_gtt_insert_sg_entries(struct sg_table *pages, unsigned int pg_start,
     216             :     unsigned int flags)
     217             : {
     218           0 :         struct inteldrm_softc *dev_priv = (void *)inteldrm_cd.cd_devs[0];
     219           0 :         struct agp_softc *sc = dev_priv->dev->agp->agpdev;
     220           0 :         bus_addr_t addr = sc->sc_apaddr + pg_start * PAGE_SIZE;
     221           0 :         struct sg_page_iter sg_iter;
     222             : 
     223           0 :         for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
     224           0 :                 sc->sc_methods->bind_page(sc->sc_chipc, addr,
     225           0 :                     sg_page_iter_dma_address(&sg_iter), flags);
     226           0 :                 addr += PAGE_SIZE;
     227             :         }
     228           0 : }
     229             : 
     230             : void
     231           0 : intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
     232             : {
     233           0 :         struct inteldrm_softc *dev_priv = (void *)inteldrm_cd.cd_devs[0];
     234           0 :         struct agp_softc *sc = dev_priv->dev->agp->agpdev;
     235           0 :         bus_addr_t addr = sc->sc_apaddr + first_entry * PAGE_SIZE;
     236             :         int i;
     237             : 
     238           0 :         for (i = 0; i < num_entries; i++) {
     239           0 :                 sc->sc_methods->unbind_page(sc->sc_chipc, addr);
     240           0 :                 addr += PAGE_SIZE;
     241             :         }
     242           0 : }

Generated by: LCOV version 1.13