19,7 → 19,6 |
#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> |
33,7 → 32,9 |
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 |
50,7 → 51,27 |
#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 |
90,6 → 111,7 |
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 */ |
99,7 → 121,7 |
struct resource ifp_resource; |
int resource_valid; |
struct page *scratch_page; |
int refcount; |
dma_addr_t scratch_page_dma; |
} intel_private; |
|
#define INTEL_GTT_GEN intel_private.driver->gen |
110,13 → 132,13 |
|
static int intel_gtt_setup_scratch_page(void) |
{ |
dma_addr_t dma_addr; |
addr_t page; |
|
dma_addr = AllocPage(); |
if (dma_addr == 0) |
page = AllocPage(); |
if (page == 0) |
return -ENOMEM; |
|
intel_private.base.scratch_page_dma = dma_addr; |
intel_private.scratch_page_dma = page; |
intel_private.scratch_page = NULL; |
|
return 0; |
419,8 → 441,8 |
{ |
intel_private.driver->cleanup(); |
|
iounmap(intel_private.gtt); |
iounmap(intel_private.registers); |
FreeKernelSpace(intel_private.gtt); |
FreeKernelSpace(intel_private.registers); |
|
intel_gtt_teardown_scratch_page(); |
} |
427,7 → 449,6 |
|
static int intel_gtt_init(void) |
{ |
u32 gma_addr; |
u32 gtt_map_size; |
int ret; |
|
459,19 → 480,13 |
|
gtt_map_size = intel_private.base.gtt_total_entries * 4; |
|
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.gtt = (u32*)MapIoMem(intel_private.gtt_bus_addr, |
gtt_map_size, PG_SW+PG_NOCACHE); |
if (!intel_private.gtt) { |
intel_private.driver->cleanup(); |
iounmap(intel_private.registers); |
FreeKernelSpace(intel_private.registers); |
return -ENOMEM; |
} |
intel_private.base.gtt = intel_private.gtt; |
|
asm volatile("wbinvd"); |
|
485,15 → 500,8 |
return ret; |
} |
|
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_enable_gtt(); |
|
intel_private.base.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); |
|
LEAVE(); |
|
return 0; |
510,10 → 518,20 |
writel(addr | pte_flags, intel_private.gtt + entry); |
} |
|
bool intel_enable_gtt(void) |
static 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; |
|
570,38 → 588,19 |
return false; |
} |
|
void intel_gtt_insert_sg_entries(struct pagelist *st, |
unsigned int pg_start, |
unsigned int flags) |
void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, |
struct page **pages, 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 = pages[i]; |
dma_addr_t addr = (dma_addr_t)(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) |
609,7 → 608,7 |
unsigned int i; |
|
for (i = first_entry; i < (first_entry + num_entries); i++) { |
intel_private.driver->write_entry(intel_private.base.scratch_page_dma, |
intel_private.driver->write_entry(intel_private.scratch_page_dma, |
i, 0); |
} |
readl(intel_private.gtt+i-1); |
680,30 → 679,6 |
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) |
{ |
728,28 → 703,6 |
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) |
{ |
} |
761,6 → 714,7 |
{ |
#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. |
776,16 → 730,13 |
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; |
|
if (INTEL_GTT_GEN >= 7) |
size = MB(2); |
intel_private.registers = (u8*)MapIoMem(reg_addr, 128 * 4096, PG_SW+PG_NOCACHE); |
|
intel_private.registers = ioremap(reg_addr, size); |
if (!intel_private.registers) |
return -ENOMEM; |
|
801,7 → 752,6 |
switch (INTEL_GTT_GEN) { |
case 5: |
case 6: |
case 7: |
gtt_offset = MB(2); |
break; |
case 4: |
889,23 → 839,6 |
.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 |
992,82 → 925,6 |
"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 } |
}; |
|
1088,7 → 945,7 |
return 1; |
} |
|
int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, |
int intel_gmch_probe(struct pci_dev *pdev, |
struct agp_bridge_data *bridge) |
{ |
int i, mask; |
1105,12 → 962,11 |
if (!intel_private.driver) |
return 0; |
|
if (bridge) { |
// bridge->driver = &intel_fake_agp_driver; |
bridge->dev_private_data = &intel_private; |
bridge->dev = bridge_pdev; |
} |
bridge->dev = pdev; |
|
intel_private.bridge_dev = bridge_pdev; |
intel_private.bridge_dev = pdev; |
|
dbgprintf("Intel %s Chipset\n", intel_gtt_chipsets[i].name); |
|
1122,11 → 978,11 |
// pci_set_consistent_dma_mask(intel_private.pcidev, |
// DMA_BIT_MASK(mask)); |
|
if (intel_gtt_init() != 0) { |
// intel_gmch_remove(); |
/*if (bridge->driver == &intel_810_driver) |
return 1;*/ |
|
if (intel_gtt_init() != 0) |
return 0; |
} |
|
return 1; |
} |
1146,7 → 1002,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; |
}; |