Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * Copyright 2018 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 *
25 */
26#ifndef __AMDGPU_GMC_H__
27#define __AMDGPU_GMC_H__
28
29#include <linux/types.h>
30
31#include "amdgpu_irq.h"
32#include "amdgpu_ras.h"
33
34/* VA hole for 48bit addresses on Vega10 */
35#define AMDGPU_GMC_HOLE_START 0x0000800000000000ULL
36#define AMDGPU_GMC_HOLE_END 0xffff800000000000ULL
37
38/*
39 * Hardware is programmed as if the hole doesn't exists with start and end
40 * address values.
41 *
42 * This mask is used to remove the upper 16bits of the VA and so come up with
43 * the linear addr value.
44 */
45#define AMDGPU_GMC_HOLE_MASK 0x0000ffffffffffffULL
46
47/*
48 * Ring size as power of two for the log of recent faults.
49 */
50#define AMDGPU_GMC_FAULT_RING_ORDER 8
51#define AMDGPU_GMC_FAULT_RING_SIZE (1 << AMDGPU_GMC_FAULT_RING_ORDER)
52
53/*
54 * Hash size as power of two for the log of recent faults
55 */
56#define AMDGPU_GMC_FAULT_HASH_ORDER 8
57#define AMDGPU_GMC_FAULT_HASH_SIZE (1 << AMDGPU_GMC_FAULT_HASH_ORDER)
58
59/*
60 * Number of IH timestamp ticks until a fault is considered handled
61 */
62#define AMDGPU_GMC_FAULT_TIMEOUT 5000ULL
63
64struct firmware;
65
66/*
67 * GMC page fault information
68 */
69struct amdgpu_gmc_fault {
70 uint64_t timestamp:48;
71 uint64_t next:AMDGPU_GMC_FAULT_RING_ORDER;
72 atomic64_t key;
73};
74
75/*
76 * VMHUB structures, functions & helpers
77 */
78struct amdgpu_vmhub_funcs {
79 void (*print_l2_protection_fault_status)(struct amdgpu_device *adev,
80 uint32_t status);
81 uint32_t (*get_invalidate_req)(unsigned int vmid, uint32_t flush_type);
82};
83
84struct amdgpu_vmhub {
85 uint32_t ctx0_ptb_addr_lo32;
86 uint32_t ctx0_ptb_addr_hi32;
87 uint32_t vm_inv_eng0_sem;
88 uint32_t vm_inv_eng0_req;
89 uint32_t vm_inv_eng0_ack;
90 uint32_t vm_context0_cntl;
91 uint32_t vm_l2_pro_fault_status;
92 uint32_t vm_l2_pro_fault_cntl;
93
94 /*
95 * store the register distances between two continuous context domain
96 * and invalidation engine.
97 */
98 uint32_t ctx_distance;
99 uint32_t ctx_addr_distance; /* include LO32/HI32 */
100 uint32_t eng_distance;
101 uint32_t eng_addr_distance; /* include LO32/HI32 */
102
103 uint32_t vm_cntx_cntl_vm_fault;
104
105 const struct amdgpu_vmhub_funcs *vmhub_funcs;
106};
107
108/*
109 * GPU MC structures, functions & helpers
110 */
111struct amdgpu_gmc_funcs {
112 /* flush the vm tlb via mmio */
113 void (*flush_gpu_tlb)(struct amdgpu_device *adev, uint32_t vmid,
114 uint32_t vmhub, uint32_t flush_type);
115 /* flush the vm tlb via pasid */
116 int (*flush_gpu_tlb_pasid)(struct amdgpu_device *adev, uint16_t pasid,
117 uint32_t flush_type, bool all_hub);
118 /* flush the vm tlb via ring */
119 uint64_t (*emit_flush_gpu_tlb)(struct amdgpu_ring *ring, unsigned vmid,
120 uint64_t pd_addr);
121 /* Change the VMID -> PASID mapping */
122 void (*emit_pasid_mapping)(struct amdgpu_ring *ring, unsigned vmid,
123 unsigned pasid);
124 /* enable/disable PRT support */
125 void (*set_prt)(struct amdgpu_device *adev, bool enable);
126 /* map mtype to hardware flags */
127 uint64_t (*map_mtype)(struct amdgpu_device *adev, uint32_t flags);
128 /* get the pde for a given mc addr */
129 void (*get_vm_pde)(struct amdgpu_device *adev, int level,
130 u64 *dst, u64 *flags);
131 /* get the pte flags to use for a BO VA mapping */
132 void (*get_vm_pte)(struct amdgpu_device *adev,
133 struct amdgpu_bo_va_mapping *mapping,
134 uint64_t *flags);
135 /* get the amount of memory used by the vbios for pre-OS console */
136 unsigned int (*get_vbios_fb_size)(struct amdgpu_device *adev);
137};
138
139struct amdgpu_xgmi_ras {
140 struct amdgpu_ras_block_object ras_block;
141};
142
143struct amdgpu_xgmi {
144 /* from psp */
145 u64 node_id;
146 u64 hive_id;
147 /* fixed per family */
148 u64 node_segment_size;
149 /* physical node (0-3) */
150 unsigned physical_node_id;
151 /* number of nodes (0-4) */
152 unsigned num_physical_nodes;
153 /* gpu list in the same hive */
154 struct list_head head;
155 bool supported;
156 struct ras_common_if *ras_if;
157 bool connected_to_cpu;
158 bool pending_reset;
159 struct amdgpu_xgmi_ras *ras;
160};
161
162struct amdgpu_gmc {
163 /* FB's physical address in MMIO space (for CPU to
164 * map FB). This is different compared to the agp/
165 * gart/vram_start/end field as the later is from
166 * GPU's view and aper_base is from CPU's view.
167 */
168 resource_size_t aper_size;
169 resource_size_t aper_base;
170 /* for some chips with <= 32MB we need to lie
171 * about vram size near mc fb location */
172 u64 mc_vram_size;
173 u64 visible_vram_size;
174 /* AGP aperture start and end in MC address space
175 * Driver find a hole in the MC address space
176 * to place AGP by setting MC_VM_AGP_BOT/TOP registers
177 * Under VMID0, logical address == MC address. AGP
178 * aperture maps to physical bus or IOVA addressed.
179 * AGP aperture is used to simulate FB in ZFB case.
180 * AGP aperture is also used for page table in system
181 * memory (mainly for APU).
182 *
183 */
184 u64 agp_size;
185 u64 agp_start;
186 u64 agp_end;
187 /* GART aperture start and end in MC address space
188 * Driver find a hole in the MC address space
189 * to place GART by setting VM_CONTEXT0_PAGE_TABLE_START/END_ADDR
190 * registers
191 * Under VMID0, logical address inside GART aperture will
192 * be translated through gpuvm gart page table to access
193 * paged system memory
194 */
195 u64 gart_size;
196 u64 gart_start;
197 u64 gart_end;
198 /* Frame buffer aperture of this GPU device. Different from
199 * fb_start (see below), this only covers the local GPU device.
200 * If driver uses FB aperture to access FB, driver get fb_start from
201 * MC_VM_FB_LOCATION_BASE (set by vbios) and calculate vram_start
202 * of this local device by adding an offset inside the XGMI hive.
203 * If driver uses GART table for VMID0 FB access, driver finds a hole in
204 * VMID0's virtual address space to place the SYSVM aperture inside
205 * which the first part is vram and the second part is gart (covering
206 * system ram).
207 */
208 u64 vram_start;
209 u64 vram_end;
210 /* FB region , it's same as local vram region in single GPU, in XGMI
211 * configuration, this region covers all GPUs in the same hive ,
212 * each GPU in the hive has the same view of this FB region .
213 * GPU0's vram starts at offset (0 * segment size) ,
214 * GPU1 starts at offset (1 * segment size), etc.
215 */
216 u64 fb_start;
217 u64 fb_end;
218 unsigned vram_width;
219 u64 real_vram_size;
220 int vram_mtrr;
221 u64 mc_mask;
222 const struct firmware *fw; /* MC firmware */
223 uint32_t fw_version;
224 struct amdgpu_irq_src vm_fault;
225 uint32_t vram_type;
226 uint8_t vram_vendor;
227 uint32_t srbm_soft_reset;
228 bool prt_warning;
229 uint32_t sdpif_register;
230 /* apertures */
231 u64 shared_aperture_start;
232 u64 shared_aperture_end;
233 u64 private_aperture_start;
234 u64 private_aperture_end;
235 /* protects concurrent invalidation */
236 spinlock_t invalidate_lock;
237 bool translate_further;
238 struct kfd_vm_fault_info *vm_fault_info;
239 atomic_t vm_fault_info_updated;
240
241 struct amdgpu_gmc_fault fault_ring[AMDGPU_GMC_FAULT_RING_SIZE];
242 struct {
243 uint64_t idx:AMDGPU_GMC_FAULT_RING_ORDER;
244 } fault_hash[AMDGPU_GMC_FAULT_HASH_SIZE];
245 uint64_t last_fault:AMDGPU_GMC_FAULT_RING_ORDER;
246
247 bool tmz_enabled;
248
249 const struct amdgpu_gmc_funcs *gmc_funcs;
250
251 struct amdgpu_xgmi xgmi;
252 struct amdgpu_irq_src ecc_irq;
253 int noretry;
254
255 uint32_t vmid0_page_table_block_size;
256 uint32_t vmid0_page_table_depth;
257 struct amdgpu_bo *pdb0_bo;
258 /* CPU kmapped address of pdb0*/
259 void *ptr_pdb0;
260};
261
262#define amdgpu_gmc_flush_gpu_tlb(adev, vmid, vmhub, type) ((adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid), (vmhub), (type)))
263#define amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, type, allhub) \
264 ((adev)->gmc.gmc_funcs->flush_gpu_tlb_pasid \
265 ((adev), (pasid), (type), (allhub)))
266#define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr))
267#define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid))
268#define amdgpu_gmc_map_mtype(adev, flags) (adev)->gmc.gmc_funcs->map_mtype((adev),(flags))
269#define amdgpu_gmc_get_vm_pde(adev, level, dst, flags) (adev)->gmc.gmc_funcs->get_vm_pde((adev), (level), (dst), (flags))
270#define amdgpu_gmc_get_vm_pte(adev, mapping, flags) (adev)->gmc.gmc_funcs->get_vm_pte((adev), (mapping), (flags))
271#define amdgpu_gmc_get_vbios_fb_size(adev) (adev)->gmc.gmc_funcs->get_vbios_fb_size((adev))
272
273/**
274 * amdgpu_gmc_vram_full_visible - Check if full VRAM is visible through the BAR
275 *
276 * @adev: amdgpu_device pointer
277 *
278 * Returns:
279 * True if full VRAM is visible through the BAR
280 */
281static inline bool amdgpu_gmc_vram_full_visible(struct amdgpu_gmc *gmc)
282{
283 WARN_ON(gmc->real_vram_size < gmc->visible_vram_size);
284
285 return (gmc->real_vram_size == gmc->visible_vram_size);
286}
287
288/**
289 * amdgpu_gmc_sign_extend - sign extend the given gmc address
290 *
291 * @addr: address to extend
292 */
293static inline uint64_t amdgpu_gmc_sign_extend(uint64_t addr)
294{
295 if (addr >= AMDGPU_GMC_HOLE_START)
296 addr |= AMDGPU_GMC_HOLE_END;
297
298 return addr;
299}
300
301int amdgpu_gmc_pdb0_alloc(struct amdgpu_device *adev);
302void amdgpu_gmc_get_pde_for_bo(struct amdgpu_bo *bo, int level,
303 uint64_t *addr, uint64_t *flags);
304int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr,
305 uint32_t gpu_page_idx, uint64_t addr,
306 uint64_t flags);
307uint64_t amdgpu_gmc_pd_addr(struct amdgpu_bo *bo);
308uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo);
309void amdgpu_gmc_sysvm_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc);
310void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
311 u64 base);
312void amdgpu_gmc_gart_location(struct amdgpu_device *adev,
313 struct amdgpu_gmc *mc);
314void amdgpu_gmc_agp_location(struct amdgpu_device *adev,
315 struct amdgpu_gmc *mc);
316bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev,
317 struct amdgpu_ih_ring *ih, uint64_t addr,
318 uint16_t pasid, uint64_t timestamp);
319void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
320 uint16_t pasid);
321int amdgpu_gmc_ras_early_init(struct amdgpu_device *adev);
322int amdgpu_gmc_ras_late_init(struct amdgpu_device *adev);
323void amdgpu_gmc_ras_fini(struct amdgpu_device *adev);
324int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev);
325
326extern void amdgpu_gmc_tmz_set(struct amdgpu_device *adev);
327extern void amdgpu_gmc_noretry_set(struct amdgpu_device *adev);
328
329extern void
330amdgpu_gmc_set_vm_fault_masks(struct amdgpu_device *adev, int hub_type,
331 bool enable);
332
333void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev);
334
335void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev);
336uint64_t amdgpu_gmc_vram_mc2pa(struct amdgpu_device *adev, uint64_t mc_addr);
337uint64_t amdgpu_gmc_vram_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
338uint64_t amdgpu_gmc_vram_cpu_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo);
339int amdgpu_gmc_vram_checking(struct amdgpu_device *adev);
340#endif