19,6 → 19,7 |
#include <errno-base.h> |
#include <linux/pci.h> |
#include <linux/kernel.h> |
#include <linux/export.h> |
//#include <linux/pagemap.h> |
//#include <linux/agp_backend.h> |
//#include <asm/smp.h> |
32,9 → 33,7 |
struct pci_dev * |
pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from); |
|
static bool intel_enable_gtt(void); |
|
|
#define PCI_VENDOR_ID_INTEL 0x8086 |
#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 |
#define PCI_DEVICE_ID_INTEL_82845G_HB 0x2560 |
51,27 → 50,7 |
#define AGP_USER_CACHED_MEMORY (AGP_USER_TYPES + 1) |
|
|
static inline int pci_read_config_word(struct pci_dev *dev, int where, |
u16 *val) |
{ |
*val = PciRead16(dev->busnr, dev->devfn, where); |
return 1; |
} |
|
static inline int pci_read_config_dword(struct pci_dev *dev, int where, |
u32 *val) |
{ |
*val = PciRead32(dev->busnr, dev->devfn, where); |
return 1; |
} |
|
static inline int pci_write_config_word(struct pci_dev *dev, int where, |
u16 val) |
{ |
PciWrite16(dev->busnr, dev->devfn, where, val); |
return 1; |
} |
|
/* |
* If we have Intel graphics, we're not going to have anything other than |
* an Intel IOMMU. So make the correct use of the PCI DMA API contingent |
111,7 → 90,6 |
struct pci_dev *bridge_dev; |
u8 __iomem *registers; |
phys_addr_t gtt_bus_addr; |
phys_addr_t gma_bus_addr; |
u32 PGETBL_save; |
u32 __iomem *gtt; /* I915G */ |
bool clear_fake_agp; /* on first access via agp, fill with scratch */ |
121,7 → 99,7 |
struct resource ifp_resource; |
int resource_valid; |
struct page *scratch_page; |
dma_addr_t scratch_page_dma; |
int refcount; |
} intel_private; |
|
#define INTEL_GTT_GEN intel_private.driver->gen |
132,13 → 110,13 |
|
static int intel_gtt_setup_scratch_page(void) |
{ |
addr_t page; |
dma_addr_t dma_addr; |
|
page = AllocPage(); |
if (page == 0) |
dma_addr = AllocPage(); |
if (dma_addr == 0) |
return -ENOMEM; |
|
intel_private.scratch_page_dma = page; |
intel_private.base.scratch_page_dma = dma_addr; |
intel_private.scratch_page = NULL; |
|
return 0; |
441,8 → 419,8 |
{ |
intel_private.driver->cleanup(); |
|
FreeKernelSpace(intel_private.gtt); |
FreeKernelSpace(intel_private.registers); |
iounmap(intel_private.gtt); |
iounmap(intel_private.registers); |
|
intel_gtt_teardown_scratch_page(); |
} |
449,6 → 427,7 |
|
static int intel_gtt_init(void) |
{ |
u32 gma_addr; |
u32 gtt_map_size; |
int ret; |
|
480,13 → 459,19 |
|
gtt_map_size = intel_private.base.gtt_total_entries * 4; |
|
intel_private.gtt = (u32*)MapIoMem(intel_private.gtt_bus_addr, |
gtt_map_size, PG_SW+PG_NOCACHE); |
if (!intel_private.gtt) { |
intel_private.gtt = NULL; |
// if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2) |
// intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr, |
// gtt_map_size); |
if (intel_private.gtt == NULL) |
intel_private.gtt = ioremap(intel_private.gtt_bus_addr, |
gtt_map_size); |
if (intel_private.gtt == NULL) { |
intel_private.driver->cleanup(); |
FreeKernelSpace(intel_private.registers); |
iounmap(intel_private.registers); |
return -ENOMEM; |
} |
intel_private.base.gtt = intel_private.gtt; |
|
asm volatile("wbinvd"); |
|
500,8 → 485,15 |
return ret; |
} |
|
intel_enable_gtt(); |
if (INTEL_GTT_GEN <= 2) |
pci_read_config_dword(intel_private.pcidev, I810_GMADDR, |
&gma_addr); |
else |
pci_read_config_dword(intel_private.pcidev, I915_GMADDR, |
&gma_addr); |
|
intel_private.base.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); |
|
LEAVE(); |
|
return 0; |
518,20 → 510,10 |
writel(addr | pte_flags, intel_private.gtt + entry); |
} |
|
static bool intel_enable_gtt(void) |
bool intel_enable_gtt(void) |
{ |
u32 gma_addr; |
u8 __iomem *reg; |
|
if (INTEL_GTT_GEN <= 2) |
pci_read_config_dword(intel_private.pcidev, I810_GMADDR, |
&gma_addr); |
else |
pci_read_config_dword(intel_private.pcidev, I915_GMADDR, |
&gma_addr); |
|
intel_private.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); |
|
if (INTEL_GTT_GEN >= 6) |
return true; |
|
588,19 → 570,38 |
return false; |
} |
|
void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, |
struct page **pages, unsigned int flags) |
void intel_gtt_insert_sg_entries(struct pagelist *st, |
unsigned int pg_start, |
unsigned int flags) |
{ |
int i, j; |
|
j = pg_start; |
|
for(i = 0; i < st->nents; i++) |
{ |
dma_addr_t addr = st->page[i]; |
intel_private.driver->write_entry(addr, j, flags); |
j++; |
}; |
|
readl(intel_private.gtt+j-1); |
} |
|
static void intel_gtt_insert_pages(unsigned int first_entry, |
unsigned int num_entries, |
dma_addr_t *pages, |
unsigned int flags) |
{ |
int i, j; |
|
for (i = 0, j = first_entry; i < num_entries; i++, j++) { |
dma_addr_t addr = (dma_addr_t)(pages[i]); |
dma_addr_t addr = pages[i]; |
intel_private.driver->write_entry(addr, |
j, flags); |
} |
readl(intel_private.gtt+j-1); |
} |
EXPORT_SYMBOL(intel_gtt_insert_pages); |
|
|
void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries) |
608,7 → 609,7 |
unsigned int i; |
|
for (i = first_entry; i < (first_entry + num_entries); i++) { |
intel_private.driver->write_entry(intel_private.scratch_page_dma, |
intel_private.driver->write_entry(intel_private.base.scratch_page_dma, |
i, 0); |
} |
readl(intel_private.gtt+i-1); |
679,6 → 680,30 |
return true; |
} |
|
static void haswell_write_entry(dma_addr_t addr, unsigned int entry, |
unsigned int flags) |
{ |
unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT; |
unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; |
u32 pte_flags; |
|
if (type_mask == AGP_USER_MEMORY) |
pte_flags = HSW_PTE_UNCACHED | I810_PTE_VALID; |
else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { |
pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; |
if (gfdt) |
pte_flags |= GEN6_PTE_GFDT; |
} else { /* set 'normal'/'cached' to LLC by default */ |
pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; |
if (gfdt) |
pte_flags |= GEN6_PTE_GFDT; |
} |
|
/* gen6 has bit11-4 for physical addr bit39-32 */ |
addr |= (addr >> 28) & 0xff0; |
writel(addr | pte_flags, intel_private.gtt + entry); |
} |
|
static void gen6_write_entry(dma_addr_t addr, unsigned int entry, |
unsigned int flags) |
{ |
703,6 → 728,28 |
writel(addr | pte_flags, intel_private.gtt + entry); |
} |
|
static void valleyview_write_entry(dma_addr_t addr, unsigned int entry, |
unsigned int flags) |
{ |
unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT; |
unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; |
u32 pte_flags; |
|
if (type_mask == AGP_USER_MEMORY) |
pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; |
else { |
pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; |
if (gfdt) |
pte_flags |= GEN6_PTE_GFDT; |
} |
|
/* gen6 has bit11-4 for physical addr bit39-32 */ |
addr |= (addr >> 28) & 0xff0; |
writel(addr | pte_flags, intel_private.gtt + entry); |
|
writel(1, intel_private.registers + GFX_FLSH_CNTL_VLV); |
} |
|
static void gen6_cleanup(void) |
{ |
} |
714,7 → 761,6 |
{ |
#ifdef CONFIG_INTEL_IOMMU |
const unsigned short gpu_devid = intel_private.pcidev->device; |
extern int intel_iommu_gfx_mapped; |
|
/* Query intel_iommu to see if we need the workaround. Presumably that |
* was loaded first. |
730,13 → 776,16 |
static int i9xx_setup(void) |
{ |
u32 reg_addr; |
int size = KB(512); |
|
pci_read_config_dword(intel_private.pcidev, I915_MMADDR, ®_addr); |
|
reg_addr &= 0xfff80000; |
|
intel_private.registers = (u8*)MapIoMem(reg_addr, 128 * 4096, PG_SW+PG_NOCACHE); |
if (INTEL_GTT_GEN >= 7) |
size = MB(2); |
|
intel_private.registers = ioremap(reg_addr, size); |
if (!intel_private.registers) |
return -ENOMEM; |
|
752,6 → 801,7 |
switch (INTEL_GTT_GEN) { |
case 5: |
case 6: |
case 7: |
gtt_offset = MB(2); |
break; |
case 4: |
839,6 → 889,23 |
.check_flags = gen6_check_flags, |
.chipset_flush = i9xx_chipset_flush, |
}; |
static const struct intel_gtt_driver haswell_gtt_driver = { |
.gen = 6, |
.setup = i9xx_setup, |
.cleanup = gen6_cleanup, |
.write_entry = haswell_write_entry, |
.dma_mask_size = 40, |
.check_flags = gen6_check_flags, |
.chipset_flush = i9xx_chipset_flush, |
}; |
static const struct intel_gtt_driver valleyview_gtt_driver = { |
.gen = 7, |
.setup = i9xx_setup, |
.cleanup = gen6_cleanup, |
.write_entry = valleyview_write_entry, |
.dma_mask_size = 40, |
.check_flags = gen6_check_flags, |
}; |
|
/* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of |
* driver and gmch_driver must be non-null, and find_gmch will determine |
925,6 → 992,82 |
"Ivybridge", &sandybridge_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG, |
"Ivybridge", &sandybridge_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG, |
"Ivybridge", &sandybridge_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG, |
"ValleyView", &valleyview_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG, |
"Haswell", &haswell_gtt_driver }, |
{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG, |
"Haswell", &haswell_gtt_driver }, |
{ 0, NULL, NULL } |
}; |
|
945,7 → 1088,7 |
return 1; |
} |
|
int intel_gmch_probe(struct pci_dev *pdev, |
int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, |
struct agp_bridge_data *bridge) |
{ |
int i, mask; |
962,11 → 1105,12 |
if (!intel_private.driver) |
return 0; |
|
// bridge->driver = &intel_fake_agp_driver; |
if (bridge) { |
bridge->dev_private_data = &intel_private; |
bridge->dev = pdev; |
bridge->dev = bridge_pdev; |
} |
|
intel_private.bridge_dev = pdev; |
intel_private.bridge_dev = bridge_pdev; |
|
dbgprintf("Intel %s Chipset\n", intel_gtt_chipsets[i].name); |
|
978,11 → 1122,11 |
// pci_set_consistent_dma_mask(intel_private.pcidev, |
// DMA_BIT_MASK(mask)); |
|
/*if (bridge->driver == &intel_810_driver) |
return 1;*/ |
if (intel_gtt_init() != 0) { |
// intel_gmch_remove(); |
|
if (intel_gtt_init() != 0) |
return 0; |
} |
|
return 1; |
} |
1002,7 → 1146,7 |
EXPORT_SYMBOL(intel_gtt_chipset_flush); |
|
|
phys_addr_t get_bus_addr(void) |
{ |
return intel_private.gma_bus_addr; |
}; |
//phys_addr_t get_bus_addr(void) |
//{ |
// return intel_private.gma_bus_addr; |
//}; |