1*98a0f868STianci.Yin /*
2*98a0f868STianci.Yin  * Copyright 2021 Advanced Micro Devices, Inc.
3*98a0f868STianci.Yin  *
4*98a0f868STianci.Yin  * Permission is hereby granted, free of charge, to any person obtaining a
5*98a0f868STianci.Yin  * copy of this software and associated documentation files (the "Software"),
6*98a0f868STianci.Yin  * to deal in the Software without restriction, including without limitation
7*98a0f868STianci.Yin  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*98a0f868STianci.Yin  * and/or sell copies of the Software, and to permit persons to whom the
9*98a0f868STianci.Yin  * Software is furnished to do so, subject to the following conditions:
10*98a0f868STianci.Yin  *
11*98a0f868STianci.Yin  * The above copyright notice and this permission notice shall be included in
12*98a0f868STianci.Yin  * all copies or substantial portions of the Software.
13*98a0f868STianci.Yin  *
14*98a0f868STianci.Yin  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*98a0f868STianci.Yin  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*98a0f868STianci.Yin  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*98a0f868STianci.Yin  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*98a0f868STianci.Yin  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*98a0f868STianci.Yin  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*98a0f868STianci.Yin  * OTHER DEALINGS IN THE SOFTWARE.
21*98a0f868STianci.Yin  *
22*98a0f868STianci.Yin  */
23*98a0f868STianci.Yin 
24*98a0f868STianci.Yin #include "amdgpu.h"
25*98a0f868STianci.Yin #include "mmhub_v3_0.h"
26*98a0f868STianci.Yin 
27*98a0f868STianci.Yin #include "mmhub/mmhub_3_0_0_offset.h"
28*98a0f868STianci.Yin #include "mmhub/mmhub_3_0_0_sh_mask.h"
29*98a0f868STianci.Yin #include "navi10_enum.h"
30*98a0f868STianci.Yin 
31*98a0f868STianci.Yin #include "soc15_common.h"
32*98a0f868STianci.Yin 
33*98a0f868STianci.Yin #define regMMVM_L2_CNTL3_DEFAULT				0x80100007
34*98a0f868STianci.Yin #define regMMVM_L2_CNTL4_DEFAULT				0x000000c1
35*98a0f868STianci.Yin #define regMMVM_L2_CNTL5_DEFAULT				0x00003fe0
36*98a0f868STianci.Yin 
37*98a0f868STianci.Yin static const char *mmhub_client_ids_v3_0_0[][2] = {
38*98a0f868STianci.Yin 	[0][0] = "VMC",
39*98a0f868STianci.Yin 	[4][0] = "DCEDMC",
40*98a0f868STianci.Yin 	[5][0] = "DCEVGA",
41*98a0f868STianci.Yin 	[6][0] = "MP0",
42*98a0f868STianci.Yin 	[7][0] = "MP1",
43*98a0f868STianci.Yin 	[8][0] = "MPIO",
44*98a0f868STianci.Yin 	[16][0] = "HDP",
45*98a0f868STianci.Yin 	[17][0] = "LSDMA",
46*98a0f868STianci.Yin 	[18][0] = "JPEG",
47*98a0f868STianci.Yin 	[19][0] = "VCNU0",
48*98a0f868STianci.Yin 	[21][0] = "VSCH",
49*98a0f868STianci.Yin 	[22][0] = "VCNU1",
50*98a0f868STianci.Yin 	[23][0] = "VCN1",
51*98a0f868STianci.Yin 	[32+20][0] = "VCN0",
52*98a0f868STianci.Yin 	[2][1] = "DBGUNBIO",
53*98a0f868STianci.Yin 	[3][1] = "DCEDWB",
54*98a0f868STianci.Yin 	[4][1] = "DCEDMC",
55*98a0f868STianci.Yin 	[5][1] = "DCEVGA",
56*98a0f868STianci.Yin 	[6][1] = "MP0",
57*98a0f868STianci.Yin 	[7][1] = "MP1",
58*98a0f868STianci.Yin 	[8][1] = "MPIO",
59*98a0f868STianci.Yin 	[10][1] = "DBGU0",
60*98a0f868STianci.Yin 	[11][1] = "DBGU1",
61*98a0f868STianci.Yin 	[12][1] = "DBGU2",
62*98a0f868STianci.Yin 	[13][1] = "DBGU3",
63*98a0f868STianci.Yin 	[14][1] = "XDP",
64*98a0f868STianci.Yin 	[15][1] = "OSSSYS",
65*98a0f868STianci.Yin 	[16][1] = "HDP",
66*98a0f868STianci.Yin 	[17][1] = "LSDMA",
67*98a0f868STianci.Yin 	[18][1] = "JPEG",
68*98a0f868STianci.Yin 	[19][1] = "VCNU0",
69*98a0f868STianci.Yin 	[20][1] = "VCN0",
70*98a0f868STianci.Yin 	[21][1] = "VSCH",
71*98a0f868STianci.Yin 	[22][1] = "VCNU1",
72*98a0f868STianci.Yin 	[23][1] = "VCN1",
73*98a0f868STianci.Yin };
74*98a0f868STianci.Yin 
75*98a0f868STianci.Yin static uint32_t mmhub_v3_0_get_invalidate_req(unsigned int vmid,
76*98a0f868STianci.Yin 					      uint32_t flush_type)
77*98a0f868STianci.Yin {
78*98a0f868STianci.Yin 	u32 req = 0;
79*98a0f868STianci.Yin 
80*98a0f868STianci.Yin 	/* invalidate using legacy mode on vmid*/
81*98a0f868STianci.Yin 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ,
82*98a0f868STianci.Yin 			    PER_VMID_INVALIDATE_REQ, 1 << vmid);
83*98a0f868STianci.Yin 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type);
84*98a0f868STianci.Yin 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
85*98a0f868STianci.Yin 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
86*98a0f868STianci.Yin 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1);
87*98a0f868STianci.Yin 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1);
88*98a0f868STianci.Yin 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1);
89*98a0f868STianci.Yin 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ,
90*98a0f868STianci.Yin 			    CLEAR_PROTECTION_FAULT_STATUS_ADDR,	0);
91*98a0f868STianci.Yin 
92*98a0f868STianci.Yin 	return req;
93*98a0f868STianci.Yin }
94*98a0f868STianci.Yin 
95*98a0f868STianci.Yin static void
96*98a0f868STianci.Yin mmhub_v3_0_print_l2_protection_fault_status(struct amdgpu_device *adev,
97*98a0f868STianci.Yin 					     uint32_t status)
98*98a0f868STianci.Yin {
99*98a0f868STianci.Yin 	uint32_t cid, rw;
100*98a0f868STianci.Yin 	const char *mmhub_cid = NULL;
101*98a0f868STianci.Yin 
102*98a0f868STianci.Yin 	cid = REG_GET_FIELD(status,
103*98a0f868STianci.Yin 			    MMVM_L2_PROTECTION_FAULT_STATUS, CID);
104*98a0f868STianci.Yin 	rw = REG_GET_FIELD(status,
105*98a0f868STianci.Yin 			   MMVM_L2_PROTECTION_FAULT_STATUS, RW);
106*98a0f868STianci.Yin 
107*98a0f868STianci.Yin 	dev_err(adev->dev,
108*98a0f868STianci.Yin 		"MMVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n",
109*98a0f868STianci.Yin 		status);
110*98a0f868STianci.Yin 	switch (adev->ip_versions[MMHUB_HWIP][0]) {
111*98a0f868STianci.Yin 	case IP_VERSION(3, 0, 0):
112*98a0f868STianci.Yin 		mmhub_cid = mmhub_client_ids_v3_0_0[cid][rw];
113*98a0f868STianci.Yin 		break;
114*98a0f868STianci.Yin 	default:
115*98a0f868STianci.Yin 		mmhub_cid = NULL;
116*98a0f868STianci.Yin 		break;
117*98a0f868STianci.Yin 	}
118*98a0f868STianci.Yin 	dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
119*98a0f868STianci.Yin 		mmhub_cid ? mmhub_cid : "unknown", cid);
120*98a0f868STianci.Yin 	dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
121*98a0f868STianci.Yin 		REG_GET_FIELD(status,
122*98a0f868STianci.Yin 		MMVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS));
123*98a0f868STianci.Yin 	dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
124*98a0f868STianci.Yin 		REG_GET_FIELD(status,
125*98a0f868STianci.Yin 		MMVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR));
126*98a0f868STianci.Yin 	dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
127*98a0f868STianci.Yin 		REG_GET_FIELD(status,
128*98a0f868STianci.Yin 		MMVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS));
129*98a0f868STianci.Yin 	dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
130*98a0f868STianci.Yin 		REG_GET_FIELD(status,
131*98a0f868STianci.Yin 		MMVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR));
132*98a0f868STianci.Yin 	dev_err(adev->dev, "\t RW: 0x%x\n", rw);
133*98a0f868STianci.Yin }
134*98a0f868STianci.Yin 
135*98a0f868STianci.Yin static void mmhub_v3_0_setup_vm_pt_regs(struct amdgpu_device *adev, uint32_t vmid,
136*98a0f868STianci.Yin 				uint64_t page_table_base)
137*98a0f868STianci.Yin {
138*98a0f868STianci.Yin 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
139*98a0f868STianci.Yin 
140*98a0f868STianci.Yin 	WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
141*98a0f868STianci.Yin 			    hub->ctx_addr_distance * vmid,
142*98a0f868STianci.Yin 			    lower_32_bits(page_table_base));
143*98a0f868STianci.Yin 
144*98a0f868STianci.Yin 	WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
145*98a0f868STianci.Yin 			    hub->ctx_addr_distance * vmid,
146*98a0f868STianci.Yin 			    upper_32_bits(page_table_base));
147*98a0f868STianci.Yin }
148*98a0f868STianci.Yin 
149*98a0f868STianci.Yin static void mmhub_v3_0_init_gart_aperture_regs(struct amdgpu_device *adev)
150*98a0f868STianci.Yin {
151*98a0f868STianci.Yin 	uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
152*98a0f868STianci.Yin 
153*98a0f868STianci.Yin 	mmhub_v3_0_setup_vm_pt_regs(adev, 0, pt_base);
154*98a0f868STianci.Yin 
155*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
156*98a0f868STianci.Yin 		     (u32)(adev->gmc.gart_start >> 12));
157*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
158*98a0f868STianci.Yin 		     (u32)(adev->gmc.gart_start >> 44));
159*98a0f868STianci.Yin 
160*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
161*98a0f868STianci.Yin 		     (u32)(adev->gmc.gart_end >> 12));
162*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
163*98a0f868STianci.Yin 		     (u32)(adev->gmc.gart_end >> 44));
164*98a0f868STianci.Yin }
165*98a0f868STianci.Yin 
166*98a0f868STianci.Yin static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
167*98a0f868STianci.Yin {
168*98a0f868STianci.Yin 	uint64_t value;
169*98a0f868STianci.Yin 	uint32_t tmp;
170*98a0f868STianci.Yin 
171*98a0f868STianci.Yin 	/* Disable AGP. */
172*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
173*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
174*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
175*98a0f868STianci.Yin 
176*98a0f868STianci.Yin 	if (!amdgpu_sriov_vf(adev)) {
177*98a0f868STianci.Yin 		/*
178*98a0f868STianci.Yin 		 * the new L1 policy will block SRIOV guest from writing
179*98a0f868STianci.Yin 		 * these regs, and they will be programed at host.
180*98a0f868STianci.Yin 		 * so skip programing these regs.
181*98a0f868STianci.Yin 		 */
182*98a0f868STianci.Yin 		/* Program the system aperture low logical page number. */
183*98a0f868STianci.Yin 		WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
184*98a0f868STianci.Yin 			     adev->gmc.vram_start >> 18);
185*98a0f868STianci.Yin 		WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
186*98a0f868STianci.Yin 			     adev->gmc.vram_end >> 18);
187*98a0f868STianci.Yin 	}
188*98a0f868STianci.Yin 
189*98a0f868STianci.Yin 	/* Set default page address. */
190*98a0f868STianci.Yin 	value = adev->vram_scratch.gpu_addr - adev->gmc.vram_start +
191*98a0f868STianci.Yin 		adev->vm_manager.vram_base_offset;
192*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
193*98a0f868STianci.Yin 		     (u32)(value >> 12));
194*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
195*98a0f868STianci.Yin 		     (u32)(value >> 44));
196*98a0f868STianci.Yin 
197*98a0f868STianci.Yin 	/* Program "protection fault". */
198*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
199*98a0f868STianci.Yin 		     (u32)(adev->dummy_page_addr >> 12));
200*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
201*98a0f868STianci.Yin 		     (u32)((u64)adev->dummy_page_addr >> 44));
202*98a0f868STianci.Yin 
203*98a0f868STianci.Yin 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL2);
204*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL2,
205*98a0f868STianci.Yin 			    ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1);
206*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL2, tmp);
207*98a0f868STianci.Yin }
208*98a0f868STianci.Yin 
209*98a0f868STianci.Yin static void mmhub_v3_0_init_tlb_regs(struct amdgpu_device *adev)
210*98a0f868STianci.Yin {
211*98a0f868STianci.Yin 	uint32_t tmp;
212*98a0f868STianci.Yin 
213*98a0f868STianci.Yin 	/* Setup TLB control */
214*98a0f868STianci.Yin 	tmp = RREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL);
215*98a0f868STianci.Yin 
216*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
217*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3);
218*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
219*98a0f868STianci.Yin 			    ENABLE_ADVANCED_DRIVER_MODEL, 1);
220*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
221*98a0f868STianci.Yin 			    SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
222*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
223*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
224*98a0f868STianci.Yin 			    MTYPE, MTYPE_UC); /* UC, uncached */
225*98a0f868STianci.Yin 
226*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL, tmp);
227*98a0f868STianci.Yin }
228*98a0f868STianci.Yin 
229*98a0f868STianci.Yin static void mmhub_v3_0_init_cache_regs(struct amdgpu_device *adev)
230*98a0f868STianci.Yin {
231*98a0f868STianci.Yin 	uint32_t tmp;
232*98a0f868STianci.Yin 
233*98a0f868STianci.Yin 	/* These registers are not accessible to VF-SRIOV.
234*98a0f868STianci.Yin 	 * The PF will program them instead.
235*98a0f868STianci.Yin 	 */
236*98a0f868STianci.Yin 	if (amdgpu_sriov_vf(adev))
237*98a0f868STianci.Yin 		return;
238*98a0f868STianci.Yin 
239*98a0f868STianci.Yin 	/* Setup L2 cache */
240*98a0f868STianci.Yin 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL);
241*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 1);
242*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
243*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL,
244*98a0f868STianci.Yin 			    ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1);
245*98a0f868STianci.Yin 	/* XXX for emulation, Refer to closed source code.*/
246*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE,
247*98a0f868STianci.Yin 			    0);
248*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
249*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
250*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
251*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL, tmp);
252*98a0f868STianci.Yin 
253*98a0f868STianci.Yin 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL2);
254*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
255*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
256*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL2, tmp);
257*98a0f868STianci.Yin 
258*98a0f868STianci.Yin 	tmp = regMMVM_L2_CNTL3_DEFAULT;
259*98a0f868STianci.Yin 	if (adev->gmc.translate_further) {
260*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 12);
261*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
262*98a0f868STianci.Yin 				    L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
263*98a0f868STianci.Yin 	} else {
264*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 9);
265*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
266*98a0f868STianci.Yin 				    L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
267*98a0f868STianci.Yin 	}
268*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL3, tmp);
269*98a0f868STianci.Yin 
270*98a0f868STianci.Yin 	tmp = regMMVM_L2_CNTL4_DEFAULT;
271*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
272*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0);
273*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL4, tmp);
274*98a0f868STianci.Yin 
275*98a0f868STianci.Yin 	tmp = regMMVM_L2_CNTL5_DEFAULT;
276*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
277*98a0f868STianci.Yin 	WREG32_SOC15(GC, 0, regMMVM_L2_CNTL5, tmp);
278*98a0f868STianci.Yin }
279*98a0f868STianci.Yin 
280*98a0f868STianci.Yin static void mmhub_v3_0_enable_system_domain(struct amdgpu_device *adev)
281*98a0f868STianci.Yin {
282*98a0f868STianci.Yin 	uint32_t tmp;
283*98a0f868STianci.Yin 
284*98a0f868STianci.Yin 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_CNTL);
285*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
286*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
287*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL,
288*98a0f868STianci.Yin 			    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
289*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_CNTL, tmp);
290*98a0f868STianci.Yin }
291*98a0f868STianci.Yin 
292*98a0f868STianci.Yin static void mmhub_v3_0_disable_identity_aperture(struct amdgpu_device *adev)
293*98a0f868STianci.Yin {
294*98a0f868STianci.Yin 	/* These registers are not accessible to VF-SRIOV.
295*98a0f868STianci.Yin 	 * The PF will program them instead.
296*98a0f868STianci.Yin 	 */
297*98a0f868STianci.Yin 	if (amdgpu_sriov_vf(adev))
298*98a0f868STianci.Yin 		return;
299*98a0f868STianci.Yin 
300*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0,
301*98a0f868STianci.Yin 		     regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32,
302*98a0f868STianci.Yin 		     0xFFFFFFFF);
303*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0,
304*98a0f868STianci.Yin 		     regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32,
305*98a0f868STianci.Yin 		     0x0000000F);
306*98a0f868STianci.Yin 
307*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0,
308*98a0f868STianci.Yin 		     regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32, 0);
309*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0,
310*98a0f868STianci.Yin 		     regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32, 0);
311*98a0f868STianci.Yin 
312*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32,
313*98a0f868STianci.Yin 		     0);
314*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32,
315*98a0f868STianci.Yin 		     0);
316*98a0f868STianci.Yin }
317*98a0f868STianci.Yin 
318*98a0f868STianci.Yin static void mmhub_v3_0_setup_vmid_config(struct amdgpu_device *adev)
319*98a0f868STianci.Yin {
320*98a0f868STianci.Yin 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
321*98a0f868STianci.Yin 	int i;
322*98a0f868STianci.Yin 	uint32_t tmp;
323*98a0f868STianci.Yin 
324*98a0f868STianci.Yin 	for (i = 0; i <= 14; i++) {
325*98a0f868STianci.Yin 		tmp = RREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_CNTL, i);
326*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
327*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
328*98a0f868STianci.Yin 				    adev->vm_manager.num_level);
329*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
330*98a0f868STianci.Yin 				    RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
331*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
332*98a0f868STianci.Yin 				    DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT,
333*98a0f868STianci.Yin 				    1);
334*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
335*98a0f868STianci.Yin 				    PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
336*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
337*98a0f868STianci.Yin 				    VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
338*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
339*98a0f868STianci.Yin 				    READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
340*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
341*98a0f868STianci.Yin 				    WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
342*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
343*98a0f868STianci.Yin 				    EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
344*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
345*98a0f868STianci.Yin 				    PAGE_TABLE_BLOCK_SIZE,
346*98a0f868STianci.Yin 				    adev->vm_manager.block_size - 9);
347*98a0f868STianci.Yin 		/* Send no-retry XNACK on fault to suppress VM fault storm. */
348*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
349*98a0f868STianci.Yin 				    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
350*98a0f868STianci.Yin 				    !amdgpu_noretry);
351*98a0f868STianci.Yin 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_CNTL,
352*98a0f868STianci.Yin 				    i * hub->ctx_distance, tmp);
353*98a0f868STianci.Yin 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
354*98a0f868STianci.Yin 				    i * hub->ctx_addr_distance, 0);
355*98a0f868STianci.Yin 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
356*98a0f868STianci.Yin 				    i * hub->ctx_addr_distance, 0);
357*98a0f868STianci.Yin 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
358*98a0f868STianci.Yin 				    i * hub->ctx_addr_distance,
359*98a0f868STianci.Yin 				    lower_32_bits(adev->vm_manager.max_pfn - 1));
360*98a0f868STianci.Yin 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
361*98a0f868STianci.Yin 				    i * hub->ctx_addr_distance,
362*98a0f868STianci.Yin 				    upper_32_bits(adev->vm_manager.max_pfn - 1));
363*98a0f868STianci.Yin 	}
364*98a0f868STianci.Yin }
365*98a0f868STianci.Yin 
366*98a0f868STianci.Yin static void mmhub_v3_0_program_invalidation(struct amdgpu_device *adev)
367*98a0f868STianci.Yin {
368*98a0f868STianci.Yin 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
369*98a0f868STianci.Yin 	unsigned i;
370*98a0f868STianci.Yin 
371*98a0f868STianci.Yin 	for (i = 0; i < 18; ++i) {
372*98a0f868STianci.Yin 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32,
373*98a0f868STianci.Yin 				    i * hub->eng_addr_distance, 0xffffffff);
374*98a0f868STianci.Yin 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ADDR_RANGE_HI32,
375*98a0f868STianci.Yin 				    i * hub->eng_addr_distance, 0x1f);
376*98a0f868STianci.Yin 	}
377*98a0f868STianci.Yin }
378*98a0f868STianci.Yin 
379*98a0f868STianci.Yin static int mmhub_v3_0_gart_enable(struct amdgpu_device *adev)
380*98a0f868STianci.Yin {
381*98a0f868STianci.Yin 	/* GART Enable. */
382*98a0f868STianci.Yin 	mmhub_v3_0_init_gart_aperture_regs(adev);
383*98a0f868STianci.Yin 	mmhub_v3_0_init_system_aperture_regs(adev);
384*98a0f868STianci.Yin 	mmhub_v3_0_init_tlb_regs(adev);
385*98a0f868STianci.Yin 	mmhub_v3_0_init_cache_regs(adev);
386*98a0f868STianci.Yin 
387*98a0f868STianci.Yin 	mmhub_v3_0_enable_system_domain(adev);
388*98a0f868STianci.Yin 	mmhub_v3_0_disable_identity_aperture(adev);
389*98a0f868STianci.Yin 	mmhub_v3_0_setup_vmid_config(adev);
390*98a0f868STianci.Yin 	mmhub_v3_0_program_invalidation(adev);
391*98a0f868STianci.Yin 
392*98a0f868STianci.Yin 	return 0;
393*98a0f868STianci.Yin }
394*98a0f868STianci.Yin 
395*98a0f868STianci.Yin static void mmhub_v3_0_gart_disable(struct amdgpu_device *adev)
396*98a0f868STianci.Yin {
397*98a0f868STianci.Yin 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
398*98a0f868STianci.Yin 	u32 tmp;
399*98a0f868STianci.Yin 	u32 i;
400*98a0f868STianci.Yin 
401*98a0f868STianci.Yin 	/* Disable all tables */
402*98a0f868STianci.Yin 	for (i = 0; i < 16; i++)
403*98a0f868STianci.Yin 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_CNTL,
404*98a0f868STianci.Yin 				    i * hub->ctx_distance, 0);
405*98a0f868STianci.Yin 
406*98a0f868STianci.Yin 	/* Setup TLB control */
407*98a0f868STianci.Yin 	tmp = RREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL);
408*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0);
409*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
410*98a0f868STianci.Yin 			    ENABLE_ADVANCED_DRIVER_MODEL, 0);
411*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL, tmp);
412*98a0f868STianci.Yin 
413*98a0f868STianci.Yin 	/* Setup L2 cache */
414*98a0f868STianci.Yin 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL);
415*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 0);
416*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL, tmp);
417*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL3, 0);
418*98a0f868STianci.Yin }
419*98a0f868STianci.Yin 
420*98a0f868STianci.Yin /**
421*98a0f868STianci.Yin  * mmhub_v3_0_set_fault_enable_default - update GART/VM fault handling
422*98a0f868STianci.Yin  *
423*98a0f868STianci.Yin  * @adev: amdgpu_device pointer
424*98a0f868STianci.Yin  * @value: true redirects VM faults to the default page
425*98a0f868STianci.Yin  */
426*98a0f868STianci.Yin static void mmhub_v3_0_set_fault_enable_default(struct amdgpu_device *adev, bool value)
427*98a0f868STianci.Yin {
428*98a0f868STianci.Yin 	u32 tmp;
429*98a0f868STianci.Yin 
430*98a0f868STianci.Yin 	/* These registers are not accessible to VF-SRIOV.
431*98a0f868STianci.Yin 	 * The PF will program them instead.
432*98a0f868STianci.Yin 	 */
433*98a0f868STianci.Yin 	if (amdgpu_sriov_vf(adev))
434*98a0f868STianci.Yin 		return;
435*98a0f868STianci.Yin 
436*98a0f868STianci.Yin 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL);
437*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
438*98a0f868STianci.Yin 			    RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
439*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
440*98a0f868STianci.Yin 			    PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value);
441*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
442*98a0f868STianci.Yin 			    PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value);
443*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
444*98a0f868STianci.Yin 			    PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value);
445*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
446*98a0f868STianci.Yin 			    TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT,
447*98a0f868STianci.Yin 			    value);
448*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
449*98a0f868STianci.Yin 			    NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value);
450*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
451*98a0f868STianci.Yin 			    DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
452*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
453*98a0f868STianci.Yin 			    VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value);
454*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
455*98a0f868STianci.Yin 			    READ_PROTECTION_FAULT_ENABLE_DEFAULT, value);
456*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
457*98a0f868STianci.Yin 			    WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
458*98a0f868STianci.Yin 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
459*98a0f868STianci.Yin 			    EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
460*98a0f868STianci.Yin 	if (!value) {
461*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
462*98a0f868STianci.Yin 				CRASH_ON_NO_RETRY_FAULT, 1);
463*98a0f868STianci.Yin 		tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
464*98a0f868STianci.Yin 				CRASH_ON_RETRY_FAULT, 1);
465*98a0f868STianci.Yin 	}
466*98a0f868STianci.Yin 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL, tmp);
467*98a0f868STianci.Yin }
468*98a0f868STianci.Yin 
469*98a0f868STianci.Yin static const struct amdgpu_vmhub_funcs mmhub_v3_0_vmhub_funcs = {
470*98a0f868STianci.Yin 	.print_l2_protection_fault_status = mmhub_v3_0_print_l2_protection_fault_status,
471*98a0f868STianci.Yin 	.get_invalidate_req = mmhub_v3_0_get_invalidate_req,
472*98a0f868STianci.Yin };
473*98a0f868STianci.Yin 
474*98a0f868STianci.Yin static void mmhub_v3_0_init(struct amdgpu_device *adev)
475*98a0f868STianci.Yin {
476*98a0f868STianci.Yin 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0];
477*98a0f868STianci.Yin 
478*98a0f868STianci.Yin 	hub->ctx0_ptb_addr_lo32 =
479*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0,
480*98a0f868STianci.Yin 				 regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32);
481*98a0f868STianci.Yin 	hub->ctx0_ptb_addr_hi32 =
482*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0,
483*98a0f868STianci.Yin 				 regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32);
484*98a0f868STianci.Yin 	hub->vm_inv_eng0_sem =
485*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_SEM);
486*98a0f868STianci.Yin 	hub->vm_inv_eng0_req =
487*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_REQ);
488*98a0f868STianci.Yin 	hub->vm_inv_eng0_ack =
489*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ACK);
490*98a0f868STianci.Yin 	hub->vm_context0_cntl =
491*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_CNTL);
492*98a0f868STianci.Yin 	hub->vm_l2_pro_fault_status =
493*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_STATUS);
494*98a0f868STianci.Yin 	hub->vm_l2_pro_fault_cntl =
495*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL);
496*98a0f868STianci.Yin 
497*98a0f868STianci.Yin 	hub->ctx_distance = regMMVM_CONTEXT1_CNTL - regMMVM_CONTEXT0_CNTL;
498*98a0f868STianci.Yin 	hub->ctx_addr_distance = regMMVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 -
499*98a0f868STianci.Yin 		regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
500*98a0f868STianci.Yin 	hub->eng_distance = regMMVM_INVALIDATE_ENG1_REQ -
501*98a0f868STianci.Yin 		regMMVM_INVALIDATE_ENG0_REQ;
502*98a0f868STianci.Yin 	hub->eng_addr_distance = regMMVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 -
503*98a0f868STianci.Yin 		regMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32;
504*98a0f868STianci.Yin 
505*98a0f868STianci.Yin 	hub->vm_cntx_cntl_vm_fault = MMVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
506*98a0f868STianci.Yin 		MMVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
507*98a0f868STianci.Yin 		MMVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
508*98a0f868STianci.Yin 		MMVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
509*98a0f868STianci.Yin 		MMVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
510*98a0f868STianci.Yin 		MMVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
511*98a0f868STianci.Yin 		MMVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
512*98a0f868STianci.Yin 
513*98a0f868STianci.Yin 	hub->vm_l2_bank_select_reserved_cid2 =
514*98a0f868STianci.Yin 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_BANK_SELECT_RESERVED_CID2);
515*98a0f868STianci.Yin 
516*98a0f868STianci.Yin 	hub->vmhub_funcs = &mmhub_v3_0_vmhub_funcs;
517*98a0f868STianci.Yin }
518*98a0f868STianci.Yin 
519*98a0f868STianci.Yin static u64 mmhub_v3_0_get_fb_location(struct amdgpu_device *adev)
520*98a0f868STianci.Yin {
521*98a0f868STianci.Yin 	u64 base;
522*98a0f868STianci.Yin 
523*98a0f868STianci.Yin 	base = RREG32_SOC15(MMHUB, 0, regMMMC_VM_FB_LOCATION_BASE);
524*98a0f868STianci.Yin 
525*98a0f868STianci.Yin 	base &= MMMC_VM_FB_LOCATION_BASE__FB_BASE_MASK;
526*98a0f868STianci.Yin 	base <<= 24;
527*98a0f868STianci.Yin 
528*98a0f868STianci.Yin 	return base;
529*98a0f868STianci.Yin }
530*98a0f868STianci.Yin 
531*98a0f868STianci.Yin static u64 mmhub_v3_0_get_mc_fb_offset(struct amdgpu_device *adev)
532*98a0f868STianci.Yin {
533*98a0f868STianci.Yin 	return (u64)RREG32_SOC15(MMHUB, 0, regMMMC_VM_FB_OFFSET) << 24;
534*98a0f868STianci.Yin }
535*98a0f868STianci.Yin 
536*98a0f868STianci.Yin static void mmhub_v3_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,
537*98a0f868STianci.Yin 							bool enable)
538*98a0f868STianci.Yin {
539*98a0f868STianci.Yin 	//TODO
540*98a0f868STianci.Yin }
541*98a0f868STianci.Yin 
542*98a0f868STianci.Yin static void mmhub_v3_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,
543*98a0f868STianci.Yin 						       bool enable)
544*98a0f868STianci.Yin {
545*98a0f868STianci.Yin 	//TODO
546*98a0f868STianci.Yin }
547*98a0f868STianci.Yin 
548*98a0f868STianci.Yin static int mmhub_v3_0_set_clockgating(struct amdgpu_device *adev,
549*98a0f868STianci.Yin 			       enum amd_clockgating_state state)
550*98a0f868STianci.Yin {
551*98a0f868STianci.Yin 	if (amdgpu_sriov_vf(adev))
552*98a0f868STianci.Yin 		return 0;
553*98a0f868STianci.Yin 
554*98a0f868STianci.Yin 	mmhub_v3_0_update_medium_grain_clock_gating(adev,
555*98a0f868STianci.Yin 			state == AMD_CG_STATE_GATE);
556*98a0f868STianci.Yin 	mmhub_v3_0_update_medium_grain_light_sleep(adev,
557*98a0f868STianci.Yin 			state == AMD_CG_STATE_GATE);
558*98a0f868STianci.Yin 	return 0;
559*98a0f868STianci.Yin }
560*98a0f868STianci.Yin 
561*98a0f868STianci.Yin static void mmhub_v3_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
562*98a0f868STianci.Yin {
563*98a0f868STianci.Yin 	//TODO
564*98a0f868STianci.Yin }
565*98a0f868STianci.Yin 
566*98a0f868STianci.Yin const struct amdgpu_mmhub_funcs mmhub_v3_0_funcs = {
567*98a0f868STianci.Yin 	.init = mmhub_v3_0_init,
568*98a0f868STianci.Yin 	.get_fb_location = mmhub_v3_0_get_fb_location,
569*98a0f868STianci.Yin 	.get_mc_fb_offset = mmhub_v3_0_get_mc_fb_offset,
570*98a0f868STianci.Yin 	.gart_enable = mmhub_v3_0_gart_enable,
571*98a0f868STianci.Yin 	.set_fault_enable_default = mmhub_v3_0_set_fault_enable_default,
572*98a0f868STianci.Yin 	.gart_disable = mmhub_v3_0_gart_disable,
573*98a0f868STianci.Yin 	.set_clockgating = mmhub_v3_0_set_clockgating,
574*98a0f868STianci.Yin 	.get_clockgating = mmhub_v3_0_get_clockgating,
575*98a0f868STianci.Yin 	.setup_vm_pt_regs = mmhub_v3_0_setup_vm_pt_regs,
576*98a0f868STianci.Yin };
577