^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Intel GTT (Graphics Translation Table) routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Caveat: This driver implements the linux agp interface, but this is far from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * a agp driver! GTT support ended up here for purely historical reasons: The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * old userspace intel graphics drivers needed an interface to map memory into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * the GTT. And the drm provides a default interface for graphic devices sitting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * on an agp port. So it made sense to fake the GTT support as an agp port to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * avoid having to create a new api.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * With gem this does not make much sense anymore, just needlessly complicates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * the code. But as long as the old graphics stack is still support, it's stuck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * /fairy-tale-mode off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/agp_backend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "agp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "intel-agp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <drm/intel-gtt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/set_memory.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * If we have Intel graphics, we're not going to have anything other than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * an Intel IOMMU. So make the correct use of the PCI DMA API contingent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * on the Intel IOMMU support (CONFIG_INTEL_IOMMU).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Only newer chipsets need to bother with this, of course.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #ifdef CONFIG_INTEL_IOMMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define USE_PCI_DMA_API 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define USE_PCI_DMA_API 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct intel_gtt_driver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int gen : 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned int is_g33 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int is_pineview : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned int is_ironlake : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned int has_pgtbl_enable : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned int dma_mask_size : 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* Chipset specific GTT setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int (*setup)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* This should undo anything done in ->setup() save the unmapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * of the mmio register file, that's done in the generic code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void (*cleanup)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) void (*write_entry)(dma_addr_t addr, unsigned int entry, unsigned int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Flags is a more or less chipset specific opaque value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * For chipsets that need to support old ums (non-gem) code, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * needs to be identical to the various supported agp memory types! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) bool (*check_flags)(unsigned int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) void (*chipset_flush)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static struct _intel_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) const struct intel_gtt_driver *driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct pci_dev *pcidev; /* device one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct pci_dev *bridge_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u8 __iomem *registers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) phys_addr_t gtt_phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u32 PGETBL_save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u32 __iomem *gtt; /* I915G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bool clear_fake_agp; /* on first access via agp, fill with scratch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int num_dcache_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void __iomem *i9xx_flush_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) char *i81x_gtt_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct resource ifp_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int resource_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct page *scratch_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) phys_addr_t scratch_page_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int refcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Whether i915 needs to use the dmar apis or not. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) unsigned int needs_dmar : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) phys_addr_t gma_bus_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Size of memory reserved for graphics by the BIOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) resource_size_t stolen_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Total number of gtt entries. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned int gtt_total_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Part of the gtt that is mappable by the cpu, for those chips where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * this is not the full gtt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int gtt_mappable_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) } intel_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define INTEL_GTT_GEN intel_private.driver->gen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define IS_G33 intel_private.driver->is_g33
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define IS_PINEVIEW intel_private.driver->is_pineview
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define IS_IRONLAKE intel_private.driver->is_ironlake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int intel_gtt_map_memory(struct page **pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned int num_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct sg_table *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) DBG("try mapping %lu pages\n", (unsigned long)num_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (sg_alloc_table(st, num_entries, GFP_KERNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) for_each_sg(st->sgl, sg, num_entries, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) sg_set_page(sg, pages[i], PAGE_SIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!pci_map_sg(intel_private.pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) st->sgl, st->nents, PCI_DMA_BIDIRECTIONAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) sg_free_table(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct sg_table st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) pci_unmap_sg(intel_private.pcidev, sg_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) num_sg, PCI_DMA_BIDIRECTIONAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) st.sgl = sg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) st.orig_nents = st.nents = num_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) sg_free_table(&st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Exists to support ARGB cursors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static struct page *i8xx_alloc_pages(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (page == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (set_pages_uc(page, 4) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) set_pages_wb(page, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) __free_pages(page, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) atomic_inc(&agp_bridge->current_memory_agp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static void i8xx_destroy_pages(struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (page == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) set_pages_wb(page, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) __free_pages(page, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) atomic_dec(&agp_bridge->current_memory_agp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define I810_GTT_ORDER 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int i810_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) phys_addr_t reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) char *gtt_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* i81x does not preallocate the gtt. It's always 64kb in size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) gtt_table = alloc_gatt_pages(I810_GTT_ORDER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (gtt_table == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) intel_private.i81x_gtt_table = gtt_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) reg_addr = pci_resource_start(intel_private.pcidev, I810_MMADR_BAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) intel_private.registers = ioremap(reg_addr, KB(64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!intel_private.registers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) writel(virt_to_phys(gtt_table) | I810_PGETBL_ENABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) intel_private.registers+I810_PGETBL_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) intel_private.gtt_phys_addr = reg_addr + I810_PTE_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if ((readl(intel_private.registers+I810_DRAM_CTL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dev_info(&intel_private.pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) "detected 4MB dedicated video ram\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) intel_private.num_dcache_entries = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static void i810_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) writel(0, intel_private.registers+I810_PGETBL_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) free_gatt_pages(intel_private.i81x_gtt_table, I810_GTT_ORDER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int i810_insert_dcache_entries(struct agp_memory *mem, off_t pg_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if ((pg_start + mem->page_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) > intel_private.num_dcache_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!mem->is_flushed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) global_cache_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) for (i = pg_start; i < (pg_start + mem->page_count); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dma_addr_t addr = i << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) intel_private.driver->write_entry(addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) i, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * The i810/i830 requires a physical address to program its mouse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * pointer into hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * However the Xserver still writes to it through the agp aperture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct agp_memory *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) switch (pg_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) case 1: page = agp_bridge->driver->agp_alloc_page(agp_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* kludge to get 4 physical pages for ARGB cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) page = i8xx_alloc_pages();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (page == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) new = agp_create_memory(pg_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (new == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) new->pages[0] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (pg_count == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* kludge to get 4 physical pages for ARGB cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) new->pages[1] = new->pages[0] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) new->pages[2] = new->pages[1] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) new->pages[3] = new->pages[2] + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) new->page_count = pg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) new->num_scratch_pages = pg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) new->type = AGP_PHYS_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) new->physical = page_to_phys(new->pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static void intel_i810_free_by_type(struct agp_memory *curr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) agp_free_key(curr->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (curr->type == AGP_PHYS_MEMORY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (curr->page_count == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) i8xx_destroy_pages(curr->pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) agp_bridge->driver->agp_destroy_page(curr->pages[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) AGP_PAGE_DESTROY_UNMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) agp_bridge->driver->agp_destroy_page(curr->pages[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) AGP_PAGE_DESTROY_FREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) agp_free_page_array(curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) kfree(curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int intel_gtt_setup_scratch_page(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) dma_addr_t dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (page == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) set_pages_uc(page, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (intel_private.needs_dmar) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) dma_addr = pci_map_page(intel_private.pcidev, page, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) __free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) intel_private.scratch_page_dma = dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) intel_private.scratch_page_dma = page_to_phys(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) intel_private.scratch_page = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static void i810_write_entry(dma_addr_t addr, unsigned int entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) u32 pte_flags = I810_PTE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) switch (flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) case AGP_DCACHE_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) pte_flags |= I810_PTE_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case AGP_USER_CACHED_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) pte_flags |= I830_PTE_SYSTEM_CACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static resource_size_t intel_gtt_stolen_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) u16 gmch_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) u8 rdct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int local = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static const int ddt[4] = { 0, 16, 32, 64 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) resource_size_t stolen_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (INTEL_GTT_GEN == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return 0; /* no stolen mem on i81x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pci_read_config_word(intel_private.bridge_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) I830_GMCH_CTRL, &gmch_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case I830_GMCH_GMS_STOLEN_512:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) stolen_size = KB(512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case I830_GMCH_GMS_STOLEN_1024:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) stolen_size = MB(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case I830_GMCH_GMS_STOLEN_8192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) stolen_size = MB(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case I830_GMCH_GMS_LOCAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) stolen_size = (I830_RDRAM_ND(rdct) + 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) MB(ddt[I830_RDRAM_DDT(rdct)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) local = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) stolen_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case I855_GMCH_GMS_STOLEN_1M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) stolen_size = MB(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) case I855_GMCH_GMS_STOLEN_4M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) stolen_size = MB(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case I855_GMCH_GMS_STOLEN_8M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) stolen_size = MB(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case I855_GMCH_GMS_STOLEN_16M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) stolen_size = MB(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case I855_GMCH_GMS_STOLEN_32M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) stolen_size = MB(32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) case I915_GMCH_GMS_STOLEN_48M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) stolen_size = MB(48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case I915_GMCH_GMS_STOLEN_64M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) stolen_size = MB(64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) case G33_GMCH_GMS_STOLEN_128M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) stolen_size = MB(128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) case G33_GMCH_GMS_STOLEN_256M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) stolen_size = MB(256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) case INTEL_GMCH_GMS_STOLEN_96M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) stolen_size = MB(96);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) case INTEL_GMCH_GMS_STOLEN_160M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) stolen_size = MB(160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) case INTEL_GMCH_GMS_STOLEN_224M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) stolen_size = MB(224);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case INTEL_GMCH_GMS_STOLEN_352M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) stolen_size = MB(352);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) stolen_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (stolen_size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_info(&intel_private.bridge_dev->dev, "detected %lluK %s memory\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) (u64)stolen_size / KB(1), local ? "local" : "stolen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) dev_info(&intel_private.bridge_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) "no pre-allocated video memory detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) stolen_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return stolen_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static void i965_adjust_pgetbl_size(unsigned int size_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) u32 pgetbl_ctl, pgetbl_ctl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* ensure that ppgtt is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) pgetbl_ctl2 = readl(intel_private.registers+I965_PGETBL_CTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) pgetbl_ctl2 &= ~I810_PGETBL_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) writel(pgetbl_ctl2, intel_private.registers+I965_PGETBL_CTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* write the new ggtt size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pgetbl_ctl &= ~I965_PGETBL_SIZE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pgetbl_ctl |= size_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) writel(pgetbl_ctl, intel_private.registers+I810_PGETBL_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static unsigned int i965_gtt_total_entries(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) u32 pgetbl_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) u16 gmch_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) pci_read_config_word(intel_private.bridge_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) I830_GMCH_CTRL, &gmch_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (INTEL_GTT_GEN == 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) switch (gmch_ctl & G4x_GMCH_SIZE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case G4x_GMCH_SIZE_1M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case G4x_GMCH_SIZE_VT_1M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) i965_adjust_pgetbl_size(I965_PGETBL_SIZE_1MB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case G4x_GMCH_SIZE_VT_1_5M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) i965_adjust_pgetbl_size(I965_PGETBL_SIZE_1_5MB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) case G4x_GMCH_SIZE_2M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) case G4x_GMCH_SIZE_VT_2M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) i965_adjust_pgetbl_size(I965_PGETBL_SIZE_2MB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case I965_PGETBL_SIZE_128KB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) size = KB(128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case I965_PGETBL_SIZE_256KB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) size = KB(256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) case I965_PGETBL_SIZE_512KB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) size = KB(512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* GTT pagetable sizes bigger than 512KB are not possible on G33! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case I965_PGETBL_SIZE_1MB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) size = KB(1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) case I965_PGETBL_SIZE_2MB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) size = KB(2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case I965_PGETBL_SIZE_1_5MB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) size = KB(1024 + 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) dev_info(&intel_private.pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) "unknown page table size, assuming 512KB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) size = KB(512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return size/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static unsigned int intel_gtt_total_entries(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (IS_G33 || INTEL_GTT_GEN == 4 || INTEL_GTT_GEN == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return i965_gtt_total_entries();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* On previous hardware, the GTT size was just what was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * required to map the aperture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return intel_private.gtt_mappable_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static unsigned int intel_gtt_mappable_entries(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) unsigned int aperture_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (INTEL_GTT_GEN == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) u32 smram_miscc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) pci_read_config_dword(intel_private.bridge_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) I810_SMRAM_MISCC, &smram_miscc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if ((smram_miscc & I810_GFX_MEM_WIN_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) == I810_GFX_MEM_WIN_32M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) aperture_size = MB(32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) aperture_size = MB(64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) } else if (INTEL_GTT_GEN == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) u16 gmch_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) pci_read_config_word(intel_private.bridge_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) I830_GMCH_CTRL, &gmch_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_64M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) aperture_size = MB(64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) aperture_size = MB(128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* 9xx supports large sizes, just look at the length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) aperture_size = pci_resource_len(intel_private.pcidev, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return aperture_size >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static void intel_gtt_teardown_scratch_page(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) set_pages_wb(intel_private.scratch_page, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (intel_private.needs_dmar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) pci_unmap_page(intel_private.pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) intel_private.scratch_page_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) __free_page(intel_private.scratch_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static void intel_gtt_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) intel_private.driver->cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) iounmap(intel_private.gtt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) iounmap(intel_private.registers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) intel_gtt_teardown_scratch_page();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* Certain Gen5 chipsets require require idling the GPU before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * unmapping anything from the GTT when VT-d is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static inline int needs_ilk_vtd_wa(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #ifdef CONFIG_INTEL_IOMMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) const unsigned short gpu_devid = intel_private.pcidev->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* Query intel_iommu to see if we need the workaround. Presumably that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * was loaded first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) intel_iommu_gfx_mapped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static bool intel_gtt_can_wc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (INTEL_GTT_GEN <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (INTEL_GTT_GEN >= 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* Reports of major corruption with ILK vt'd enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (needs_ilk_vtd_wa())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) static int intel_gtt_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) u32 gtt_map_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) int ret, bar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ret = intel_private.driver->setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) intel_private.gtt_mappable_entries = intel_gtt_mappable_entries();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) intel_private.gtt_total_entries = intel_gtt_total_entries();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* save the PGETBL reg for resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) intel_private.PGETBL_save =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) readl(intel_private.registers+I810_PGETBL_CTL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) & ~I810_PGETBL_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /* we only ever restore the register when enabling the PGTBL... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (HAS_PGTBL_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) intel_private.PGETBL_save |= I810_PGETBL_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dev_info(&intel_private.bridge_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) "detected gtt size: %dK total, %dK mappable\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) intel_private.gtt_total_entries * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) intel_private.gtt_mappable_entries * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) gtt_map_size = intel_private.gtt_total_entries * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) intel_private.gtt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (intel_gtt_can_wc())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) intel_private.gtt = ioremap_wc(intel_private.gtt_phys_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) gtt_map_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (intel_private.gtt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) intel_private.gtt = ioremap(intel_private.gtt_phys_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) gtt_map_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (intel_private.gtt == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) intel_private.driver->cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) iounmap(intel_private.registers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) global_cache_flush(); /* FIXME: ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) intel_private.stolen_size = intel_gtt_stolen_size();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) intel_private.needs_dmar = USE_PCI_DMA_API && INTEL_GTT_GEN > 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) ret = intel_gtt_setup_scratch_page();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) intel_gtt_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (INTEL_GTT_GEN <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) bar = I810_GMADR_BAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) bar = I915_GMADR_BAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) intel_private.gma_bus_addr = pci_bus_address(intel_private.pcidev, bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static const struct aper_size_info_fixed intel_fake_agp_sizes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {32, 8192, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {64, 16384, 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {128, 32768, 5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {256, 65536, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {512, 131072, 7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static int intel_fake_agp_fetch_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) int num_sizes = ARRAY_SIZE(intel_fake_agp_sizes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) unsigned int aper_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) aper_size = (intel_private.gtt_mappable_entries << PAGE_SHIFT) / MB(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) for (i = 0; i < num_sizes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (aper_size == intel_fake_agp_sizes[i].size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) agp_bridge->current_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) (void *) (intel_fake_agp_sizes + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return aper_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static void i830_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /* The chipset_flush interface needs to get data that has already been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * flushed out of the CPU all the way out to main memory, because the GPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * doesn't snoop those buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * The 8xx series doesn't have the same lovely interface for flushing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * chipset write buffers that the later chips do. According to the 865
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * specs, it's 64 octwords, or 1KB. So, to get those previous things in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * that buffer out, we just fill 1KB and clflush it out, on the assumption
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * that it'll push whatever was in there out. It appears to work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static void i830_chipset_flush(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) unsigned long timeout = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* Forcibly evict everything from the CPU write buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * clflush appears to be insufficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) wbinvd_on_all_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Now we've only seen documents for this magic bit on 855GM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * we hope it exists for the other gen2 chipsets...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * Also works as advertised on my 845G.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) writel(readl(intel_private.registers+I830_HIC) | (1<<31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) intel_private.registers+I830_HIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) while (readl(intel_private.registers+I830_HIC) & (1<<31)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (time_after(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static void i830_write_entry(dma_addr_t addr, unsigned int entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) u32 pte_flags = I810_PTE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (flags == AGP_USER_CACHED_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) pte_flags |= I830_PTE_SYSTEM_CACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) bool intel_enable_gtt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) u8 __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (INTEL_GTT_GEN == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) u16 gmch_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) pci_read_config_word(intel_private.bridge_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) I830_GMCH_CTRL, &gmch_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) gmch_ctrl |= I830_GMCH_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) pci_write_config_word(intel_private.bridge_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) I830_GMCH_CTRL, gmch_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) pci_read_config_word(intel_private.bridge_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) I830_GMCH_CTRL, &gmch_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if ((gmch_ctrl & I830_GMCH_ENABLED) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) dev_err(&intel_private.pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) "failed to enable the GTT: GMCH_CTRL=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) gmch_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* On the resume path we may be adjusting the PGTBL value, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * be paranoid and flush all chipset write buffers...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (INTEL_GTT_GEN >= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) writel(0, intel_private.registers+GFX_FLSH_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) reg = intel_private.registers+I810_PGETBL_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) writel(intel_private.PGETBL_save, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (HAS_PGTBL_EN && (readl(reg) & I810_PGETBL_ENABLED) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dev_err(&intel_private.pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) "failed to enable the GTT: PGETBL=%x [expected %x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) readl(reg), intel_private.PGETBL_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (INTEL_GTT_GEN >= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) writel(0, intel_private.registers+GFX_FLSH_CNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) EXPORT_SYMBOL(intel_enable_gtt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static int i830_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) phys_addr_t reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) reg_addr = pci_resource_start(intel_private.pcidev, I810_MMADR_BAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) intel_private.registers = ioremap(reg_addr, KB(64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (!intel_private.registers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) intel_private.gtt_phys_addr = reg_addr + I810_PTE_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static int intel_fake_agp_create_gatt_table(struct agp_bridge_data *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) agp_bridge->gatt_table_real = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) agp_bridge->gatt_table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) agp_bridge->gatt_bus_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static int intel_fake_agp_configure(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (!intel_enable_gtt())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) intel_private.clear_fake_agp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) agp_bridge->gart_bus_addr = intel_private.gma_bus_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) static bool i830_check_flags(unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) switch (flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case AGP_PHYS_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) case AGP_USER_CACHED_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) case AGP_USER_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) void intel_gtt_insert_page(dma_addr_t addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) unsigned int pg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) intel_private.driver->write_entry(addr, pg, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) readl(intel_private.gtt + pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (intel_private.driver->chipset_flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) intel_private.driver->chipset_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) EXPORT_SYMBOL(intel_gtt_insert_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) void intel_gtt_insert_sg_entries(struct sg_table *st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) unsigned int pg_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) unsigned int len, m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) j = pg_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /* sg may merge pages, but we have to separate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * per-page addr for GTT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) for_each_sg(st->sgl, sg, st->nents, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) len = sg_dma_len(sg) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) for (m = 0; m < len; m++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) intel_private.driver->write_entry(addr, j, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) readl(intel_private.gtt + j - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (intel_private.driver->chipset_flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) intel_private.driver->chipset_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) EXPORT_SYMBOL(intel_gtt_insert_sg_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static void intel_gtt_insert_pages(unsigned int first_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) unsigned int num_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct page **pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) for (i = 0, j = first_entry; i < num_entries; i++, j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dma_addr_t addr = page_to_phys(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) intel_private.driver->write_entry(addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) j, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static int intel_fake_agp_insert_entries(struct agp_memory *mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) off_t pg_start, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (intel_private.clear_fake_agp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) int start = intel_private.stolen_size / PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int end = intel_private.gtt_mappable_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) intel_gtt_clear_range(start, end - start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) intel_private.clear_fake_agp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return i810_insert_dcache_entries(mem, pg_start, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (mem->page_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (pg_start + mem->page_count > intel_private.gtt_total_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (type != mem->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (!intel_private.driver->check_flags(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (!mem->is_flushed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) global_cache_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (intel_private.needs_dmar) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct sg_table st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ret = intel_gtt_map_memory(mem->pages, mem->page_count, &st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) intel_gtt_insert_sg_entries(&st, pg_start, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) mem->sg_list = st.sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) mem->num_sg = st.nents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) intel_gtt_insert_pages(pg_start, mem->page_count, mem->pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) mem->is_flushed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) for (i = first_entry; i < (first_entry + num_entries); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) intel_private.driver->write_entry(intel_private.scratch_page_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) EXPORT_SYMBOL(intel_gtt_clear_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) static int intel_fake_agp_remove_entries(struct agp_memory *mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) off_t pg_start, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (mem->page_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) intel_gtt_clear_range(pg_start, mem->page_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (intel_private.needs_dmar) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) intel_gtt_unmap_memory(mem->sg_list, mem->num_sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) mem->sg_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) mem->num_sg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct agp_memory *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (type == AGP_DCACHE_MEMORY && INTEL_GTT_GEN == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (pg_count != intel_private.num_dcache_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) new = agp_create_memory(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (new == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) new->type = AGP_DCACHE_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) new->page_count = pg_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) new->num_scratch_pages = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) agp_free_page_array(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (type == AGP_PHYS_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return alloc_agpphysmem_i8xx(pg_count, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) /* always return NULL for other allocation types for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static int intel_alloc_chipset_flush_resource(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ret = pci_bus_alloc_resource(intel_private.bridge_dev->bus, &intel_private.ifp_resource, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) PAGE_SIZE, PCIBIOS_MIN_MEM, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) pcibios_align_resource, intel_private.bridge_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static void intel_i915_setup_chipset_flush(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) u32 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) pci_read_config_dword(intel_private.bridge_dev, I915_IFPADDR, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (!(temp & 0x1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) intel_alloc_chipset_flush_resource();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) intel_private.resource_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) pci_write_config_dword(intel_private.bridge_dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) temp &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) intel_private.resource_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) intel_private.ifp_resource.start = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) intel_private.ifp_resource.end = temp + PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) ret = request_resource(&iomem_resource, &intel_private.ifp_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* some BIOSes reserve this area in a pnp some don't */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) intel_private.resource_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static void intel_i965_g33_setup_chipset_flush(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) u32 temp_hi, temp_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) pci_read_config_dword(intel_private.bridge_dev, I965_IFPADDR + 4, &temp_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) pci_read_config_dword(intel_private.bridge_dev, I965_IFPADDR, &temp_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (!(temp_lo & 0x1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) intel_alloc_chipset_flush_resource();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) intel_private.resource_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) pci_write_config_dword(intel_private.bridge_dev, I965_IFPADDR + 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) upper_32_bits(intel_private.ifp_resource.start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) pci_write_config_dword(intel_private.bridge_dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) u64 l64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) temp_lo &= ~0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) l64 = ((u64)temp_hi << 32) | temp_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) intel_private.resource_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) intel_private.ifp_resource.start = l64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) intel_private.ifp_resource.end = l64 + PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) ret = request_resource(&iomem_resource, &intel_private.ifp_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* some BIOSes reserve this area in a pnp some don't */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) intel_private.resource_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static void intel_i9xx_setup_flush(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* return if already configured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (intel_private.ifp_resource.start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (INTEL_GTT_GEN == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* setup a resource for this object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) intel_private.ifp_resource.name = "Intel Flush Page";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) intel_private.ifp_resource.flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* Setup chipset flush for 915 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (IS_G33 || INTEL_GTT_GEN >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) intel_i965_g33_setup_chipset_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) intel_i915_setup_chipset_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (intel_private.ifp_resource.start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) intel_private.i9xx_flush_page = ioremap(intel_private.ifp_resource.start, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (!intel_private.i9xx_flush_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) dev_err(&intel_private.pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) "can't ioremap flush page - no chipset flushing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static void i9xx_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (intel_private.i9xx_flush_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) iounmap(intel_private.i9xx_flush_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (intel_private.resource_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) release_resource(&intel_private.ifp_resource);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) intel_private.ifp_resource.start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) intel_private.resource_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static void i9xx_chipset_flush(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (intel_private.i9xx_flush_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) writel(1, intel_private.i9xx_flush_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static void i965_write_entry(dma_addr_t addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) unsigned int entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) u32 pte_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) pte_flags = I810_PTE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (flags == AGP_USER_CACHED_MEMORY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) pte_flags |= I830_PTE_SYSTEM_CACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) /* Shift high bits down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) addr |= (addr >> 28) & 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) writel_relaxed(addr | pte_flags, intel_private.gtt + entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static int i9xx_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) phys_addr_t reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) int size = KB(512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) reg_addr = pci_resource_start(intel_private.pcidev, I915_MMADR_BAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) intel_private.registers = ioremap(reg_addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (!intel_private.registers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) switch (INTEL_GTT_GEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) intel_private.gtt_phys_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) pci_resource_start(intel_private.pcidev, I915_PTE_BAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) intel_private.gtt_phys_addr = reg_addr + MB(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) intel_private.gtt_phys_addr = reg_addr + KB(512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) intel_i9xx_setup_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) static const struct agp_bridge_driver intel_fake_agp_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) .size_type = FIXED_APER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) .aperture_sizes = intel_fake_agp_sizes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) .configure = intel_fake_agp_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) .fetch_size = intel_fake_agp_fetch_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) .cleanup = intel_gtt_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) .agp_enable = intel_fake_agp_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) .cache_flush = global_cache_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) .create_gatt_table = intel_fake_agp_create_gatt_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) .free_gatt_table = intel_fake_agp_free_gatt_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) .insert_memory = intel_fake_agp_insert_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) .remove_memory = intel_fake_agp_remove_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) .alloc_by_type = intel_fake_agp_alloc_by_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) .free_by_type = intel_i810_free_by_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) .agp_alloc_page = agp_generic_alloc_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) .agp_alloc_pages = agp_generic_alloc_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) .agp_destroy_page = agp_generic_destroy_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) .agp_destroy_pages = agp_generic_destroy_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) static const struct intel_gtt_driver i81x_gtt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) .gen = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) .has_pgtbl_enable = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) .dma_mask_size = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) .setup = i810_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) .cleanup = i810_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) .check_flags = i830_check_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) .write_entry = i810_write_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static const struct intel_gtt_driver i8xx_gtt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) .gen = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) .has_pgtbl_enable = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) .setup = i830_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .cleanup = i830_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) .write_entry = i830_write_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) .dma_mask_size = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) .check_flags = i830_check_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) .chipset_flush = i830_chipset_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) static const struct intel_gtt_driver i915_gtt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) .gen = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) .has_pgtbl_enable = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) .setup = i9xx_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) .cleanup = i9xx_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) /* i945 is the last gpu to need phys mem (for overlay and cursors). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .write_entry = i830_write_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) .dma_mask_size = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .check_flags = i830_check_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) .chipset_flush = i9xx_chipset_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static const struct intel_gtt_driver g33_gtt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .gen = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .is_g33 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .setup = i9xx_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .cleanup = i9xx_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .write_entry = i965_write_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .dma_mask_size = 36,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .check_flags = i830_check_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) .chipset_flush = i9xx_chipset_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) static const struct intel_gtt_driver pineview_gtt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) .gen = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) .is_pineview = 1, .is_g33 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) .setup = i9xx_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) .cleanup = i9xx_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) .write_entry = i965_write_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) .dma_mask_size = 36,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) .check_flags = i830_check_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) .chipset_flush = i9xx_chipset_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) static const struct intel_gtt_driver i965_gtt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) .gen = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) .has_pgtbl_enable = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) .setup = i9xx_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) .cleanup = i9xx_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) .write_entry = i965_write_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) .dma_mask_size = 36,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .check_flags = i830_check_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .chipset_flush = i9xx_chipset_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) static const struct intel_gtt_driver g4x_gtt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .gen = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .setup = i9xx_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) .cleanup = i9xx_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) .write_entry = i965_write_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) .dma_mask_size = 36,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) .check_flags = i830_check_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .chipset_flush = i9xx_chipset_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) static const struct intel_gtt_driver ironlake_gtt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) .gen = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) .is_ironlake = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) .setup = i9xx_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) .cleanup = i9xx_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) .write_entry = i965_write_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) .dma_mask_size = 36,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) .check_flags = i830_check_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .chipset_flush = i9xx_chipset_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * driver and gmch_driver must be non-null, and find_gmch will determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * which one should be used if a gmch_chip_id is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) static const struct intel_gtt_driver_description {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) unsigned int gmch_chip_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) const struct intel_gtt_driver *gtt_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) } intel_gtt_chipsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) { PCI_DEVICE_ID_INTEL_82810_IG1, "i810",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) &i81x_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) { PCI_DEVICE_ID_INTEL_82810_IG3, "i810",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) &i81x_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) { PCI_DEVICE_ID_INTEL_82810E_IG, "i810",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) &i81x_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) { PCI_DEVICE_ID_INTEL_82815_CGC, "i815",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) &i81x_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) { PCI_DEVICE_ID_INTEL_82830_CGC, "830M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) &i8xx_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) { PCI_DEVICE_ID_INTEL_82845G_IG, "845G",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) &i8xx_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) { PCI_DEVICE_ID_INTEL_82854_IG, "854",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) &i8xx_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) { PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) &i8xx_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) { PCI_DEVICE_ID_INTEL_82865_IG, "865",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) &i8xx_gtt_driver},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) { PCI_DEVICE_ID_INTEL_E7221_IG, "E7221 (i915)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) &i915_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) { PCI_DEVICE_ID_INTEL_82915G_IG, "915G",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) &i915_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) { PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) &i915_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) { PCI_DEVICE_ID_INTEL_82945G_IG, "945G",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) &i915_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) { PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) &i915_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) { PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) &i915_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) { PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) &i965_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) { PCI_DEVICE_ID_INTEL_82G35_IG, "G35",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) &i965_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) { PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) &i965_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) { PCI_DEVICE_ID_INTEL_82965G_IG, "965G",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) &i965_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) { PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) &i965_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) { PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) &i965_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) { PCI_DEVICE_ID_INTEL_G33_IG, "G33",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) &g33_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) { PCI_DEVICE_ID_INTEL_Q35_IG, "Q35",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) &g33_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) { PCI_DEVICE_ID_INTEL_Q33_IG, "Q33",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) &g33_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) { PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, "GMA3150",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) &pineview_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) { PCI_DEVICE_ID_INTEL_PINEVIEW_IG, "GMA3150",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) &pineview_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) { PCI_DEVICE_ID_INTEL_GM45_IG, "GM45",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) &g4x_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) { PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, "Eaglelake",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) &g4x_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) { PCI_DEVICE_ID_INTEL_Q45_IG, "Q45/Q43",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) &g4x_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) { PCI_DEVICE_ID_INTEL_G45_IG, "G45/G43",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) &g4x_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) { PCI_DEVICE_ID_INTEL_B43_IG, "B43",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) &g4x_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) { PCI_DEVICE_ID_INTEL_B43_1_IG, "B43",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) &g4x_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) { PCI_DEVICE_ID_INTEL_G41_IG, "G41",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) &g4x_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) { PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) "HD Graphics", &ironlake_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) { PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) "HD Graphics", &ironlake_gtt_driver },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) { 0, NULL, NULL }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) static int find_gmch(u16 device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct pci_dev *gmch_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) device, gmch_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (!gmch_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) intel_private.pcidev = gmch_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct agp_bridge_data *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) int i, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (gpu_pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (gpu_pdev->device ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) intel_gtt_chipsets[i].gmch_chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) intel_private.pcidev = pci_dev_get(gpu_pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) intel_private.driver =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) intel_gtt_chipsets[i].gtt_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) } else if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) intel_private.driver =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) intel_gtt_chipsets[i].gtt_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (!intel_private.driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) #if IS_ENABLED(CONFIG_AGP_INTEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (INTEL_GTT_GEN > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) bridge->driver = &intel_fake_agp_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) bridge->dev_private_data = &intel_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) bridge->dev = bridge_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * Can be called from the fake agp driver but also directly from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * drm/i915.ko. Hence we need to check whether everything is set up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (intel_private.refcount++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) intel_private.bridge_dev = pci_dev_get(bridge_pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) dev_info(&bridge_pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if (bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) mask = intel_private.driver->dma_mask_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) dev_err(&intel_private.pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) "set gfx device dma mask %d-bit failed!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) pci_set_consistent_dma_mask(intel_private.pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) DMA_BIT_MASK(mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (intel_gtt_init() != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) intel_gmch_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) EXPORT_SYMBOL(intel_gmch_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) void intel_gtt_get(u64 *gtt_total,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) phys_addr_t *mappable_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) resource_size_t *mappable_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) *gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) *mappable_base = intel_private.gma_bus_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) *mappable_end = intel_private.gtt_mappable_entries << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) EXPORT_SYMBOL(intel_gtt_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) void intel_gtt_chipset_flush(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (intel_private.driver->chipset_flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) intel_private.driver->chipset_flush();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) EXPORT_SYMBOL(intel_gtt_chipset_flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) void intel_gmch_remove(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (--intel_private.refcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if (intel_private.scratch_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) intel_gtt_teardown_scratch_page();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (intel_private.pcidev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) pci_dev_put(intel_private.pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (intel_private.bridge_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) pci_dev_put(intel_private.bridge_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) intel_private.driver = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) EXPORT_SYMBOL(intel_gmch_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) MODULE_AUTHOR("Dave Jones, Various @Intel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) MODULE_LICENSE("GPL and additional rights");