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

          Line data    Source code
       1             : /*      $OpenBSD: agp_i810.c,v 1.93 2015/12/19 16:07:20 kettenis Exp $  */
       2             : 
       3             : /*-
       4             :  * Copyright (c) 2000 Doug Rabson
       5             :  * Copyright (c) 2000 Ruslan Ermilov
       6             :  * All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  * 1. Redistributions of source code must retain the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer.
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      18             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      19             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      20             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      21             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      22             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      23             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      24             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      25             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      26             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      27             :  * SUCH DAMAGE.
      28             :  *
      29             :  */
      30             : 
      31             : #include "acpi.h"
      32             : #include "drm.h"
      33             : #include "vga.h"
      34             : 
      35             : #include <sys/param.h>
      36             : #include <sys/systm.h>
      37             : #include <sys/malloc.h>
      38             : #include <sys/device.h>
      39             : #include <sys/rwlock.h>
      40             : 
      41             : #include <dev/pci/pcivar.h>
      42             : #include <dev/pci/pcireg.h>
      43             : #include <dev/pci/pcidevs.h>
      44             : #include <dev/pci/agpvar.h>
      45             : #include <dev/pci/agpreg.h>
      46             : #include <dev/pci/drm/i915/i915_drv.h>
      47             : 
      48             : #include <machine/bus.h>
      49             : 
      50             : #define READ1(off)      bus_space_read_1(isc->map->bst, isc->map->bsh, off)
      51             : #define READ4(off)      bus_space_read_4(isc->map->bst, isc->map->bsh, off)
      52             : #define WRITE4(off,v)   bus_space_write_4(isc->map->bst, isc->map->bsh, off, v)
      53             : 
      54             : /*
      55             :  * Intel IGP gtt bits.
      56             :  */
      57             : /* PTE is enabled */
      58             : #define INTEL_ENABLED   0x1
      59             : /* I810/I815 only, memory is in dcache */
      60             : #define INTEL_LOCAL     0x2
      61             : /* Memory is snooped, must not be accessed through gtt from the cpu. */
      62             : #define INTEL_COHERENT  0x6     
      63             : 
      64             : enum {
      65             :         CHIP_NONE       = 0,    /* not integrated graphics */
      66             :         CHIP_I810       = 1,    /* i810/i815 */
      67             :         CHIP_I830       = 2,    /* i830/i845 */
      68             :         CHIP_I855       = 3,    /* i852GM/i855GM/i865G */
      69             :         CHIP_I915       = 4,    /* i915G/i915GM */
      70             :         CHIP_I965       = 5,    /* i965/i965GM */
      71             :         CHIP_G33        = 6,    /* G33/Q33/Q35 */
      72             :         CHIP_G4X        = 7,    /* G4X */
      73             :         CHIP_PINEVIEW   = 8,    /* Pineview/Pineview M */
      74             :         CHIP_IRONLAKE   = 9,    /* Clarkdale/Arrandale */
      75             : };
      76             : 
      77             : struct agp_i810_softc {
      78             :         struct device            dev;
      79             :         bus_dma_segment_t        scrib_seg;
      80             :         struct agp_softc        *agpdev;
      81             :         struct agp_gatt         *gatt;
      82             :         struct vga_pci_bar      *map;
      83             :         bus_space_tag_t          gtt_bst;
      84             :         bus_space_handle_t       gtt_bsh;
      85             :         bus_size_t               gtt_size;
      86             :         bus_dmamap_t             scrib_dmamap;
      87             :         bus_addr_t               isc_apaddr;
      88             :         bus_size_t               isc_apsize;    /* current aperture size */
      89             :         int                      chiptype;      /* i810-like or i830 */
      90             :         u_int32_t                dcache_size;   /* i810 only */
      91             :         u_int32_t                stolen;        /* number of i830/845 gtt
      92             :                                                    entries for stolen memory */
      93             : };
      94             : 
      95             : void    agp_i810_attach(struct device *, struct device *, void *);
      96             : int     agp_i810_activate(struct device *, int);
      97             : void    agp_i810_configure(struct agp_i810_softc *);
      98             : int     agp_i810_probe(struct device *, void *, void *);
      99             : int     agp_i810_get_chiptype(struct pci_attach_args *);
     100             : void    agp_i810_bind_page(void *, bus_size_t, paddr_t, int);
     101             : void    agp_i810_unbind_page(void *, bus_size_t);
     102             : void    agp_i810_flush_tlb(void *);
     103             : int     agp_i810_enable(void *, u_int32_t mode);
     104             : void    intagp_write_gtt(struct agp_i810_softc *, bus_size_t, paddr_t);
     105             : int     intagp_gmch_match(struct pci_attach_args *);
     106             : 
     107             : extern void     intagp_dma_sync(bus_dma_tag_t, bus_dmamap_t,
     108             :                     bus_addr_t, bus_size_t, int);
     109             : 
     110             : struct cfattach intagp_ca = {
     111             :         sizeof(struct agp_i810_softc), agp_i810_probe, agp_i810_attach,
     112             :         NULL, agp_i810_activate,
     113             : };
     114             : 
     115             : struct cfdriver intagp_cd = {
     116             :         NULL, "intagp", DV_DULL
     117             : };
     118             : 
     119             : struct agp_methods agp_i810_methods = {
     120             :         agp_i810_bind_page,
     121             :         agp_i810_unbind_page,
     122             :         agp_i810_flush_tlb,
     123             :         agp_i810_enable,
     124             : };
     125             : 
     126             : int
     127           0 : agp_i810_get_chiptype(struct pci_attach_args *pa)
     128             : {
     129           0 :         switch (PCI_PRODUCT(pa->pa_id)) {
     130             :         case PCI_PRODUCT_INTEL_82810_IGD:
     131             :         case PCI_PRODUCT_INTEL_82810_DC100_IGD:
     132             :         case PCI_PRODUCT_INTEL_82810E_IGD:
     133             :         case PCI_PRODUCT_INTEL_82815_IGD:
     134           0 :                 return (CHIP_I810);
     135             :                 break;
     136             :         case PCI_PRODUCT_INTEL_82830M_IGD:
     137             :         case PCI_PRODUCT_INTEL_82845G_IGD:
     138           0 :                 return (CHIP_I830);
     139             :                 break;
     140             :         case PCI_PRODUCT_INTEL_82854_IGD:
     141             :         case PCI_PRODUCT_INTEL_82855GM_IGD:
     142             :         case PCI_PRODUCT_INTEL_82865G_IGD:
     143           0 :                 return (CHIP_I855);
     144             :                 break;
     145             :         case PCI_PRODUCT_INTEL_E7221_IGD:
     146             :         case PCI_PRODUCT_INTEL_82915G_IGD_1:
     147             :         case PCI_PRODUCT_INTEL_82915G_IGD_2:
     148             :         case PCI_PRODUCT_INTEL_82915GM_IGD_1:
     149             :         case PCI_PRODUCT_INTEL_82915GM_IGD_2:
     150             :         case PCI_PRODUCT_INTEL_82945G_IGD_1:
     151             :         case PCI_PRODUCT_INTEL_82945G_IGD_2:
     152             :         case PCI_PRODUCT_INTEL_82945GM_IGD_1:
     153             :         case PCI_PRODUCT_INTEL_82945GM_IGD_2:
     154             :         case PCI_PRODUCT_INTEL_82945GME_IGD_1:
     155           0 :                 return (CHIP_I915);
     156             :                 break;
     157             :         case PCI_PRODUCT_INTEL_82946GZ_IGD_1:
     158             :         case PCI_PRODUCT_INTEL_82946GZ_IGD_2:
     159             :         case PCI_PRODUCT_INTEL_82Q965_IGD_1:
     160             :         case PCI_PRODUCT_INTEL_82Q965_IGD_2:
     161             :         case PCI_PRODUCT_INTEL_82G965_IGD_1:
     162             :         case PCI_PRODUCT_INTEL_82G965_IGD_2:
     163             :         case PCI_PRODUCT_INTEL_82GM965_IGD_1:
     164             :         case PCI_PRODUCT_INTEL_82GM965_IGD_2:
     165             :         case PCI_PRODUCT_INTEL_82GME965_IGD_1:
     166             :         case PCI_PRODUCT_INTEL_82GME965_IGD_2:
     167             :         case PCI_PRODUCT_INTEL_82G35_IGD_1:
     168             :         case PCI_PRODUCT_INTEL_82G35_IGD_2:
     169           0 :                 return (CHIP_I965);
     170             :                 break;
     171             :         case PCI_PRODUCT_INTEL_82G33_IGD_1:
     172             :         case PCI_PRODUCT_INTEL_82G33_IGD_2:
     173             :         case PCI_PRODUCT_INTEL_82Q35_IGD_1:
     174             :         case PCI_PRODUCT_INTEL_82Q35_IGD_2:
     175             :         case PCI_PRODUCT_INTEL_82Q33_IGD_1:
     176             :         case PCI_PRODUCT_INTEL_82Q33_IGD_2:
     177           0 :                 return (CHIP_G33);
     178             :                 break;
     179             :         case PCI_PRODUCT_INTEL_82GM45_IGD_1:
     180             :         case PCI_PRODUCT_INTEL_4SERIES_IGD:
     181             :         case PCI_PRODUCT_INTEL_82Q45_IGD_1:
     182             :         case PCI_PRODUCT_INTEL_82G45_IGD_1:
     183             :         case PCI_PRODUCT_INTEL_82G41_IGD_1:
     184             :         case PCI_PRODUCT_INTEL_82B43_IGD_1:
     185             :         case PCI_PRODUCT_INTEL_82B43_IGD_2:
     186           0 :                 return (CHIP_G4X);
     187             :                 break;
     188             :         case PCI_PRODUCT_INTEL_PINEVIEW_IGC_1:
     189             :         case PCI_PRODUCT_INTEL_PINEVIEW_M_IGC_1:
     190           0 :                 return (CHIP_PINEVIEW);
     191             :                 break;
     192             :         case PCI_PRODUCT_INTEL_CLARKDALE_IGD:
     193             :         case PCI_PRODUCT_INTEL_ARRANDALE_IGD:
     194           0 :                 return (CHIP_IRONLAKE);
     195             :                 break;
     196             :         }
     197             :         
     198           0 :         return (CHIP_NONE);
     199           0 : }
     200             : 
     201             : /*
     202             :  * We're intel IGD, bus 0 function 0 dev 0 should be the GMCH, so it should
     203             :  * be Intel
     204             :  */
     205             : int
     206           0 : intagp_gmch_match(struct pci_attach_args *pa)
     207             : {
     208           0 :         if (pa->pa_bus == 0 && pa->pa_device == 0 && pa->pa_function == 0 &&
     209           0 :             PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
     210           0 :             PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
     211           0 :             PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST)
     212           0 :                 return (1);
     213           0 :         return (0);
     214           0 : }
     215             : 
     216             : int
     217           0 : agp_i810_probe(struct device *parent, void *match, void *aux)
     218             : {
     219           0 :         struct pci_attach_args  *pa = aux;
     220             : 
     221           0 :         if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
     222           0 :             PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
     223           0 :                 return (0);
     224             : 
     225           0 :         return (agp_i810_get_chiptype(pa) != CHIP_NONE);
     226           0 : }
     227             : 
     228             : void
     229           0 : agp_i810_attach(struct device *parent, struct device *self, void *aux)
     230             : {
     231           0 :         struct agp_i810_softc           *isc = (struct agp_i810_softc *)self;
     232             :         struct agp_gatt                 *gatt;
     233           0 :         struct pci_attach_args          *pa = aux, bpa;
     234           0 :         struct inteldrm_softc           *psc = (struct inteldrm_softc *)parent;
     235           0 :         bus_addr_t                       mmaddr, gmaddr, tmp;
     236             :         bus_size_t                       gtt_off = 0;
     237             :         pcireg_t                         memtype, reg;
     238             :         u_int32_t                        stolen;
     239             :         u_int16_t                        gcc1;
     240             : 
     241           0 :         isc->chiptype = agp_i810_get_chiptype(pa);
     242             : 
     243           0 :         switch (isc->chiptype) {
     244             :         case CHIP_I915:
     245             :         case CHIP_G33:
     246             :         case CHIP_PINEVIEW:
     247             :                 gmaddr = AGP_I915_GMADR;
     248             :                 mmaddr = AGP_I915_MMADR;
     249             :                 memtype = PCI_MAPREG_TYPE_MEM;
     250           0 :                 break;
     251             :         case CHIP_I965:
     252             :         case CHIP_G4X:
     253             :         case CHIP_IRONLAKE:
     254             :                 gmaddr = AGP_I965_GMADR;
     255             :                 mmaddr = AGP_I965_MMADR;
     256             :                 memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT;
     257           0 :                 if (isc->chiptype == CHIP_I965)
     258           0 :                         gtt_off = AGP_I965_GTT;
     259             :                 else
     260             :                         gtt_off = AGP_G4X_GTT;
     261             :                 break;
     262             :         default:
     263             :                 gmaddr = AGP_APBASE;
     264             :                 mmaddr = AGP_I810_MMADR;
     265             :                 memtype = PCI_MAPREG_TYPE_MEM;
     266             :                 gtt_off = AGP_I810_GTT;
     267           0 :                 break;
     268             :         }
     269             : 
     270           0 :         if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, gmaddr, memtype,
     271           0 :             &isc->isc_apaddr, &isc->isc_apsize, NULL) != 0) {
     272           0 :                 printf("can't get aperture info\n");
     273           0 :                 return;
     274             :         }
     275             : 
     276           0 :         isc->map = psc->regs;
     277             : 
     278           0 :         if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33 ||
     279           0 :             isc->chiptype == CHIP_PINEVIEW) {
     280           0 :                 if (pci_mapreg_map(pa, AGP_I915_GTTADR, memtype,
     281           0 :                     BUS_SPACE_MAP_LINEAR, &isc->gtt_bst, &isc->gtt_bsh,
     282           0 :                     NULL, &isc->gtt_size, 0)) {
     283           0 :                         printf("can't map gatt registers\n");
     284           0 :                         goto out;
     285             :                 }
     286           0 :         } else if (gtt_off >= isc->map->size) {
     287             :                 isc->gtt_bst = isc->map->bst;
     288           0 :                 isc->gtt_size = (isc->isc_apsize >> AGP_PAGE_SHIFT) * 4;
     289           0 :                 if (bus_space_map(isc->gtt_bst, isc->map->base + gtt_off,
     290           0 :                     isc->gtt_size, BUS_SPACE_MAP_LINEAR, &isc->gtt_bsh)) {
     291           0 :                         printf("can't map gatt registers\n");
     292           0 :                         isc->gtt_size = 0;
     293           0 :                         goto out;
     294             :                 }
     295             :         } else {
     296             :                 isc->gtt_bst = isc->map->bst;
     297           0 :                 if (bus_space_subregion(isc->map->bst, isc->map->bsh, gtt_off,
     298           0 :                     (isc->isc_apsize >> AGP_PAGE_SHIFT) * 4, &isc->gtt_bsh)) {
     299           0 :                         printf("can't map gatt registers\n");
     300           0 :                         goto out;
     301             :                 }
     302             :         }
     303             : 
     304           0 :         gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT | M_ZERO);
     305           0 :         if (gatt == NULL) {
     306           0 :                 printf("can't alloc gatt\n");
     307           0 :                 goto out;
     308             :         }
     309           0 :         isc->gatt = gatt;
     310             : 
     311           0 :         gatt->ag_entries = isc->isc_apsize >> AGP_PAGE_SHIFT;
     312             : 
     313             :         /*
     314             :          * Find the GMCH, some of the registers we need to read for
     315             :          * configuration purposes are on there. it's always at
     316             :          * 0/0/0 (bus/dev/func).
     317             :          */
     318           0 :         if (pci_find_device(&bpa, intagp_gmch_match) == 0) {
     319           0 :                 printf("can't find GMCH\n");
     320           0 :                 goto out;
     321             :         }
     322             : 
     323           0 :         switch (isc->chiptype) {
     324             :         case CHIP_I810:
     325             :                 /* Some i810s have on-chip memory called dcache */
     326           0 :                 if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
     327           0 :                         isc->dcache_size = 4 * 1024 * 1024;
     328             :                 else
     329           0 :                         isc->dcache_size = 0;
     330             : 
     331             :                 /* According to the specs the gatt on the i810 must be 64k */
     332           0 :                 if (agp_alloc_dmamem(pa->pa_dmat, 64 * 1024, &gatt->ag_dmamap,
     333           0 :                     &gatt->ag_physical, &gatt->ag_dmaseg) != 0) {
     334             :                         goto out;
     335             :                 }
     336           0 :                 gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t);
     337             : 
     338           0 :                 if (bus_dmamem_map(pa->pa_dmat, &gatt->ag_dmaseg, 1, 64 * 1024,
     339           0 :                     (caddr_t *)&gatt->ag_virtual, BUS_DMA_NOWAIT) != 0)
     340             :                         goto out;
     341             :                 break;
     342             : 
     343             :         case CHIP_I830:
     344             :                 /* The i830 automatically initializes the 128k gatt on boot. */
     345             : 
     346           0 :                 reg = pci_conf_read(bpa.pa_pc, bpa.pa_tag, AGP_I830_GCC0);
     347           0 :                 gcc1 = (u_int16_t)(reg >> 16);
     348           0 :                 switch (gcc1 & AGP_I830_GCC1_GMS) {
     349             :                 case AGP_I830_GCC1_GMS_STOLEN_512:
     350           0 :                         isc->stolen = (512 - 132) * 1024 / 4096;
     351           0 :                         break;
     352             :                 case AGP_I830_GCC1_GMS_STOLEN_1024:
     353           0 :                         isc->stolen = (1024 - 132) * 1024 / 4096;
     354           0 :                         break;
     355             :                 case AGP_I830_GCC1_GMS_STOLEN_8192:
     356           0 :                         isc->stolen = (8192 - 132) * 1024 / 4096;
     357           0 :                         break;
     358             :                 default:
     359           0 :                         isc->stolen = 0;
     360           0 :                         printf("unknown memory configuration, disabling\n");
     361           0 :                         goto out;
     362             :                 }
     363             : #ifdef DEBUG
     364             :                 if (isc->stolen > 0) {
     365             :                         printf(": detected %dk stolen memory",
     366             :                             isc->stolen * 4);
     367             :                 } else
     368             :                         printf(": no preallocated video memory\n");
     369             : #endif
     370             : 
     371             :                 /* XXX */
     372           0 :                 isc->stolen = 0;
     373             : 
     374             :                 /* GATT address is already in there, make sure it's enabled */
     375           0 :                 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1;
     376           0 :                 break;
     377             : 
     378             :         case CHIP_I855:
     379             :                 /* FALLTHROUGH */
     380             :         case CHIP_I915:
     381             :                 /* FALLTHROUGH */
     382             :         case CHIP_I965: 
     383             :                 /* FALLTHROUGH */
     384             :         case CHIP_G33:
     385             :                 /* FALLTHROUGH */
     386             :         case CHIP_G4X:
     387             :         case CHIP_PINEVIEW:
     388             :         case CHIP_IRONLAKE:
     389             : 
     390             :                 /* Stolen memory is set up at the beginning of the aperture by
     391             :                  * the BIOS, consisting of the GATT followed by 4kb for the
     392             :                  * BIOS display.
     393             :                  */
     394             : 
     395           0 :                 reg = pci_conf_read(bpa.pa_pc, bpa.pa_tag, AGP_I855_GCC1);
     396           0 :                 gcc1 = (u_int16_t)(reg >> 16);
     397           0 :                 switch (isc->chiptype) {
     398             :                 case CHIP_I855:
     399             :                 /* The 855GM automatically initializes the 128k gatt on boot. */
     400             :                         stolen = 128 + 4;
     401           0 :                         break;
     402             :                 case CHIP_I915:
     403             :                 /* The 915G automatically initializes the 256k gatt on boot. */
     404             :                         stolen = 256 + 4;
     405           0 :                         break;
     406             :                 case CHIP_I965:
     407           0 :                         switch (READ4(AGP_I810_PGTBL_CTL) &
     408             :                             AGP_I810_PGTBL_SIZE_MASK) {
     409             :                         case AGP_I810_PGTBL_SIZE_512KB:
     410             :                                 stolen = 512 + 4;
     411           0 :                                 break;
     412             :                         case AGP_I810_PGTBL_SIZE_256KB:
     413             :                                 stolen = 256 + 4;
     414           0 :                                 break;
     415             :                         case AGP_I810_PGTBL_SIZE_128KB:
     416             :                         default:
     417             :                                 stolen = 128 + 4;
     418           0 :                                 break;
     419             :                         }
     420             :                         break;
     421             :                 case CHIP_G33:
     422           0 :                         switch (gcc1 & AGP_G33_PGTBL_SIZE_MASK) {
     423             :                         case AGP_G33_PGTBL_SIZE_2M:
     424             :                                 stolen = 2048 + 4;
     425           0 :                                 break;
     426             :                         case AGP_G33_PGTBL_SIZE_1M:
     427             :                         default:
     428             :                                 stolen = 1024 + 4;
     429           0 :                                 break;
     430             :                         }
     431             :                         break;
     432             :                 case CHIP_G4X:
     433             :                 case CHIP_PINEVIEW:
     434             :                 case CHIP_IRONLAKE:
     435             :                         /*
     436             :                          * GTT stolen is separate from graphics stolen on
     437             :                          * 4 series hardware. so ignore it in stolen gtt entries
     438             :                          * counting. However, 4Kb of stolen memory isn't mapped
     439             :                          * to the GTT.
     440             :                          */
     441             :                         stolen = 4;
     442           0 :                         break;
     443             :                 default:
     444           0 :                         printf("bad chiptype\n");
     445           0 :                         goto out;
     446             :                 }
     447             : 
     448           0 :                 switch (gcc1 & AGP_I855_GCC1_GMS) {
     449             :                 case AGP_I855_GCC1_GMS_STOLEN_1M:
     450           0 :                         isc->stolen = (1024 - stolen) * 1024 / 4096;
     451           0 :                         break;
     452             :                 case AGP_I855_GCC1_GMS_STOLEN_4M:
     453           0 :                         isc->stolen = (4096 - stolen) * 1024 / 4096;
     454           0 :                         break;
     455             :                 case AGP_I855_GCC1_GMS_STOLEN_8M:
     456           0 :                         isc->stolen = (8192 - stolen) * 1024 / 4096;
     457           0 :                         break;
     458             :                 case AGP_I855_GCC1_GMS_STOLEN_16M:
     459           0 :                         isc->stolen = (16384 - stolen) * 1024 / 4096;
     460           0 :                         break;
     461             :                 case AGP_I855_GCC1_GMS_STOLEN_32M:
     462           0 :                         isc->stolen = (32768 - stolen) * 1024 / 4096;
     463           0 :                         break;
     464             :                 case AGP_I915_GCC1_GMS_STOLEN_48M:
     465           0 :                         isc->stolen = (49152 - stolen) * 1024 / 4096;
     466           0 :                         break;
     467             :                 case AGP_I915_GCC1_GMS_STOLEN_64M:
     468           0 :                         isc->stolen = (65536 - stolen) * 1024 / 4096;
     469           0 :                         break;
     470             :                 case AGP_G33_GCC1_GMS_STOLEN_128M:
     471           0 :                         isc->stolen = (131072 - stolen) * 1024 / 4096;
     472           0 :                         break;
     473             :                 case AGP_G33_GCC1_GMS_STOLEN_256M:
     474           0 :                         isc->stolen = (262144 - stolen) * 1024 / 4096;
     475           0 :                         break;
     476             :                 case AGP_INTEL_GMCH_GMS_STOLEN_96M:
     477           0 :                         isc->stolen = (98304 - stolen) * 1024 / 4096;
     478           0 :                         break;
     479             :                 case AGP_INTEL_GMCH_GMS_STOLEN_160M:
     480           0 :                         isc->stolen = (163840 - stolen) * 1024 / 4096;
     481           0 :                         break;
     482             :                 case AGP_INTEL_GMCH_GMS_STOLEN_224M:
     483           0 :                         isc->stolen = (229376 - stolen) * 1024 / 4096;
     484           0 :                         break;
     485             :                 case AGP_INTEL_GMCH_GMS_STOLEN_352M:
     486           0 :                         isc->stolen = (360448 - stolen) * 1024 / 4096;
     487           0 :                         break;
     488             :                 default:
     489           0 :                         isc->stolen = 0;
     490           0 :                         printf("unknown memory configuration, disabling\n");
     491           0 :                         goto out;
     492             :                 }
     493             : #ifdef DEBUG
     494             :                 if (isc->stolen > 0) {
     495             :                         printf(": detected %dk stolen memory",
     496             :                             isc->stolen * 4);
     497             :                 } else
     498             :                         printf(": no preallocated video memory\n");
     499             : #endif
     500             : 
     501             :                 /* XXX */
     502           0 :                 isc->stolen = 0;
     503             : 
     504             :                 /* GATT address is already in there, make sure it's enabled */
     505           0 :                 gatt->ag_physical = READ4(AGP_I810_PGTBL_CTL) & ~1;
     506           0 :                 break;
     507             : 
     508             :         default:
     509           0 :                 printf(": unknown initialisation\n");
     510           0 :                 return;
     511             :         }
     512             :         /* Intel recommends that you have a fake page bound to the gtt always */
     513           0 :         if (agp_alloc_dmamem(pa->pa_dmat, AGP_PAGE_SIZE, &isc->scrib_dmamap,
     514           0 :             &tmp, &isc->scrib_seg) != 0) {
     515           0 :                 printf(": can't get scribble page\n");
     516           0 :                 return;
     517             :         }
     518           0 :         agp_i810_configure(isc);
     519             : 
     520           0 :         isc->agpdev = (struct agp_softc *)agp_attach_bus(pa, &agp_i810_methods,
     521           0 :             isc->isc_apaddr, isc->isc_apsize, &isc->dev);
     522           0 :         isc->agpdev->sc_stolen_entries = isc->stolen;
     523           0 :         return;
     524             : out:
     525             : 
     526           0 :         if (isc->gatt) {
     527           0 :                 if (isc->gatt->ag_size != 0)
     528           0 :                         agp_free_dmamem(pa->pa_dmat, isc->gatt->ag_size,
     529           0 :                             isc->gatt->ag_dmamap, &isc->gatt->ag_dmaseg);
     530           0 :                 free(isc->gatt, M_AGP, sizeof (*isc->gatt));
     531           0 :         }
     532           0 :         if (isc->gtt_size != 0)
     533           0 :                 bus_space_unmap(isc->gtt_bst, isc->gtt_bsh, isc->gtt_size);
     534           0 : }
     535             : 
     536             : int
     537           0 : agp_i810_activate(struct device *arg, int act)
     538             : {
     539           0 :         struct agp_i810_softc *isc = (struct agp_i810_softc *)arg;
     540             : 
     541             :         /*
     542             :          * Anything kept in agp over a suspend/resume cycle (and thus by X
     543             :          * over a vt switch cycle) is undefined upon resume.
     544             :          */
     545           0 :         switch (act) {
     546             :         case DVACT_RESUME:
     547           0 :                 agp_i810_configure(isc);
     548           0 :                 break;
     549             :         }
     550             : 
     551           0 :         return (0);
     552             : }
     553             : 
     554             : void
     555           0 : agp_i810_configure(struct agp_i810_softc *isc)
     556             : {
     557             :         bus_addr_t      tmp;
     558             : 
     559           0 :         tmp = isc->isc_apaddr;
     560           0 :         if (isc->chiptype == CHIP_I810) {
     561           0 :                 tmp += isc->dcache_size;
     562           0 :         } else {  
     563           0 :                 tmp += isc->stolen << AGP_PAGE_SHIFT;
     564             :         }
     565             : 
     566           0 :         agp_flush_cache();
     567             :         /* Install the GATT. */
     568           0 :         WRITE4(AGP_I810_PGTBL_CTL, isc->gatt->ag_physical | 1);
     569             : 
     570             :         /* initialise all gtt entries to point to scribble page */
     571           0 :         for (; tmp < (isc->isc_apaddr + isc->isc_apsize);
     572           0 :             tmp += AGP_PAGE_SIZE)
     573           0 :                 agp_i810_unbind_page(isc, tmp);
     574             :         /* XXX we'll need to restore the GTT contents when we go kms */
     575             : 
     576             :         /*
     577             :          * Make sure the chipset can see everything.
     578             :          */
     579           0 :         agp_flush_cache();
     580           0 : }
     581             : 
     582             : void
     583           0 : agp_i810_bind_page(void *sc, bus_addr_t offset, paddr_t physical, int flags)
     584             : {
     585           0 :         struct agp_i810_softc *isc = sc;
     586             : 
     587             :         /*
     588             :          * COHERENT mappings mean set the snoop bit. this should never be
     589             :          * accessed by the gpu through the gtt.
     590             :          */
     591           0 :         if (flags & BUS_DMA_COHERENT)
     592           0 :                 physical |= INTEL_COHERENT;
     593             : 
     594           0 :         intagp_write_gtt(isc, offset - isc->isc_apaddr, physical);
     595           0 : }
     596             : 
     597             : void
     598           0 : agp_i810_unbind_page(void *sc, bus_size_t offset)
     599             : {
     600           0 :         struct agp_i810_softc *isc = sc;
     601             : 
     602           0 :         intagp_write_gtt(isc, offset - isc->isc_apaddr,
     603           0 :             isc->scrib_dmamap->dm_segs[0].ds_addr);
     604           0 : }
     605             : 
     606             : /*
     607             :  * Writing via memory mapped registers already flushes all TLBs.
     608             :  */
     609             : void
     610           0 : agp_i810_flush_tlb(void *sc)
     611             : {
     612           0 : }
     613             : 
     614             : int
     615           0 : agp_i810_enable(void *sc, u_int32_t mode)
     616             : {
     617           0 :         return (0);
     618             : }
     619             : 
     620             : void
     621           0 : intagp_write_gtt(struct agp_i810_softc *isc, bus_size_t off, paddr_t v)
     622             : {
     623             :         u_int32_t       pte = 0;
     624             :         bus_size_t      wroff;
     625             : 
     626           0 :         if (isc->chiptype != CHIP_I810 &&
     627           0 :             (off >> AGP_PAGE_SHIFT) < isc->stolen) {
     628           0 :                 printf("intagp: binding into stolen memory! (0x%lx)\n",
     629             :                         (off >> AGP_PAGE_SHIFT));
     630           0 :         }
     631             : 
     632           0 :         if (v != 0) {
     633           0 :                 pte = v | INTEL_ENABLED;
     634             :                 /* 965+ can do 36-bit addressing, add in the extra bits */
     635           0 :                 switch (isc->chiptype) {
     636             :                 case CHIP_I965:
     637             :                 case CHIP_G4X:
     638             :                 case CHIP_PINEVIEW:
     639             :                 case CHIP_G33:
     640             :                 case CHIP_IRONLAKE:
     641           0 :                         pte |= (v & 0x0000000f00000000ULL) >> 28;
     642           0 :                         break;
     643             :                 }
     644             :         }
     645             : 
     646           0 :         wroff = (off >> AGP_PAGE_SHIFT) * 4;
     647           0 :         bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, wroff, pte);
     648           0 : }

Generated by: LCOV version 1.13