A rewrite of the i810 bits of the agp(4) driver. New driver supports

operations required by GEMified i915.ko. It also attaches to SandyBridge
and IvyBridge CPU northbridges now.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
This commit is contained in:
Konstantin Belousov 2012-05-22 10:59:26 +00:00
parent 9280affe16
commit 28d86329af
9 changed files with 2285 additions and 650 deletions

View File

@ -239,7 +239,8 @@ agp_generic_attach(device_t dev)
if (memsize <= agp_max[i][0])
break;
}
if (i == agp_max_size) i = agp_max_size - 1;
if (i == agp_max_size)
i = agp_max_size - 1;
sc->as_maxmem = agp_max[i][1] << 20U;
/*
@ -802,6 +803,13 @@ agp_unbind_user(device_t dev, agp_unbind *unbind)
return AGP_UNBIND_MEMORY(dev, mem);
}
static int
agp_chipset_flush(device_t dev)
{
return (AGP_CHIPSET_FLUSH(dev));
}
static int
agp_open(struct cdev *kdev, int oflags, int devtype, struct thread *td)
{
@ -869,6 +877,8 @@ agp_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int fflag, struct thread
case AGPIOC_UNBIND:
return agp_unbind_user(dev, (agp_unbind *)data);
case AGPIOC_CHIPSET_FLUSH:
return agp_chipset_flush(dev);
}
return EINVAL;

File diff suppressed because it is too large Load Diff

101
sys/dev/agp/agp_i810.h Normal file
View File

@ -0,0 +1,101 @@
/*-
* Copyright (c) 2011 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Konstantin Belousov under sponsorship from
* the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef AGP_AGP_I810_H
#define AGP_AGP_I810_H
#include <sys/param.h>
#include <sys/sglist.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
/* Special gtt memory types */
#define AGP_DCACHE_MEMORY 1
#define AGP_PHYS_MEMORY 2
/* New caching attributes for gen6/sandybridge */
#define AGP_USER_CACHED_MEMORY_LLC_MLC (AGP_USER_TYPES + 2)
#define AGP_USER_UNCACHED_MEMORY (AGP_USER_TYPES + 4)
/* flag for GFDT type */
#define AGP_USER_CACHED_MEMORY_GFDT (1 << 3)
struct intel_gtt {
/* Size of memory reserved for graphics by the BIOS */
u_int stolen_size;
/* Total number of gtt entries. */
u_int gtt_total_entries;
/*
* Part of the gtt that is mappable by the cpu, for those
* chips where this is not the full gtt.
*/
u_int gtt_mappable_entries;
/*
* Always false.
*/
u_int do_idle_maps;
/*
* Share the scratch page dma with ppgtts.
*/
vm_paddr_t scratch_page_dma;
};
struct intel_gtt agp_intel_gtt_get(device_t dev);
int agp_intel_gtt_chipset_flush(device_t dev);
void agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list);
void agp_intel_gtt_clear_range(device_t dev, u_int first_entry,
u_int num_entries);
int agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries,
struct sglist **sg_list);
void agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list,
u_int pg_start, u_int flags);
void agp_intel_gtt_insert_pages(device_t dev, u_int first_entry,
u_int num_entries, vm_page_t *pages, u_int flags);
struct intel_gtt intel_gtt_get(void);
int intel_gtt_chipset_flush(void);
void intel_gtt_unmap_memory(struct sglist *sg_list);
void intel_gtt_clear_range(u_int first_entry, u_int num_entries);
int intel_gtt_map_memory(vm_page_t *pages, u_int num_entries,
struct sglist **sg_list);
void intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int pg_start,
u_int flags);
void intel_gtt_insert_pages(u_int first_entry, u_int num_entries,
vm_page_t *pages, u_int flags);
vm_paddr_t intel_gtt_read_pte_paddr(u_int entry);
u_int32_t intel_gtt_read_pte(u_int entry);
device_t intel_gtt_get_bridge_device(void);
void intel_gtt_write(u_int entry, uint32_t val);
#endif

View File

@ -36,6 +36,14 @@
#
INTERFACE agp;
CODE {
static int
null_agp_chipset_flush(device_t dev)
{
return (ENXIO);
}
};
#
# Return the current aperture size.
#
@ -132,3 +140,7 @@ METHOD int unbind_memory {
device_t dev;
struct agp_memory *handle;
};
METHOD int chipset_flush {
device_t dev;
} DEFAULT null_agp_chipset_flush;

