1770b93e9SHawking Zhang /*
2770b93e9SHawking Zhang  * Copyright 2019 Advanced Micro Devices, Inc.
3770b93e9SHawking Zhang  *
4770b93e9SHawking Zhang  * Permission is hereby granted, free of charge, to any person obtaining a
5770b93e9SHawking Zhang  * copy of this software and associated documentation files (the "Software"),
6770b93e9SHawking Zhang  * to deal in the Software without restriction, including without limitation
7770b93e9SHawking Zhang  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8770b93e9SHawking Zhang  * and/or sell copies of the Software, and to permit persons to whom the
9770b93e9SHawking Zhang  * Software is furnished to do so, subject to the following conditions:
10770b93e9SHawking Zhang  *
11770b93e9SHawking Zhang  * The above copyright notice and this permission notice shall be included in
12770b93e9SHawking Zhang  * all copies or substantial portions of the Software.
13770b93e9SHawking Zhang  *
14770b93e9SHawking Zhang  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15770b93e9SHawking Zhang  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16770b93e9SHawking Zhang  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17770b93e9SHawking Zhang  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18770b93e9SHawking Zhang  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19770b93e9SHawking Zhang  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20770b93e9SHawking Zhang  * OTHER DEALINGS IN THE SOFTWARE.
21770b93e9SHawking Zhang  *
22770b93e9SHawking Zhang  */
23770b93e9SHawking Zhang 
24770b93e9SHawking Zhang #include "amdgpu.h"
25770b93e9SHawking Zhang #include "gfxhub_v2_0.h"
26770b93e9SHawking Zhang 
27770b93e9SHawking Zhang #include "gc/gc_10_1_0_offset.h"
28770b93e9SHawking Zhang #include "gc/gc_10_1_0_sh_mask.h"
29770b93e9SHawking Zhang #include "gc/gc_10_1_0_default.h"
30770b93e9SHawking Zhang #include "navi10_enum.h"
31770b93e9SHawking Zhang 
32770b93e9SHawking Zhang #include "soc15_common.h"
33770b93e9SHawking Zhang 
34*0e2b8507SSrinivasan Shanmugam static const char * const gfxhub_client_ids[] = {
3593fabd84SAlex Deucher 	"CB/DB",
3693fabd84SAlex Deucher 	"Reserved",
3793fabd84SAlex Deucher 	"GE1",
3893fabd84SAlex Deucher 	"GE2",
3993fabd84SAlex Deucher 	"CPF",
4093fabd84SAlex Deucher 	"CPC",
4193fabd84SAlex Deucher 	"CPG",
4293fabd84SAlex Deucher 	"RLC",
4393fabd84SAlex Deucher 	"TCP",
4493fabd84SAlex Deucher 	"SQC (inst)",
4593fabd84SAlex Deucher 	"SQC (data)",
4693fabd84SAlex Deucher 	"SQG",
4793fabd84SAlex Deucher 	"Reserved",
4893fabd84SAlex Deucher 	"SDMA0",
4993fabd84SAlex Deucher 	"SDMA1",
5093fabd84SAlex Deucher 	"GCR",
5193fabd84SAlex Deucher 	"SDMA2",
5293fabd84SAlex Deucher 	"SDMA3",
5393fabd84SAlex Deucher };
5493fabd84SAlex Deucher 
gfxhub_v2_0_get_invalidate_req(unsigned int vmid,uint32_t flush_type)55caa9f483SHuang Rui static uint32_t gfxhub_v2_0_get_invalidate_req(unsigned int vmid,
56caa9f483SHuang Rui 					       uint32_t flush_type)
57caa9f483SHuang Rui {
58caa9f483SHuang Rui 	u32 req = 0;
59caa9f483SHuang Rui 
60caa9f483SHuang Rui 	/* invalidate using legacy mode on vmid*/
61caa9f483SHuang Rui 	req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ,
62caa9f483SHuang Rui 			    PER_VMID_INVALIDATE_REQ, 1 << vmid);
63caa9f483SHuang Rui 	req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type);
64caa9f483SHuang Rui 	req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
65caa9f483SHuang Rui 	req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
66caa9f483SHuang Rui 	req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1);
67caa9f483SHuang Rui 	req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1);
68caa9f483SHuang Rui 	req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1);
69caa9f483SHuang Rui 	req = REG_SET_FIELD(req, GCVM_INVALIDATE_ENG0_REQ,
70caa9f483SHuang Rui 			    CLEAR_PROTECTION_FAULT_STATUS_ADDR,	0);
71caa9f483SHuang Rui 
72caa9f483SHuang Rui 	return req;
73caa9f483SHuang Rui }
74caa9f483SHuang Rui 
752577db91SHuang Rui static void
gfxhub_v2_0_print_l2_protection_fault_status(struct amdgpu_device * adev,uint32_t status)762577db91SHuang Rui gfxhub_v2_0_print_l2_protection_fault_status(struct amdgpu_device *adev,
772577db91SHuang Rui 					     uint32_t status)
782577db91SHuang Rui {
7993fabd84SAlex Deucher 	u32 cid = REG_GET_FIELD(status,
8093fabd84SAlex Deucher 				GCVM_L2_PROTECTION_FAULT_STATUS, CID);
8193fabd84SAlex Deucher 
822577db91SHuang Rui 	dev_err(adev->dev,
832577db91SHuang Rui 		"GCVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
842577db91SHuang Rui 		status);
8593fabd84SAlex Deucher 	dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
8693fabd84SAlex Deucher 		cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : gfxhub_client_ids[cid],
8793fabd84SAlex Deucher 		cid);
882577db91SHuang Rui 	dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
892577db91SHuang Rui 		REG_GET_FIELD(status,
902577db91SHuang Rui 		GCVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
912577db91SHuang Rui 	dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
922577db91SHuang Rui 		REG_GET_FIELD(status,
932577db91SHuang Rui 		GCVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
942577db91SHuang Rui 	dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
952577db91SHuang Rui 		REG_GET_FIELD(status,
962577db91SHuang Rui 		GCVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
972577db91SHuang Rui 	dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
982577db91SHuang Rui 		REG_GET_FIELD(status,
992577db91SHuang Rui 		GCVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
1002577db91SHuang Rui 	dev_err(adev->dev, "\t RW: 0x%lx\n",
1012577db91SHuang Rui 		REG_GET_FIELD(status,
1022577db91SHuang Rui 		GCVM_L2_PROTECTION_FAULT_STATUS, RW));
1032577db91SHuang Rui }
1042577db91SHuang Rui 
gfxhub_v2_0_get_fb_location(struct amdgpu_device * adev)1058ffff9b4SOak Zeng static u64 gfxhub_v2_0_get_fb_location(struct amdgpu_device *adev)
106770b93e9SHawking Zhang {
107770b93e9SHawking Zhang 	u64 base = RREG32_SOC15(GC, 0, mmGCMC_VM_FB_LOCATION_BASE);
108770b93e9SHawking Zhang 
109770b93e9SHawking Zhang 	base &= GCMC_VM_FB_LOCATION_BASE__FB_BASE_MASK;
110770b93e9SHawking Zhang 	base <<= 24;
111770b93e9SHawking Zhang 
112770b93e9SHawking Zhang 	return base;
113770b93e9SHawking Zhang }
114770b93e9SHawking Zhang 
gfxhub_v2_0_get_mc_fb_offset(struct amdgpu_device * adev)1158ffff9b4SOak Zeng static u64 gfxhub_v2_0_get_mc_fb_offset(struct amdgpu_device *adev)
116770b93e9SHawking Zhang {
117770b93e9SHawking Zhang 	return (u64)RREG32_SOC15(GC, 0, mmGCMC_VM_FB_OFFSET) << 24;
118770b93e9SHawking Zhang }
119770b93e9SHawking Zhang 
gfxhub_v2_0_setup_vm_pt_regs(struct amdgpu_device * adev,uint32_t vmid,uint64_t page_table_base)1208ffff9b4SOak Zeng static void gfxhub_v2_0_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid,
121286b789eSYong Zhao 				uint64_t page_table_base)
122770b93e9SHawking Zhang {
123f4caf584SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
124770b93e9SHawking Zhang 
125286b789eSYong Zhao 	WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
1261e40eebeSHuang Rui 			    hub->ctx_addr_distance * vmid,
1271e40eebeSHuang Rui 			    lower_32_bits(page_table_base));
128770b93e9SHawking Zhang 
129286b789eSYong Zhao 	WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
1301e40eebeSHuang Rui 			    hub->ctx_addr_distance * vmid,
1311e40eebeSHuang Rui 			    upper_32_bits(page_table_base));
132770b93e9SHawking Zhang }
133770b93e9SHawking Zhang 
gfxhub_v2_0_init_gart_aperture_regs(struct amdgpu_device * adev)134770b93e9SHawking Zhang static void gfxhub_v2_0_init_gart_aperture_regs(struct amdgpu_device *adev)
135770b93e9SHawking Zhang {
136286b789eSYong Zhao 	uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
137286b789eSYong Zhao 
138286b789eSYong Zhao 	gfxhub_v2_0_setup_vm_pt_regs(adev, 0, pt_base);
139770b93e9SHawking Zhang 
140770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
141770b93e9SHawking Zhang 		     (u32)(adev->gmc.gart_start >> 12));
142770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
143770b93e9SHawking Zhang 		     (u32)(adev->gmc.gart_start >> 44));
144770b93e9SHawking Zhang 
145770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
146770b93e9SHawking Zhang 		     (u32)(adev->gmc.gart_end >> 12));
147770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
148770b93e9SHawking Zhang 		     (u32)(adev->gmc.gart_end >> 44));
149770b93e9SHawking Zhang }
150770b93e9SHawking Zhang 
gfxhub_v2_0_init_system_aperture_regs(struct amdgpu_device * adev)151770b93e9SHawking Zhang static void gfxhub_v2_0_init_system_aperture_regs(struct amdgpu_device *adev)
152770b93e9SHawking Zhang {
153770b93e9SHawking Zhang 	uint64_t value;
154770b93e9SHawking Zhang 
1558a43cf88STiecheng Zhou 	if (!amdgpu_sriov_vf(adev)) {
15699698b51SAlex Deucher 		/* Program the AGP BAR */
157770b93e9SHawking Zhang 		WREG32_SOC15(GC, 0, mmGCMC_VM_AGP_BASE, 0);
15899698b51SAlex Deucher 		WREG32_SOC15(GC, 0, mmGCMC_VM_AGP_BOT, adev->gmc.agp_start >> 24);
15999698b51SAlex Deucher 		WREG32_SOC15(GC, 0, mmGCMC_VM_AGP_TOP, adev->gmc.agp_end >> 24);
160770b93e9SHawking Zhang 
161770b93e9SHawking Zhang 		/* Program the system aperture low logical page number. */
162770b93e9SHawking Zhang 		WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_LOW_ADDR,
16399698b51SAlex Deucher 			     min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
164770b93e9SHawking Zhang 		WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
16599698b51SAlex Deucher 			     max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
166770b93e9SHawking Zhang 
167770b93e9SHawking Zhang 		/* Set default page address. */
1687ccfd79fSChristian König 		value = amdgpu_gmc_vram_mc2pa(adev, adev->mem_scratch.gpu_addr);
169770b93e9SHawking Zhang 		WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
170770b93e9SHawking Zhang 			     (u32)(value >> 12));
171770b93e9SHawking Zhang 		WREG32_SOC15(GC, 0, mmGCMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
172770b93e9SHawking Zhang 			     (u32)(value >> 44));
1738a43cf88STiecheng Zhou 	}
174770b93e9SHawking Zhang 
175770b93e9SHawking Zhang 	/* Program "protection fault". */
176770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
177770b93e9SHawking Zhang 		     (u32)(adev->dummy_page_addr >> 12));
178770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
179770b93e9SHawking Zhang 		     (u32)((u64)adev->dummy_page_addr >> 44));
180770b93e9SHawking Zhang 
181770b93e9SHawking Zhang 	WREG32_FIELD15(GC, 0, GCVM_L2_PROTECTION_FAULT_CNTL2,
182770b93e9SHawking Zhang 		       ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1);
183770b93e9SHawking Zhang }
184770b93e9SHawking Zhang 
185770b93e9SHawking Zhang 
gfxhub_v2_0_init_tlb_regs(struct amdgpu_device * adev)186770b93e9SHawking Zhang static void gfxhub_v2_0_init_tlb_regs(struct amdgpu_device *adev)
187770b93e9SHawking Zhang {
188770b93e9SHawking Zhang 	uint32_t tmp;
189770b93e9SHawking Zhang 
190770b93e9SHawking Zhang 	/* Setup TLB control */
191770b93e9SHawking Zhang 	tmp = RREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL);
192770b93e9SHawking Zhang 
193770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
194770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3);
195770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
196770b93e9SHawking Zhang 			    ENABLE_ADVANCED_DRIVER_MODEL, 1);
197770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
198770b93e9SHawking Zhang 			    SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
199770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
200770b93e9SHawking Zhang 			    MTYPE, MTYPE_UC); /* UC, uncached */
201770b93e9SHawking Zhang 
202770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL, tmp);
203770b93e9SHawking Zhang }
204770b93e9SHawking Zhang 
gfxhub_v2_0_init_cache_regs(struct amdgpu_device * adev)205770b93e9SHawking Zhang static void gfxhub_v2_0_init_cache_regs(struct amdgpu_device *adev)
206770b93e9SHawking Zhang {
207770b93e9SHawking Zhang 	uint32_t tmp;
208770b93e9SHawking Zhang 
20975ddb640SRohit Khaire 	/* These regs are not accessible for VF, PF will program these in SRIOV */
21075ddb640SRohit Khaire 	if (amdgpu_sriov_vf(adev))
21175ddb640SRohit Khaire 		return;
21275ddb640SRohit Khaire 
213770b93e9SHawking Zhang 	/* Setup L2 cache */
214770b93e9SHawking Zhang 	tmp = RREG32_SOC15(GC, 0, mmGCVM_L2_CNTL);
215770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, ENABLE_L2_CACHE, 1);
216770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
2173ebab625SJack Xiao 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
2183ebab625SJack Xiao 			    ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1);
219770b93e9SHawking Zhang 	/* XXX for emulation, Refer to closed source code.*/
220770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL,
221770b93e9SHawking Zhang 			    L2_PDE0_CACHE_TAG_GENERATION_MODE, 0);
2228b7d6157SYong Zhao 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
223770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
224770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
225770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL, tmp);
226770b93e9SHawking Zhang 
227770b93e9SHawking Zhang 	tmp = RREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2);
228770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
229770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
230770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2, tmp);
231770b93e9SHawking Zhang 
232770b93e9SHawking Zhang 	tmp = mmGCVM_L2_CNTL3_DEFAULT;
23346203a50SAlex Deucher 	if (adev->gmc.translate_further) {
23446203a50SAlex Deucher 		tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 12);
23546203a50SAlex Deucher 		tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
23646203a50SAlex Deucher 				    L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
23746203a50SAlex Deucher 	} else {
23846203a50SAlex Deucher 		tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 9);
23946203a50SAlex Deucher 		tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3,
24046203a50SAlex Deucher 				    L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
24146203a50SAlex Deucher 	}
242770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL3, tmp);
243770b93e9SHawking Zhang 
244770b93e9SHawking Zhang 	tmp = mmGCVM_L2_CNTL4_DEFAULT;
245770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
246770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0);
247770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL4, tmp);
248ec683759SAlex Deucher 
249ec683759SAlex Deucher 	tmp = mmGCVM_L2_CNTL5_DEFAULT;
250ec683759SAlex Deucher 	tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
251ec683759SAlex Deucher 	WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL5, tmp);
252770b93e9SHawking Zhang }
253770b93e9SHawking Zhang 
gfxhub_v2_0_enable_system_domain(struct amdgpu_device * adev)254770b93e9SHawking Zhang static void gfxhub_v2_0_enable_system_domain(struct amdgpu_device *adev)
255770b93e9SHawking Zhang {
256770b93e9SHawking Zhang 	uint32_t tmp;
257770b93e9SHawking Zhang 
258770b93e9SHawking Zhang 	tmp = RREG32_SOC15(GC, 0, mmGCVM_CONTEXT0_CNTL);
259770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
260770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
2617cae7061SFelix Kuehling 	tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL,
2627cae7061SFelix Kuehling 			    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
263770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_CONTEXT0_CNTL, tmp);
264770b93e9SHawking Zhang }
265770b93e9SHawking Zhang 
gfxhub_v2_0_disable_identity_aperture(struct amdgpu_device * adev)266770b93e9SHawking Zhang static void gfxhub_v2_0_disable_identity_aperture(struct amdgpu_device *adev)
267770b93e9SHawking Zhang {
268770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32,
269770b93e9SHawking Zhang 		     0xFFFFFFFF);
270770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32,
271770b93e9SHawking Zhang 		     0x0000000F);
272770b93e9SHawking Zhang 
273770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32,
274770b93e9SHawking Zhang 		     0);
275770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32,
276770b93e9SHawking Zhang 		     0);
277770b93e9SHawking Zhang 
278770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32, 0);
279770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32, 0);
280770b93e9SHawking Zhang 
281770b93e9SHawking Zhang }
282770b93e9SHawking Zhang 
gfxhub_v2_0_setup_vmid_config(struct amdgpu_device * adev)283770b93e9SHawking Zhang static void gfxhub_v2_0_setup_vmid_config(struct amdgpu_device *adev)
284770b93e9SHawking Zhang {
285f4caf584SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
286770b93e9SHawking Zhang 	int i;
287770b93e9SHawking Zhang 	uint32_t tmp;
288770b93e9SHawking Zhang 
289770b93e9SHawking Zhang 	for (i = 0; i <= 14; i++) {
290770b93e9SHawking Zhang 		tmp = RREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_CNTL, i);
291770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
292770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
293770b93e9SHawking Zhang 				    adev->vm_manager.num_level);
294770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
295770b93e9SHawking Zhang 				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
296770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
297770b93e9SHawking Zhang 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
298770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
299770b93e9SHawking Zhang 				PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
300770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
301770b93e9SHawking Zhang 				VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
302770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
303770b93e9SHawking Zhang 				READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
304770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
305770b93e9SHawking Zhang 				WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
306770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
307770b93e9SHawking Zhang 				EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
308770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
309770b93e9SHawking Zhang 				PAGE_TABLE_BLOCK_SIZE,
310770b93e9SHawking Zhang 				adev->vm_manager.block_size - 9);
311770b93e9SHawking Zhang 		/* Send no-retry XNACK on fault to suppress VM fault storm. */
312770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT1_CNTL,
31375ee6487SFelix Kuehling 				    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
3149b498efaSAlex Deucher 				    !adev->gmc.noretry);
3151e40eebeSHuang Rui 		WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_CNTL,
3161e40eebeSHuang Rui 				    i * hub->ctx_distance, tmp);
3171e40eebeSHuang Rui 		WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
3181e40eebeSHuang Rui 				    i * hub->ctx_addr_distance, 0);
3191e40eebeSHuang Rui 		WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
3201e40eebeSHuang Rui 				    i * hub->ctx_addr_distance, 0);
3211e40eebeSHuang Rui 		WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
3221e40eebeSHuang Rui 				    i * hub->ctx_addr_distance,
323770b93e9SHawking Zhang 				    lower_32_bits(adev->vm_manager.max_pfn - 1));
3241e40eebeSHuang Rui 		WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
3251e40eebeSHuang Rui 				    i * hub->ctx_addr_distance,
326770b93e9SHawking Zhang 				    upper_32_bits(adev->vm_manager.max_pfn - 1));
327770b93e9SHawking Zhang 	}
328d7dab4fcSJack Xiao 
329d7dab4fcSJack Xiao 	hub->vm_cntx_cntl = tmp;
330770b93e9SHawking Zhang }
331770b93e9SHawking Zhang 
gfxhub_v2_0_program_invalidation(struct amdgpu_device * adev)332770b93e9SHawking Zhang static void gfxhub_v2_0_program_invalidation(struct amdgpu_device *adev)
333770b93e9SHawking Zhang {
334f4caf584SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
335*0e2b8507SSrinivasan Shanmugam 	unsigned int i;
336770b93e9SHawking Zhang 
337770b93e9SHawking Zhang 	for (i = 0 ; i < 18; ++i) {
338770b93e9SHawking Zhang 		WREG32_SOC15_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32,
3391e40eebeSHuang Rui 				    i * hub->eng_addr_distance, 0xffffffff);
340770b93e9SHawking Zhang 		WREG32_SOC15_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_ADDR_RANGE_HI32,
3411e40eebeSHuang Rui 				    i * hub->eng_addr_distance, 0x1f);
342770b93e9SHawking Zhang 	}
343770b93e9SHawking Zhang }
344770b93e9SHawking Zhang 
gfxhub_v2_0_gart_enable(struct amdgpu_device * adev)3458ffff9b4SOak Zeng static int gfxhub_v2_0_gart_enable(struct amdgpu_device *adev)
346770b93e9SHawking Zhang {
347770b93e9SHawking Zhang 	/* GART Enable. */
348770b93e9SHawking Zhang 	gfxhub_v2_0_init_gart_aperture_regs(adev);
349770b93e9SHawking Zhang 	gfxhub_v2_0_init_system_aperture_regs(adev);
350770b93e9SHawking Zhang 	gfxhub_v2_0_init_tlb_regs(adev);
351770b93e9SHawking Zhang 	gfxhub_v2_0_init_cache_regs(adev);
352770b93e9SHawking Zhang 
353770b93e9SHawking Zhang 	gfxhub_v2_0_enable_system_domain(adev);
354770b93e9SHawking Zhang 	gfxhub_v2_0_disable_identity_aperture(adev);
355770b93e9SHawking Zhang 	gfxhub_v2_0_setup_vmid_config(adev);
356770b93e9SHawking Zhang 	gfxhub_v2_0_program_invalidation(adev);
357770b93e9SHawking Zhang 
358770b93e9SHawking Zhang 	return 0;
359770b93e9SHawking Zhang }
360770b93e9SHawking Zhang 
gfxhub_v2_0_gart_disable(struct amdgpu_device * adev)3618ffff9b4SOak Zeng static void gfxhub_v2_0_gart_disable(struct amdgpu_device *adev)
362770b93e9SHawking Zhang {
363f4caf584SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
364770b93e9SHawking Zhang 	u32 tmp;
365770b93e9SHawking Zhang 	u32 i;
366770b93e9SHawking Zhang 
367770b93e9SHawking Zhang 	/* Disable all tables */
368770b93e9SHawking Zhang 	for (i = 0; i < 16; i++)
3691e40eebeSHuang Rui 		WREG32_SOC15_OFFSET(GC, 0, mmGCVM_CONTEXT0_CNTL,
3701e40eebeSHuang Rui 				    i * hub->ctx_distance, 0);
371770b93e9SHawking Zhang 
372770b93e9SHawking Zhang 	/* Setup TLB control */
373770b93e9SHawking Zhang 	tmp = RREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL);
374770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0);
375770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCMC_VM_MX_L1_TLB_CNTL,
376770b93e9SHawking Zhang 			    ENABLE_ADVANCED_DRIVER_MODEL, 0);
377770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCMC_VM_MX_L1_TLB_CNTL, tmp);
378770b93e9SHawking Zhang 
37975ddb640SRohit Khaire 	if (!amdgpu_sriov_vf(adev)) {
380770b93e9SHawking Zhang 		/* Setup L2 cache */
381770b93e9SHawking Zhang 		WREG32_FIELD15(GC, 0, GCVM_L2_CNTL, ENABLE_L2_CACHE, 0);
382770b93e9SHawking Zhang 		WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL3, 0);
383770b93e9SHawking Zhang 	}
38475ddb640SRohit Khaire }
385770b93e9SHawking Zhang 
386770b93e9SHawking Zhang /**
387770b93e9SHawking Zhang  * gfxhub_v2_0_set_fault_enable_default - update GART/VM fault handling
388770b93e9SHawking Zhang  *
389770b93e9SHawking Zhang  * @adev: amdgpu_device pointer
390770b93e9SHawking Zhang  * @value: true redirects VM faults to the default page
391770b93e9SHawking Zhang  */
gfxhub_v2_0_set_fault_enable_default(struct amdgpu_device * adev,bool value)3928ffff9b4SOak Zeng static void gfxhub_v2_0_set_fault_enable_default(struct amdgpu_device *adev,
393770b93e9SHawking Zhang 					  bool value)
394770b93e9SHawking Zhang {
395770b93e9SHawking Zhang 	u32 tmp;
396*0e2b8507SSrinivasan Shanmugam 
397770b93e9SHawking Zhang 	tmp = RREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL);
398770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
399770b93e9SHawking Zhang 			    RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
400770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
401770b93e9SHawking Zhang 			    PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value);
402770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
403770b93e9SHawking Zhang 			    PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value);
404770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
405770b93e9SHawking Zhang 			    PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value);
406770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
407770b93e9SHawking Zhang 			    TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT,
408770b93e9SHawking Zhang 			    value);
409770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
410770b93e9SHawking Zhang 			    NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value);
411770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
412770b93e9SHawking Zhang 			    DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
413770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
414770b93e9SHawking Zhang 			    VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value);
415770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
416770b93e9SHawking Zhang 			    READ_PROTECTION_FAULT_ENABLE_DEFAULT, value);
417770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
418770b93e9SHawking Zhang 			    WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
419770b93e9SHawking Zhang 	tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
420770b93e9SHawking Zhang 			    EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
421770b93e9SHawking Zhang 	if (!value) {
422770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
423770b93e9SHawking Zhang 				CRASH_ON_NO_RETRY_FAULT, 1);
424770b93e9SHawking Zhang 		tmp = REG_SET_FIELD(tmp, GCVM_L2_PROTECTION_FAULT_CNTL,
425770b93e9SHawking Zhang 				CRASH_ON_RETRY_FAULT, 1);
426770b93e9SHawking Zhang 	}
427770b93e9SHawking Zhang 	WREG32_SOC15(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL, tmp);
428770b93e9SHawking Zhang }
429770b93e9SHawking Zhang 
4302577db91SHuang Rui static const struct amdgpu_vmhub_funcs gfxhub_v2_0_vmhub_funcs = {
4312577db91SHuang Rui 	.print_l2_protection_fault_status = gfxhub_v2_0_print_l2_protection_fault_status,
432caa9f483SHuang Rui 	.get_invalidate_req = gfxhub_v2_0_get_invalidate_req,
4332577db91SHuang Rui };
4342577db91SHuang Rui 
gfxhub_v2_0_init(struct amdgpu_device * adev)4358ffff9b4SOak Zeng static void gfxhub_v2_0_init(struct amdgpu_device *adev)
436770b93e9SHawking Zhang {
437f4caf584SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
438770b93e9SHawking Zhang 
439770b93e9SHawking Zhang 	hub->ctx0_ptb_addr_lo32 =
440770b93e9SHawking Zhang 		SOC15_REG_OFFSET(GC, 0,
441770b93e9SHawking Zhang 				 mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32);
442770b93e9SHawking Zhang 	hub->ctx0_ptb_addr_hi32 =
443770b93e9SHawking Zhang 		SOC15_REG_OFFSET(GC, 0,
444770b93e9SHawking Zhang 				 mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32);
4456c2c8972Schangzhu 	hub->vm_inv_eng0_sem =
4466c2c8972Schangzhu 		SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_SEM);
447770b93e9SHawking Zhang 	hub->vm_inv_eng0_req =
448770b93e9SHawking Zhang 		SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_REQ);
449770b93e9SHawking Zhang 	hub->vm_inv_eng0_ack =
450770b93e9SHawking Zhang 		SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_ACK);
451770b93e9SHawking Zhang 	hub->vm_context0_cntl =
452770b93e9SHawking Zhang 		SOC15_REG_OFFSET(GC, 0, mmGCVM_CONTEXT0_CNTL);
453770b93e9SHawking Zhang 	hub->vm_l2_pro_fault_status =
454770b93e9SHawking Zhang 		SOC15_REG_OFFSET(GC, 0, mmGCVM_L2_PROTECTION_FAULT_STATUS);
455770b93e9SHawking Zhang 	hub->vm_l2_pro_fault_cntl =
456770b93e9SHawking Zhang 		SOC15_REG_OFFSET(GC, 0, mmGCVM_L2_PROTECTION_FAULT_CNTL);
4571f9d56c3SHuang Rui 
4581f9d56c3SHuang Rui 	hub->ctx_distance = mmGCVM_CONTEXT1_CNTL - mmGCVM_CONTEXT0_CNTL;
4591f9d56c3SHuang Rui 	hub->ctx_addr_distance = mmGCVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 -
4601f9d56c3SHuang Rui 		mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
4611f9d56c3SHuang Rui 	hub->eng_distance = mmGCVM_INVALIDATE_ENG1_REQ -
4621f9d56c3SHuang Rui 		mmGCVM_INVALIDATE_ENG0_REQ;
4631f9d56c3SHuang Rui 	hub->eng_addr_distance = mmGCVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 -
4641f9d56c3SHuang Rui 		mmGCVM_INVALIDATE_ENG0_ADDR_RANGE_LO32;
4655befb6fcSHuang Rui 
4665befb6fcSHuang Rui 	hub->vm_cntx_cntl_vm_fault = GCVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
4675befb6fcSHuang Rui 		GCVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
4685befb6fcSHuang Rui 		GCVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
4695befb6fcSHuang Rui 		GCVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
4705befb6fcSHuang Rui 		GCVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
4715befb6fcSHuang Rui 		GCVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
4725befb6fcSHuang Rui 		GCVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
4732577db91SHuang Rui 
4742577db91SHuang Rui 	hub->vmhub_funcs = &gfxhub_v2_0_vmhub_funcs;
475770b93e9SHawking Zhang }
4768ffff9b4SOak Zeng 
4778ffff9b4SOak Zeng const struct amdgpu_gfxhub_funcs gfxhub_v2_0_funcs = {
4788ffff9b4SOak Zeng 	.get_fb_location = gfxhub_v2_0_get_fb_location,
4798ffff9b4SOak Zeng 	.get_mc_fb_offset = gfxhub_v2_0_get_mc_fb_offset,
4808ffff9b4SOak Zeng 	.setup_vm_pt_regs = gfxhub_v2_0_setup_vm_pt_regs,
4818ffff9b4SOak Zeng 	.gart_enable = gfxhub_v2_0_gart_enable,
4828ffff9b4SOak Zeng 	.gart_disable = gfxhub_v2_0_gart_disable,
4838ffff9b4SOak Zeng 	.set_fault_enable_default = gfxhub_v2_0_set_fault_enable_default,
4848ffff9b4SOak Zeng 	.init = gfxhub_v2_0_init,
4858ffff9b4SOak Zeng };
486