Home | History | Annotate | Line # | Download | only in amdgpu
      1  1.12  riastrad /*	$NetBSD: amdgpu_gart.c,v 1.12 2024/07/01 13:27:55 riastradh Exp $	*/
      2   1.1  riastrad 
      3   1.1  riastrad /*
      4   1.1  riastrad  * Copyright 2008 Advanced Micro Devices, Inc.
      5   1.1  riastrad  * Copyright 2008 Red Hat Inc.
      6   1.1  riastrad  * Copyright 2009 Jerome Glisse.
      7   1.1  riastrad  *
      8   1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      9   1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
     10   1.1  riastrad  * to deal in the Software without restriction, including without limitation
     11   1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     12   1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     13   1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     14   1.1  riastrad  *
     15   1.1  riastrad  * The above copyright notice and this permission notice shall be included in
     16   1.1  riastrad  * all copies or substantial portions of the Software.
     17   1.1  riastrad  *
     18   1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19   1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20   1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     21   1.1  riastrad  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     22   1.1  riastrad  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     23   1.1  riastrad  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     24   1.1  riastrad  * OTHER DEALINGS IN THE SOFTWARE.
     25   1.1  riastrad  *
     26   1.1  riastrad  * Authors: Dave Airlie
     27   1.1  riastrad  *          Alex Deucher
     28   1.1  riastrad  *          Jerome Glisse
     29   1.1  riastrad  */
     30   1.5  riastrad 
     31   1.1  riastrad #include <sys/cdefs.h>
     32  1.12  riastrad __KERNEL_RCSID(0, "$NetBSD: amdgpu_gart.c,v 1.12 2024/07/01 13:27:55 riastradh Exp $");
     33   1.5  riastrad 
     34   1.5  riastrad #include <linux/pci.h>
     35   1.5  riastrad #include <linux/vmalloc.h>
     36   1.1  riastrad 
     37   1.1  riastrad #include <drm/amdgpu_drm.h>
     38   1.5  riastrad #ifdef CONFIG_X86
     39   1.5  riastrad #include <asm/set_memory.h>
     40   1.5  riastrad #endif
     41   1.1  riastrad #include "amdgpu.h"
     42   1.1  riastrad 
     43   1.1  riastrad /*
     44   1.1  riastrad  * GART
     45   1.1  riastrad  * The GART (Graphics Aperture Remapping Table) is an aperture
     46   1.1  riastrad  * in the GPU's address space.  System pages can be mapped into
     47   1.1  riastrad  * the aperture and look like contiguous pages from the GPU's
     48   1.1  riastrad  * perspective.  A page table maps the pages in the aperture
     49   1.1  riastrad  * to the actual backing pages in system memory.
     50   1.1  riastrad  *
     51   1.1  riastrad  * Radeon GPUs support both an internal GART, as described above,
     52   1.1  riastrad  * and AGP.  AGP works similarly, but the GART table is configured
     53   1.1  riastrad  * and maintained by the northbridge rather than the driver.
     54   1.1  riastrad  * Radeon hw has a separate AGP aperture that is programmed to
     55   1.1  riastrad  * point to the AGP aperture provided by the northbridge and the
     56   1.1  riastrad  * requests are passed through to the northbridge aperture.
     57   1.1  riastrad  * Both AGP and internal GART can be used at the same time, however
     58   1.1  riastrad  * that is not currently supported by the driver.
     59   1.1  riastrad  *
     60   1.1  riastrad  * This file handles the common internal GART management.
     61   1.1  riastrad  */
     62   1.1  riastrad 
     63   1.1  riastrad /*
     64   1.1  riastrad  * Common GART table functions.
     65   1.1  riastrad  */
     66   1.5  riastrad 
     67   1.1  riastrad /**
     68   1.5  riastrad  * amdgpu_dummy_page_init - init dummy page used by the driver
     69   1.1  riastrad  *
     70   1.1  riastrad  * @adev: amdgpu_device pointer
     71   1.1  riastrad  *
     72   1.5  riastrad  * Allocate the dummy page used by the driver (all asics).
     73   1.5  riastrad  * This dummy page is used by the driver as a filler for gart entries
     74   1.5  riastrad  * when pages are taken out of the GART
     75   1.5  riastrad  * Returns 0 on sucess, -ENOMEM on failure.
     76   1.1  riastrad  */
     77   1.5  riastrad static int amdgpu_gart_dummy_page_init(struct amdgpu_device *adev)
     78   1.1  riastrad {
     79   1.3  riastrad #ifdef __NetBSD__
     80   1.3  riastrad 	int rsegs;
     81   1.9  riastrad 	void *p;
     82   1.3  riastrad 	int error;
     83   1.3  riastrad 
     84   1.5  riastrad 	/* XXX Can this be called more than once??  */
     85   1.5  riastrad 	if (adev->dummy_page_map != NULL)
     86   1.5  riastrad 		return 0;
     87   1.5  riastrad 
     88   1.5  riastrad 	error = bus_dmamem_alloc(adev->ddev->dmat, PAGE_SIZE, PAGE_SIZE, 0,
     89   1.5  riastrad 	    &adev->dummy_page_seg, 1, &rsegs, BUS_DMA_WAITOK);
     90   1.3  riastrad 	if (error)
     91   1.3  riastrad 		goto fail0;
     92   1.3  riastrad 	KASSERT(rsegs == 1);
     93   1.9  riastrad 	error = bus_dmamem_map(adev->ddev->dmat, &adev->dummy_page_seg, 1,
     94   1.9  riastrad 	    PAGE_SIZE, &p, BUS_DMA_WAITOK);
     95   1.9  riastrad 	if (error)
     96   1.9  riastrad 		goto fail1;
     97   1.9  riastrad 	memset(p, 0, PAGE_SIZE);
     98   1.9  riastrad 	bus_dmamem_unmap(adev->ddev->dmat, p, PAGE_SIZE);
     99   1.5  riastrad 	error = bus_dmamap_create(adev->ddev->dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
    100   1.5  riastrad 	    BUS_DMA_WAITOK, &adev->dummy_page_map);
    101   1.3  riastrad 	if (error)
    102   1.3  riastrad 		goto fail1;
    103   1.5  riastrad 	error = bus_dmamap_load_raw(adev->ddev->dmat, adev->dummy_page_map,
    104   1.5  riastrad 	    &adev->dummy_page_seg, 1, PAGE_SIZE, BUS_DMA_WAITOK);
    105   1.3  riastrad 	if (error)
    106   1.3  riastrad 		goto fail2;
    107   1.3  riastrad 
    108  1.10  riastrad 	bus_dmamap_sync(adev->ddev->dmat, adev->dummy_page_map, 0, PAGE_SIZE,
    109  1.10  riastrad 	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    110  1.10  riastrad 
    111   1.3  riastrad 	/* Success!  */
    112   1.5  riastrad 	adev->dummy_page_addr = adev->dummy_page_map->dm_segs[0].ds_addr;
    113   1.3  riastrad 	return 0;
    114   1.3  riastrad 
    115   1.5  riastrad fail3: __unused
    116   1.5  riastrad 	bus_dmamap_unload(adev->ddev->dmat, adev->dummy_page_map);
    117   1.5  riastrad fail2:	bus_dmamap_destroy(adev->ddev->dmat, adev->dummy_page_map);
    118   1.5  riastrad fail1:	bus_dmamem_free(adev->ddev->dmat, &adev->dummy_page_seg, 1);
    119   1.3  riastrad fail0:	KASSERT(error);
    120   1.5  riastrad 	adev->dummy_page_map = NULL;
    121   1.5  riastrad 	adev->dummy_page_addr = 0; /* paranoia */
    122   1.3  riastrad 	/* XXX errno NetBSD->Linux */
    123   1.3  riastrad 	return -error;
    124   1.3  riastrad #else  /* __NetBSD__ */
    125   1.5  riastrad 	struct page *dummy_page = ttm_bo_glob.dummy_read_page;
    126   1.1  riastrad 
    127   1.5  riastrad 	if (adev->dummy_page_addr)
    128   1.5  riastrad 		return 0;
    129   1.5  riastrad 	adev->dummy_page_addr = pci_map_page(adev->pdev, dummy_page, 0,
    130   1.5  riastrad 					     PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
    131   1.5  riastrad 	if (pci_dma_mapping_error(adev->pdev, adev->dummy_page_addr)) {
    132   1.5  riastrad 		dev_err(&adev->pdev->dev, "Failed to DMA MAP the dummy page\n");
    133   1.5  riastrad 		adev->dummy_page_addr = 0;
    134   1.1  riastrad 		return -ENOMEM;
    135   1.1  riastrad 	}
    136   1.1  riastrad 	return 0;
    137   1.3  riastrad #endif	/* __NetBSD__ */
    138   1.1  riastrad }
    139   1.1  riastrad 
    140   1.1  riastrad /**
    141   1.5  riastrad  * amdgpu_dummy_page_fini - free dummy page used by the driver
    142   1.1  riastrad  *
    143   1.1  riastrad  * @adev: amdgpu_device pointer
    144   1.1  riastrad  *
    145   1.5  riastrad  * Frees the dummy page used by the driver (all asics).
    146   1.1  riastrad  */
    147   1.5  riastrad static void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev)
    148   1.1  riastrad {
    149   1.5  riastrad 	if (!adev->dummy_page_addr)
    150   1.1  riastrad 		return;
    151   1.3  riastrad #ifdef __NetBSD__
    152   1.5  riastrad 	bus_dmamap_unload(adev->ddev->dmat, adev->dummy_page_map);
    153   1.5  riastrad 	bus_dmamap_destroy(adev->ddev->dmat, adev->dummy_page_map);
    154   1.5  riastrad 	bus_dmamem_free(adev->ddev->dmat, &adev->dummy_page_seg, 1);
    155   1.5  riastrad 	adev->dummy_page_map = NULL;
    156   1.3  riastrad #else
    157   1.5  riastrad 	pci_unmap_page(adev->pdev, adev->dummy_page_addr,
    158   1.5  riastrad 		       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
    159   1.3  riastrad #endif
    160   1.5  riastrad 	adev->dummy_page_addr = 0;
    161   1.1  riastrad }
    162   1.1  riastrad 
    163   1.1  riastrad /**
    164   1.1  riastrad  * amdgpu_gart_table_vram_alloc - allocate vram for gart page table
    165   1.1  riastrad  *
    166   1.1  riastrad  * @adev: amdgpu_device pointer
    167   1.1  riastrad  *
    168   1.1  riastrad  * Allocate video memory for GART page table
    169   1.1  riastrad  * (pcie r4xx, r5xx+).  These asics require the
    170   1.1  riastrad  * gart table to be in video memory.
    171   1.1  riastrad  * Returns 0 for success, error for failure.
    172   1.1  riastrad  */
    173   1.1  riastrad int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
    174   1.1  riastrad {
    175   1.1  riastrad 	int r;
    176   1.1  riastrad 
    177   1.5  riastrad 	if (adev->gart.bo == NULL) {
    178   1.5  riastrad 		struct amdgpu_bo_param bp;
    179   1.5  riastrad 
    180   1.5  riastrad 		memset(&bp, 0, sizeof(bp));
    181   1.5  riastrad 		bp.size = adev->gart.table_size;
    182   1.5  riastrad 		bp.byte_align = PAGE_SIZE;
    183   1.5  riastrad 		bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
    184   1.5  riastrad 		bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
    185   1.5  riastrad 			AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
    186   1.5  riastrad 		bp.type = ttm_bo_type_kernel;
    187   1.5  riastrad 		bp.resv = NULL;
    188   1.5  riastrad 		r = amdgpu_bo_create(adev, &bp, &adev->gart.bo);
    189   1.1  riastrad 		if (r) {
    190   1.1  riastrad 			return r;
    191   1.1  riastrad 		}
    192   1.1  riastrad 	}
    193   1.1  riastrad 	return 0;
    194   1.1  riastrad }
    195   1.1  riastrad 
    196   1.1  riastrad /**
    197   1.1  riastrad  * amdgpu_gart_table_vram_pin - pin gart page table in vram
    198   1.1  riastrad  *
    199   1.1  riastrad  * @adev: amdgpu_device pointer
    200   1.1  riastrad  *
    201   1.1  riastrad  * Pin the GART page table in vram so it will not be moved
    202   1.1  riastrad  * by the memory manager (pcie r4xx, r5xx+).  These asics require the
    203   1.1  riastrad  * gart table to be in video memory.
    204   1.1  riastrad  * Returns 0 for success, error for failure.
    205   1.1  riastrad  */
    206   1.1  riastrad int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev)
    207   1.1  riastrad {
    208   1.1  riastrad 	int r;
    209   1.1  riastrad 
    210   1.5  riastrad 	r = amdgpu_bo_reserve(adev->gart.bo, false);
    211   1.1  riastrad 	if (unlikely(r != 0))
    212   1.1  riastrad 		return r;
    213   1.5  riastrad 	r = amdgpu_bo_pin(adev->gart.bo, AMDGPU_GEM_DOMAIN_VRAM);
    214   1.1  riastrad 	if (r) {
    215   1.5  riastrad 		amdgpu_bo_unreserve(adev->gart.bo);
    216   1.1  riastrad 		return r;
    217   1.1  riastrad 	}
    218   1.5  riastrad 	r = amdgpu_bo_kmap(adev->gart.bo, &adev->gart.ptr);
    219   1.1  riastrad 	if (r)
    220   1.5  riastrad 		amdgpu_bo_unpin(adev->gart.bo);
    221   1.5  riastrad 	amdgpu_bo_unreserve(adev->gart.bo);
    222   1.1  riastrad 	return r;
    223   1.1  riastrad }
    224   1.1  riastrad 
    225   1.1  riastrad /**
    226   1.1  riastrad  * amdgpu_gart_table_vram_unpin - unpin gart page table in vram
    227   1.1  riastrad  *
    228   1.1  riastrad  * @adev: amdgpu_device pointer
    229   1.1  riastrad  *
    230   1.1  riastrad  * Unpin the GART page table in vram (pcie r4xx, r5xx+).
    231   1.1  riastrad  * These asics require the gart table to be in video memory.
    232   1.1  riastrad  */
    233   1.1  riastrad void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev)
    234   1.1  riastrad {
    235   1.1  riastrad 	int r;
    236   1.1  riastrad 
    237   1.5  riastrad 	if (adev->gart.bo == NULL) {
    238   1.1  riastrad 		return;
    239   1.1  riastrad 	}
    240   1.5  riastrad 	r = amdgpu_bo_reserve(adev->gart.bo, true);
    241   1.1  riastrad 	if (likely(r == 0)) {
    242   1.5  riastrad 		amdgpu_bo_kunmap(adev->gart.bo);
    243   1.5  riastrad 		amdgpu_bo_unpin(adev->gart.bo);
    244   1.5  riastrad 		amdgpu_bo_unreserve(adev->gart.bo);
    245   1.1  riastrad 		adev->gart.ptr = NULL;
    246   1.1  riastrad 	}
    247   1.1  riastrad }
    248   1.1  riastrad 
    249   1.1  riastrad /**
    250   1.1  riastrad  * amdgpu_gart_table_vram_free - free gart page table vram
    251   1.1  riastrad  *
    252   1.1  riastrad  * @adev: amdgpu_device pointer
    253   1.1  riastrad  *
    254   1.1  riastrad  * Free the video memory used for the GART page table
    255   1.1  riastrad  * (pcie r4xx, r5xx+).  These asics require the gart table to
    256   1.1  riastrad  * be in video memory.
    257   1.1  riastrad  */
    258   1.1  riastrad void amdgpu_gart_table_vram_free(struct amdgpu_device *adev)
    259   1.1  riastrad {
    260   1.5  riastrad 	if (adev->gart.bo == NULL) {
    261   1.1  riastrad 		return;
    262   1.1  riastrad 	}
    263   1.5  riastrad 	amdgpu_bo_unref(&adev->gart.bo);
    264   1.1  riastrad }
    265   1.1  riastrad 
    266   1.3  riastrad #ifdef __NetBSD__
    267   1.3  riastrad static void
    268   1.3  riastrad amdgpu_gart_pre_update(struct amdgpu_device *adev, unsigned gpu_pgstart,
    269   1.3  riastrad     unsigned gpu_npages)
    270   1.3  riastrad {
    271   1.3  riastrad 
    272   1.3  riastrad 	if (adev->gart.ag_table_map != NULL) {
    273   1.3  riastrad 		const unsigned entsize =
    274   1.3  riastrad 		    adev->gart.table_size / adev->gart.num_gpu_pages;
    275   1.3  riastrad 
    276   1.3  riastrad 		bus_dmamap_sync(adev->ddev->dmat, adev->gart.ag_table_map,
    277   1.3  riastrad 		    gpu_pgstart*entsize, gpu_npages*entsize,
    278   1.3  riastrad 		    BUS_DMASYNC_POSTWRITE);
    279   1.3  riastrad 	}
    280   1.3  riastrad }
    281   1.3  riastrad 
    282   1.3  riastrad static void
    283   1.3  riastrad amdgpu_gart_post_update(struct amdgpu_device *adev, unsigned gpu_pgstart,
    284   1.3  riastrad     unsigned gpu_npages)
    285   1.3  riastrad {
    286   1.6  riastrad 	unsigned i;
    287   1.3  riastrad 
    288   1.3  riastrad 	if (adev->gart.ag_table_map != NULL) {
    289   1.3  riastrad 		const unsigned entsize =
    290   1.3  riastrad 		    adev->gart.table_size / adev->gart.num_gpu_pages;
    291   1.3  riastrad 
    292   1.3  riastrad 		bus_dmamap_sync(adev->ddev->dmat, adev->gart.ag_table_map,
    293   1.3  riastrad 		    gpu_pgstart*entsize, gpu_npages*entsize,
    294   1.3  riastrad 		    BUS_DMASYNC_PREWRITE);
    295   1.3  riastrad 	}
    296   1.6  riastrad 	mb();			/* XXX why is bus_dmamap_sync not enough? */
    297   1.6  riastrad 	amdgpu_asic_flush_hdp(adev, NULL);
    298   1.6  riastrad 	for (i = 0; i < adev->num_vmhubs; i++)
    299   1.6  riastrad 		amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
    300   1.3  riastrad }
    301   1.3  riastrad #endif
    302   1.3  riastrad 
    303   1.1  riastrad /*
    304   1.1  riastrad  * Common gart functions.
    305   1.1  riastrad  */
    306   1.3  riastrad #ifdef __NetBSD__
    307   1.7  riastrad int
    308   1.3  riastrad amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t gpu_start,
    309   1.3  riastrad     unsigned npages)
    310   1.3  riastrad {
    311   1.6  riastrad 	const unsigned gpu_per_cpu = AMDGPU_GPU_PAGES_IN_CPU_PAGE;
    312   1.3  riastrad 	const unsigned gpu_npages = (npages * gpu_per_cpu);
    313   1.3  riastrad 	const uint64_t gpu_pgstart = (gpu_start / AMDGPU_GPU_PAGE_SIZE);
    314   1.8  riastrad 	const uint64_t pgstart __diagused = (gpu_pgstart / gpu_per_cpu);
    315   1.3  riastrad 	uint64_t pgno, gpu_pgno;
    316   1.3  riastrad 	uint32_t flags = AMDGPU_PTE_SYSTEM;
    317   1.3  riastrad 
    318   1.3  riastrad 	KASSERT(pgstart == (gpu_start / PAGE_SIZE));
    319   1.3  riastrad 	KASSERT(npages <= adev->gart.num_cpu_pages);
    320   1.3  riastrad 	KASSERT(gpu_npages <= adev->gart.num_cpu_pages);
    321   1.3  riastrad 
    322   1.3  riastrad 	if (!adev->gart.ready) {
    323   1.3  riastrad 		WARN(1, "trying to bind memory to uninitialized GART !\n");
    324   1.7  riastrad 		return -EINVAL;
    325   1.3  riastrad 	}
    326   1.3  riastrad 
    327   1.3  riastrad 	amdgpu_gart_pre_update(adev, gpu_pgstart, gpu_npages);
    328   1.3  riastrad 	for (pgno = 0; pgno < npages; pgno++) {
    329   1.6  riastrad #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
    330   1.3  riastrad 		adev->gart.pages[pgstart + pgno] = NULL;
    331   1.6  riastrad #endif
    332   1.3  riastrad 
    333   1.3  riastrad 		if (adev->gart.ptr == NULL)
    334   1.3  riastrad 			continue;
    335   1.3  riastrad 		for (gpu_pgno = 0; gpu_pgno < gpu_per_cpu; gpu_pgno++) {
    336   1.6  riastrad 			amdgpu_gmc_set_pte_pde(adev, adev->gart.ptr,
    337   1.3  riastrad 			    gpu_pgstart + gpu_per_cpu*pgno + gpu_pgno,
    338   1.6  riastrad 			    adev->dummy_page_addr, flags);
    339   1.3  riastrad 		}
    340   1.3  riastrad 	}
    341   1.3  riastrad 	amdgpu_gart_post_update(adev, gpu_pgstart, gpu_npages);
    342   1.7  riastrad 
    343   1.7  riastrad 	return 0;
    344   1.3  riastrad }
    345   1.3  riastrad #else  /* __NetBSD__ */
    346   1.1  riastrad /**
    347   1.1  riastrad  * amdgpu_gart_unbind - unbind pages from the gart page table
    348   1.1  riastrad  *
    349   1.1  riastrad  * @adev: amdgpu_device pointer
    350   1.1  riastrad  * @offset: offset into the GPU's gart aperture
    351   1.1  riastrad  * @pages: number of pages to unbind
    352   1.1  riastrad  *
    353   1.1  riastrad  * Unbinds the requested pages from the gart page table and
    354   1.1  riastrad  * replaces them with the dummy page (all asics).
    355   1.5  riastrad  * Returns 0 for success, -EINVAL for failure.
    356   1.1  riastrad  */
    357   1.5  riastrad int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
    358   1.1  riastrad 			int pages)
    359   1.1  riastrad {
    360   1.1  riastrad 	unsigned t;
    361   1.1  riastrad 	unsigned p;
    362   1.1  riastrad 	int i, j;
    363   1.1  riastrad 	u64 page_base;
    364   1.5  riastrad 	/* Starting from VEGA10, system bit must be 0 to mean invalid. */
    365   1.5  riastrad 	uint64_t flags = 0;
    366   1.1  riastrad 
    367   1.1  riastrad 	if (!adev->gart.ready) {
    368   1.1  riastrad 		WARN(1, "trying to unbind memory from uninitialized GART !\n");
    369   1.5  riastrad 		return -EINVAL;
    370   1.1  riastrad 	}
    371   1.1  riastrad 
    372   1.1  riastrad 	t = offset / AMDGPU_GPU_PAGE_SIZE;
    373   1.5  riastrad 	p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
    374   1.1  riastrad 	for (i = 0; i < pages; i++, p++) {
    375   1.5  riastrad #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
    376   1.5  riastrad 		adev->gart.pages[p] = NULL;
    377   1.5  riastrad #endif
    378   1.5  riastrad 		page_base = adev->dummy_page_addr;
    379   1.5  riastrad 		if (!adev->gart.ptr)
    380   1.5  riastrad 			continue;
    381   1.5  riastrad 
    382   1.5  riastrad 		for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) {
    383   1.5  riastrad 			amdgpu_gmc_set_pte_pde(adev, adev->gart.ptr,
    384   1.5  riastrad 					       t, page_base, flags);
    385   1.5  riastrad 			page_base += AMDGPU_GPU_PAGE_SIZE;
    386   1.1  riastrad 		}
    387   1.1  riastrad 	}
    388   1.1  riastrad 	mb();
    389   1.5  riastrad 	amdgpu_asic_flush_hdp(adev, NULL);
    390   1.5  riastrad 	for (i = 0; i < adev->num_vmhubs; i++)
    391   1.5  riastrad 		amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
    392   1.5  riastrad 
    393   1.5  riastrad 	return 0;
    394   1.5  riastrad }
    395   1.7  riastrad #endif	/* __NetBSD__ */
    396   1.5  riastrad 
    397   1.5  riastrad /**
    398   1.5  riastrad  * amdgpu_gart_map - map dma_addresses into GART entries
    399   1.5  riastrad  *
    400   1.5  riastrad  * @adev: amdgpu_device pointer
    401   1.5  riastrad  * @offset: offset into the GPU's gart aperture
    402   1.5  riastrad  * @pages: number of pages to bind
    403   1.5  riastrad  * @dma_addr: DMA addresses of pages
    404   1.5  riastrad  * @flags: page table entry flags
    405   1.5  riastrad  * @dst: CPU address of the gart table
    406   1.5  riastrad  *
    407   1.5  riastrad  * Map the dma_addresses into GART entries (all asics).
    408   1.5  riastrad  * Returns 0 for success, -EINVAL for failure.
    409   1.5  riastrad  */
    410   1.7  riastrad #ifdef __NetBSD__
    411   1.7  riastrad int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t gpu_start,
    412   1.7  riastrad     unsigned npages, bus_size_t map_start, bus_dmamap_t dmamap, uint32_t flags,
    413   1.7  riastrad     void *dst)
    414   1.7  riastrad {
    415   1.7  riastrad 	bus_size_t seg_off = 0;
    416   1.7  riastrad 	unsigned i, j, t;
    417   1.7  riastrad 
    418   1.7  riastrad 	CTASSERT(AMDGPU_GPU_PAGE_SIZE <= PAGE_SIZE);
    419   1.7  riastrad 	CTASSERT((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) == 0);
    420   1.7  riastrad 
    421   1.7  riastrad 	KASSERT((gpu_start & (PAGE_SIZE - 1)) == 0);
    422   1.7  riastrad 
    423   1.7  riastrad 	if (!adev->gart.ready) {
    424   1.7  riastrad 		WARN(1, "trying to bind memory to uninitialized GART !\n");
    425   1.7  riastrad 		return -EINVAL;
    426   1.7  riastrad 	}
    427   1.7  riastrad 
    428   1.7  riastrad 	for (i = 0; i < dmamap->dm_nsegs; i++) {
    429   1.7  riastrad 		KASSERT((dmamap->dm_segs[i].ds_len & (PAGE_SIZE - 1)) == 0);
    430   1.7  riastrad 		if (map_start == 0)
    431   1.7  riastrad 			break;
    432   1.7  riastrad 		if (map_start < dmamap->dm_segs[i].ds_len) {
    433   1.7  riastrad 			seg_off = map_start;
    434   1.7  riastrad 			break;
    435   1.7  riastrad 		}
    436   1.7  riastrad 		map_start -= dmamap->dm_segs[i].ds_len;
    437   1.7  riastrad 	}
    438   1.7  riastrad 	KASSERT(i < dmamap->dm_nsegs);
    439   1.7  riastrad 
    440   1.7  riastrad 	t = gpu_start / AMDGPU_GPU_PAGE_SIZE;
    441   1.7  riastrad 
    442   1.7  riastrad 	for (i = 0; npages --> 0;) {
    443  1.12  riastrad 		for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) {
    444  1.11  riastrad 			KASSERT(i < dmamap->dm_nsegs);
    445  1.11  riastrad 			KASSERT(seg_off < dmamap->dm_segs[i].ds_len);
    446   1.7  riastrad 			amdgpu_gmc_set_pte_pde(adev, dst, t,
    447   1.7  riastrad 			    dmamap->dm_segs[i].ds_addr + seg_off, flags);
    448   1.7  riastrad 			seg_off += AMDGPU_GPU_PAGE_SIZE;
    449   1.7  riastrad 			if (seg_off == dmamap->dm_segs[i].ds_len) {
    450   1.7  riastrad 				i++;
    451   1.7  riastrad 				seg_off = 0;
    452   1.7  riastrad 			}
    453   1.7  riastrad 		}
    454   1.7  riastrad 	}
    455   1.7  riastrad 
    456   1.7  riastrad 	return 0;
    457   1.7  riastrad }
    458   1.7  riastrad #else
    459   1.5  riastrad int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
    460   1.5  riastrad 		    int pages, dma_addr_t *dma_addr, uint64_t flags,
    461   1.5  riastrad 		    void *dst)
    462   1.5  riastrad {
    463   1.5  riastrad 	uint64_t page_base;
    464   1.5  riastrad 	unsigned i, j, t;
    465   1.5  riastrad 
    466   1.5  riastrad 	if (!adev->gart.ready) {
    467   1.5  riastrad 		WARN(1, "trying to bind memory to uninitialized GART !\n");
    468   1.5  riastrad 		return -EINVAL;
    469   1.5  riastrad 	}
    470   1.5  riastrad 
    471   1.5  riastrad 	t = offset / AMDGPU_GPU_PAGE_SIZE;
    472   1.5  riastrad 
    473   1.5  riastrad 	for (i = 0; i < pages; i++) {
    474   1.5  riastrad 		page_base = dma_addr[i];
    475   1.5  riastrad 		for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) {
    476   1.5  riastrad 			amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, flags);
    477   1.5  riastrad 			page_base += AMDGPU_GPU_PAGE_SIZE;
    478   1.5  riastrad 		}
    479   1.5  riastrad 	}
    480   1.5  riastrad 	return 0;
    481   1.1  riastrad }
    482   1.3  riastrad #endif	/* __NetBSD__ */
    483   1.3  riastrad 
    484   1.3  riastrad #ifdef __NetBSD__
    485   1.3  riastrad int
    486   1.3  riastrad amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t gpu_start,
    487   1.3  riastrad     unsigned npages, struct page **pages, bus_dmamap_t dmamap, uint32_t flags)
    488   1.3  riastrad {
    489   1.6  riastrad 	const unsigned gpu_per_cpu = AMDGPU_GPU_PAGES_IN_CPU_PAGE;
    490   1.3  riastrad 	const unsigned gpu_npages = (npages * gpu_per_cpu);
    491   1.3  riastrad 	const uint64_t gpu_pgstart = (gpu_start / AMDGPU_GPU_PAGE_SIZE);
    492   1.8  riastrad 	const uint64_t pgstart __diagused = (gpu_pgstart / gpu_per_cpu);
    493   1.3  riastrad 	uint64_t pgno, gpu_pgno;
    494   1.3  riastrad 
    495   1.3  riastrad 	KASSERT(pgstart == (gpu_start / PAGE_SIZE));
    496   1.3  riastrad 	KASSERT(npages == dmamap->dm_nsegs);
    497   1.3  riastrad 	KASSERT(npages <= adev->gart.num_cpu_pages);
    498   1.3  riastrad 	KASSERT(gpu_npages <= adev->gart.num_cpu_pages);
    499   1.3  riastrad 
    500   1.3  riastrad 	if (!adev->gart.ready) {
    501   1.3  riastrad 		WARN(1, "trying to bind memory to uninitialized GART !\n");
    502   1.3  riastrad 		return -EINVAL;
    503   1.3  riastrad 	}
    504   1.3  riastrad 
    505   1.3  riastrad 	amdgpu_gart_pre_update(adev, gpu_pgstart, gpu_npages);
    506   1.3  riastrad 	for (pgno = 0; pgno < npages; pgno++) {
    507   1.3  riastrad 		const bus_addr_t addr = dmamap->dm_segs[pgno].ds_addr;
    508   1.3  riastrad 
    509   1.3  riastrad 		KASSERT(dmamap->dm_segs[pgno].ds_len == PAGE_SIZE);
    510   1.6  riastrad #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
    511   1.6  riastrad 		adev->gart.pages[pgstart + pgno] = NULL;
    512   1.6  riastrad #endif
    513   1.3  riastrad 
    514   1.3  riastrad 		if (adev->gart.ptr == NULL)
    515   1.3  riastrad 			continue;
    516   1.3  riastrad 
    517   1.3  riastrad 		for (gpu_pgno = 0; gpu_pgno < gpu_per_cpu; gpu_pgno++) {
    518   1.6  riastrad 			amdgpu_gmc_set_pte_pde(adev, adev->gart.ptr,
    519   1.3  riastrad 			    gpu_pgstart + gpu_per_cpu*pgno + gpu_pgno,
    520   1.3  riastrad 			    addr + gpu_pgno*AMDGPU_GPU_PAGE_SIZE, flags);
    521   1.3  riastrad 		}
    522   1.3  riastrad 	}
    523   1.3  riastrad 	amdgpu_gart_post_update(adev, gpu_pgstart, gpu_npages);
    524   1.1  riastrad 
    525   1.3  riastrad 	return 0;
    526   1.3  riastrad }
    527   1.3  riastrad #else  /* __NetBSD__ */
    528   1.1  riastrad /**
    529   1.1  riastrad  * amdgpu_gart_bind - bind pages into the gart page table
    530   1.1  riastrad  *
    531   1.1  riastrad  * @adev: amdgpu_device pointer
    532   1.1  riastrad  * @offset: offset into the GPU's gart aperture
    533   1.1  riastrad  * @pages: number of pages to bind
    534   1.1  riastrad  * @pagelist: pages to bind
    535   1.1  riastrad  * @dma_addr: DMA addresses of pages
    536   1.5  riastrad  * @flags: page table entry flags
    537   1.1  riastrad  *
    538   1.1  riastrad  * Binds the requested pages to the gart page table
    539   1.1  riastrad  * (all asics).
    540   1.1  riastrad  * Returns 0 for success, -EINVAL for failure.
    541   1.1  riastrad  */
    542   1.1  riastrad int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
    543   1.1  riastrad 		     int pages, struct page **pagelist, dma_addr_t *dma_addr,
    544   1.5  riastrad 		     uint64_t flags)
    545   1.1  riastrad {
    546   1.5  riastrad #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
    547   1.5  riastrad 	unsigned t,p;
    548   1.5  riastrad #endif
    549   1.5  riastrad 	int r, i;
    550   1.1  riastrad 
    551   1.1  riastrad 	if (!adev->gart.ready) {
    552   1.1  riastrad 		WARN(1, "trying to bind memory to uninitialized GART !\n");
    553   1.1  riastrad 		return -EINVAL;
    554   1.1  riastrad 	}
    555   1.1  riastrad 
    556   1.5  riastrad #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
    557   1.1  riastrad 	t = offset / AMDGPU_GPU_PAGE_SIZE;
    558   1.5  riastrad 	p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE;
    559   1.5  riastrad 	for (i = 0; i < pages; i++, p++)
    560   1.5  riastrad 		adev->gart.pages[p] = pagelist ? pagelist[i] : NULL;
    561   1.5  riastrad #endif
    562   1.5  riastrad 
    563   1.5  riastrad 	if (!adev->gart.ptr)
    564   1.5  riastrad 		return 0;
    565   1.5  riastrad 
    566   1.5  riastrad 	r = amdgpu_gart_map(adev, offset, pages, dma_addr, flags,
    567   1.5  riastrad 		    adev->gart.ptr);
    568   1.5  riastrad 	if (r)
    569   1.5  riastrad 		return r;
    570   1.1  riastrad 
    571   1.1  riastrad 	mb();
    572   1.5  riastrad 	amdgpu_asic_flush_hdp(adev, NULL);
    573   1.5  riastrad 	for (i = 0; i < adev->num_vmhubs; i++)
    574   1.5  riastrad 		amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
    575   1.1  riastrad 	return 0;
    576   1.1  riastrad }
    577   1.3  riastrad #endif
    578   1.1  riastrad 
    579   1.1  riastrad /**
    580   1.1  riastrad  * amdgpu_gart_init - init the driver info for managing the gart
    581   1.1  riastrad  *
    582   1.1  riastrad  * @adev: amdgpu_device pointer
    583   1.1  riastrad  *
    584   1.1  riastrad  * Allocate the dummy page and init the gart driver info (all asics).
    585   1.1  riastrad  * Returns 0 for success, error for failure.
    586   1.1  riastrad  */
    587   1.1  riastrad int amdgpu_gart_init(struct amdgpu_device *adev)
    588   1.1  riastrad {
    589   1.5  riastrad 	int r;
    590   1.1  riastrad 
    591   1.5  riastrad 	if (adev->dummy_page_addr)
    592   1.1  riastrad 		return 0;
    593   1.5  riastrad 
    594   1.1  riastrad 	/* We need PAGE_SIZE >= AMDGPU_GPU_PAGE_SIZE */
    595   1.1  riastrad 	if (PAGE_SIZE < AMDGPU_GPU_PAGE_SIZE) {
    596   1.1  riastrad 		DRM_ERROR("Page size is smaller than GPU page size!\n");
    597   1.1  riastrad 		return -EINVAL;
    598   1.1  riastrad 	}
    599   1.5  riastrad 	r = amdgpu_gart_dummy_page_init(adev);
    600   1.1  riastrad 	if (r)
    601   1.1  riastrad 		return r;
    602   1.1  riastrad 	/* Compute table size */
    603   1.5  riastrad 	adev->gart.num_cpu_pages = adev->gmc.gart_size / PAGE_SIZE;
    604   1.5  riastrad 	adev->gart.num_gpu_pages = adev->gmc.gart_size / AMDGPU_GPU_PAGE_SIZE;
    605   1.1  riastrad 	DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
    606   1.1  riastrad 		 adev->gart.num_cpu_pages, adev->gart.num_gpu_pages);
    607   1.5  riastrad 
    608   1.5  riastrad #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
    609   1.1  riastrad 	/* Allocate pages table */
    610   1.5  riastrad 	adev->gart.pages = vzalloc(array_size(sizeof(void *),
    611   1.5  riastrad 					      adev->gart.num_cpu_pages));
    612   1.5  riastrad 	if (adev->gart.pages == NULL)
    613   1.1  riastrad 		return -ENOMEM;
    614   1.5  riastrad #endif
    615   1.5  riastrad 
    616   1.1  riastrad 	return 0;
    617   1.1  riastrad }
    618   1.1  riastrad 
    619   1.1  riastrad /**
    620   1.1  riastrad  * amdgpu_gart_fini - tear down the driver info for managing the gart
    621   1.1  riastrad  *
    622   1.1  riastrad  * @adev: amdgpu_device pointer
    623   1.1  riastrad  *
    624   1.1  riastrad  * Tear down the gart driver info and free the dummy page (all asics).
    625   1.1  riastrad  */
    626   1.1  riastrad void amdgpu_gart_fini(struct amdgpu_device *adev)
    627   1.1  riastrad {
    628   1.5  riastrad #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
    629   1.1  riastrad 	vfree(adev->gart.pages);
    630   1.1  riastrad 	adev->gart.pages = NULL;
    631   1.5  riastrad #endif
    632   1.5  riastrad 	amdgpu_gart_dummy_page_fini(adev);
    633   1.1  riastrad }
    634