View File

@ -73,7 +73,7 @@ struct agp_softc {
struct agp_memory_list as_memory; /* list of allocated memory */
int as_nextid; /* next memory block id */
int as_isopen; /* user device is open */
struct cdev *as_devnode; /* from make_dev */
struct cdev *as_devnode; /* from make_dev */
struct mtx as_lock; /* lock for access to GATT */
};

View File

@ -176,10 +176,33 @@
#define AGP_I810_GMADR 0x10
#define AGP_I810_MMADR 0x14
#define I810_PTE_VALID 0x00000001
/*
* Cache control
*
* Pre-Sandybridge bits
*/
#define I810_PTE_MAIN_UNCACHED 0x00000000
#define I810_PTE_LOCAL 0x00000002 /* Non-snooped main phys memory */
#define I830_PTE_SYSTEM_CACHED 0x00000006 /* Snooped main phys memory */
/*
* Sandybridge
* LLC - Last Level Cache
* MMC - Mid Level Cache
*/
#define GEN6_PTE_RESERVED 0x00000000
#define GEN6_PTE_UNCACHED 0x00000002 /* Do not cache */
#define GEN6_PTE_LLC 0x00000004 /* Cache in LLC */
#define GEN6_PTE_LLC_MLC 0x00000006 /* Cache in LLC and MLC */
#define GEN6_PTE_GFDT 0x00000008 /* Graphics Data Type */
/*
* Memory mapped register offsets for i810 chipset.
*/
#define AGP_I810_PGTBL_CTL 0x2020
#define AGP_I810_PGTBL_ENABLED 0x00000001
/**
* This field determines the actual size of the global GTT on the 965
* and G33
@ -187,7 +210,23 @@
#define AGP_I810_PGTBL_SIZE_MASK 0x0000000e
#define AGP_I810_PGTBL_SIZE_512KB (0 << 1)
#define AGP_I810_PGTBL_SIZE_256KB (1 << 1)
#define AGP_I810_PGTBL_SIZE_128KB (2 << 1)
#define AGP_I810_PGTBL_SIZE_128KB (2 << 1)
#define AGP_I810_PGTBL_SIZE_1MB (3 << 1)
#define AGP_I810_PGTBL_SIZE_2MB (4 << 1)
#define AGP_I810_PGTBL_SIZE_1_5MB (5 << 1)
#define AGP_G33_GCC1_SIZE_MASK (3 << 8)
#define AGP_G33_GCC1_SIZE_1M (1 << 8)
#define AGP_G33_GCC1_SIZE_2M (2 << 8)
#define AGP_G4x_GCC1_SIZE_MASK (0xf << 8)
#define AGP_G4x_GCC1_SIZE_1M (0x1 << 8)
#define AGP_G4x_GCC1_SIZE_2M (0x3 << 8)
#define AGP_G4x_GCC1_SIZE_VT_EN (0x8 << 8)
#define AGP_G4x_GCC1_SIZE_VT_1M \
(AGP_G4x_GCC1_SIZE_1M | AGP_G4x_GCC1_SIZE_VT_EN)
#define AGP_G4x_GCC1_SIZE_VT_1_5M ((0x2 << 8) | AGP_G4x_GCC1_SIZE_VT_EN)
#define AGP_G4x_GCC1_SIZE_VT_2M \
(AGP_G4x_GCC1_SIZE_2M | AGP_G4x_GCC1_SIZE_VT_EN)
#define AGP_I810_DRT 0x3000
#define AGP_I810_DRT_UNPOPULATED 0x00
#define AGP_I810_DRT_POPULATED 0x01
@ -207,6 +246,7 @@
#define AGP_I830_GCC1_GMASIZE 0x01
#define AGP_I830_GCC1_GMASIZE_64 0x01
#define AGP_I830_GCC1_GMASIZE_128 0x00
#define AGP_I830_HIC 0x70
/*
* Config registers for 852GM/855GM/865G device 0
@ -243,6 +283,9 @@
#define AGP_I915_GCC1_GMS_STOLEN_48M 0x60
#define AGP_I915_GCC1_GMS_STOLEN_64M 0x70
#define AGP_I915_DEVEN 0x54
#define AGP_SB_DEVEN_D2EN 0x10 /* SB+ has IGD enabled bit */
#define AGP_SB_DEVEN_D2EN_ENABLED 0x10 /* in different place */
#define AGP_SB_DEVEN_D2EN_DISABLED 0x00
#define AGP_I915_DEVEN_D2F0 0x08
#define AGP_I915_DEVEN_D2F0_ENABLED 0x08
#define AGP_I915_DEVEN_D2F0_DISABLED 0x00
@ -250,6 +293,7 @@
#define AGP_I915_MSAC_GMASIZE 0x02
#define AGP_I915_MSAC_GMASIZE_128 0x02
#define AGP_I915_MSAC_GMASIZE_256 0x00
#define AGP_I915_IFPADDR 0x60
/*
* G965 registers
@ -262,6 +306,8 @@
#define AGP_I965_PGTBL_SIZE_1MB (3 << 1)
#define AGP_I965_PGTBL_SIZE_2MB (4 << 1)
#define AGP_I965_PGTBL_SIZE_1_5MB (5 << 1)
#define AGP_I965_PGTBL_CTL2 0x20c4
#define AGP_I965_IFPADDR 0x70
/*
* G33 registers
@ -275,11 +321,42 @@
/*
* G4X registers
*/
#define AGP_G4X_GMADR 0x20
#define AGP_G4X_MMADR 0x10
#define AGP_G4X_GTTADR 0x18
#define AGP_G4X_GCC1_GMS_STOLEN_96M 0xa0
#define AGP_G4X_GCC1_GMS_STOLEN_160M 0xb0
#define AGP_G4X_GCC1_GMS_STOLEN_224M 0xc0
#define AGP_G4X_GCC1_GMS_STOLEN_352M 0xd0
/*
* SandyBridge/IvyBridge registers
*/
#define AGP_SNB_GCC1 0x50
#define AGP_SNB_GMCH_GMS_STOLEN_MASK 0xF8
#define AGP_SNB_GMCH_GMS_STOLEN_32M (1 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_64M (2 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_96M (3 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_128M (4 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_160M (5 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_192M (6 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_224M (7 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_256M (8 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_288M (9 << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_320M (0xa << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_352M (0xb << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_384M (0xc << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_416M (0xd << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_448M (0xe << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_480M (0xf << 3)
#define AGP_SNB_GMCH_GMS_STOLEN_512M (0x10 << 3)
#define AGP_SNB_GTT_SIZE_0M (0 << 8)
#define AGP_SNB_GTT_SIZE_1M (1 << 8)
#define AGP_SNB_GTT_SIZE_2M (2 << 8)
#define AGP_SNB_GTT_SIZE_MASK (3 << 8)
#define AGP_SNB_GFX_MODE 0x02520
/*
* NVIDIA nForce/nForce2 registers
*/

View File

@ -122,4 +122,10 @@ int agp_unbind_memory(device_t dev, void *handle);
*/
void agp_memory_info(device_t dev, void *handle, struct agp_memory_info *mi);
#define AGP_NORMAL_MEMORY 0
#define AGP_USER_TYPES (1 << 16)
#define AGP_USER_MEMORY (AGP_USER_TYPES)
#define AGP_USER_CACHED_MEMORY (AGP_USER_TYPES + 1)
#endif /* !_PCI_AGPVAR_H_ */

View File

@ -33,4 +33,16 @@ EXPORT_SYMS= agp_find_device \
agp_unbind_memory \
agp_memory_info
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
EXPORT_SYMS+= intel_gtt_clear_range \
intel_gtt_insert_pages \
intel_gtt_get \
intel_gtt_chipset_flush \
intel_gtt_unmap_memory \
intel_gtt_map_memory \
intel_gtt_insert_sg_entries \
intel_gtt_get_bridge_device
.endif
.include <bsd.kmod.mk>

View File

@ -88,6 +88,7 @@
#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
#define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, agp_bind)
#define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, agp_unbind)
#define AGPIOC_CHIPSET_FLUSH _IO (AGPIOC_BASE, 10)
typedef struct _agp_version {
u_int16_t major;