xref: /linux/drivers/gpu/drm/amd/amdgpu/mmhub_v4_1_0.c (revision 15833fea97c1fdb3b34fceefa4b51177dd57e18f)
18e9f1575SHawking Zhang /*
28e9f1575SHawking Zhang  * Copyright 2023 Advanced Micro Devices, Inc.
38e9f1575SHawking Zhang  *
48e9f1575SHawking Zhang  * Permission is hereby granted, free of charge, to any person obtaining a
58e9f1575SHawking Zhang  * copy of this software and associated documentation files (the "Software"),
68e9f1575SHawking Zhang  * to deal in the Software without restriction, including without limitation
78e9f1575SHawking Zhang  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88e9f1575SHawking Zhang  * and/or sell copies of the Software, and to permit persons to whom the
98e9f1575SHawking Zhang  * Software is furnished to do so, subject to the following conditions:
108e9f1575SHawking Zhang  *
118e9f1575SHawking Zhang  * The above copyright notice and this permission notice shall be included in
128e9f1575SHawking Zhang  * all copies or substantial portions of the Software.
138e9f1575SHawking Zhang  *
148e9f1575SHawking Zhang  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
158e9f1575SHawking Zhang  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
168e9f1575SHawking Zhang  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
178e9f1575SHawking Zhang  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
188e9f1575SHawking Zhang  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
198e9f1575SHawking Zhang  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
208e9f1575SHawking Zhang  * OTHER DEALINGS IN THE SOFTWARE.
218e9f1575SHawking Zhang  *
228e9f1575SHawking Zhang  */
238e9f1575SHawking Zhang 
248e9f1575SHawking Zhang #include "amdgpu.h"
258e9f1575SHawking Zhang #include "mmhub_v4_1_0.h"
268e9f1575SHawking Zhang 
278e9f1575SHawking Zhang #include "mmhub/mmhub_4_1_0_offset.h"
288e9f1575SHawking Zhang #include "mmhub/mmhub_4_1_0_sh_mask.h"
298e9f1575SHawking Zhang 
308e9f1575SHawking Zhang #include "soc15_common.h"
318e9f1575SHawking Zhang #include "soc24_enum.h"
328e9f1575SHawking Zhang 
338e9f1575SHawking Zhang #define regMMVM_L2_CNTL3_DEFAULT				0x80100007
348e9f1575SHawking Zhang #define regMMVM_L2_CNTL4_DEFAULT				0x000000c1
358e9f1575SHawking Zhang #define regMMVM_L2_CNTL5_DEFAULT				0x00003fe0
368e9f1575SHawking Zhang 
378e9f1575SHawking Zhang static const char *mmhub_client_ids_v4_1_0[][2] = {
388e9f1575SHawking Zhang 	[0][0] = "VMC",
398e9f1575SHawking Zhang 	[4][0] = "DCEDMC",
408e9f1575SHawking Zhang 	[5][0] = "DCEVGA",
418e9f1575SHawking Zhang 	[6][0] = "MP0",
428e9f1575SHawking Zhang 	[7][0] = "MP1",
438e9f1575SHawking Zhang 	[8][0] = "MPIO",
448e9f1575SHawking Zhang 	[16][0] = "HDP",
458e9f1575SHawking Zhang 	[17][0] = "LSDMA",
468e9f1575SHawking Zhang 	[18][0] = "JPEG",
478e9f1575SHawking Zhang 	[19][0] = "VCNU0",
488e9f1575SHawking Zhang 	[21][0] = "VSCH",
498e9f1575SHawking Zhang 	[22][0] = "VCNU1",
508e9f1575SHawking Zhang 	[23][0] = "VCN1",
518e9f1575SHawking Zhang 	[32+20][0] = "VCN0",
528e9f1575SHawking Zhang 	[2][1] = "DBGUNBIO",
538e9f1575SHawking Zhang 	[3][1] = "DCEDWB",
548e9f1575SHawking Zhang 	[4][1] = "DCEDMC",
558e9f1575SHawking Zhang 	[5][1] = "DCEVGA",
568e9f1575SHawking Zhang 	[6][1] = "MP0",
578e9f1575SHawking Zhang 	[7][1] = "MP1",
588e9f1575SHawking Zhang 	[8][1] = "MPIO",
598e9f1575SHawking Zhang 	[10][1] = "DBGU0",
608e9f1575SHawking Zhang 	[11][1] = "DBGU1",
618e9f1575SHawking Zhang 	[12][1] = "DBGU2",
628e9f1575SHawking Zhang 	[13][1] = "DBGU3",
638e9f1575SHawking Zhang 	[14][1] = "XDP",
648e9f1575SHawking Zhang 	[15][1] = "OSSSYS",
658e9f1575SHawking Zhang 	[16][1] = "HDP",
668e9f1575SHawking Zhang 	[17][1] = "LSDMA",
678e9f1575SHawking Zhang 	[18][1] = "JPEG",
688e9f1575SHawking Zhang 	[19][1] = "VCNU0",
698e9f1575SHawking Zhang 	[20][1] = "VCN0",
708e9f1575SHawking Zhang 	[21][1] = "VSCH",
718e9f1575SHawking Zhang 	[22][1] = "VCNU1",
728e9f1575SHawking Zhang 	[23][1] = "VCN1",
738e9f1575SHawking Zhang };
748e9f1575SHawking Zhang 
mmhub_v4_1_0_get_invalidate_req(unsigned int vmid,uint32_t flush_type)758e9f1575SHawking Zhang static uint32_t mmhub_v4_1_0_get_invalidate_req(unsigned int vmid,
768e9f1575SHawking Zhang 						uint32_t flush_type)
778e9f1575SHawking Zhang {
788e9f1575SHawking Zhang 	u32 req = 0;
798e9f1575SHawking Zhang 
808e9f1575SHawking Zhang 	/* invalidate using legacy mode on vmid*/
818e9f1575SHawking Zhang 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ,
828e9f1575SHawking Zhang 			    PER_VMID_INVALIDATE_REQ, 1 << vmid);
83*aa5c9701SLikun Gao 	/* Only use legacy inv on mmhub side */
84*aa5c9701SLikun Gao 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, 0);
858e9f1575SHawking Zhang 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
868e9f1575SHawking Zhang 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
878e9f1575SHawking Zhang 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1);
888e9f1575SHawking Zhang 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1);
898e9f1575SHawking Zhang 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1);
908e9f1575SHawking Zhang 	req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ,
918e9f1575SHawking Zhang 			    CLEAR_PROTECTION_FAULT_STATUS_ADDR,	0);
928e9f1575SHawking Zhang 
938e9f1575SHawking Zhang 	return req;
948e9f1575SHawking Zhang }
958e9f1575SHawking Zhang 
968e9f1575SHawking Zhang static void
mmhub_v4_1_0_print_l2_protection_fault_status(struct amdgpu_device * adev,uint32_t status)978e9f1575SHawking Zhang mmhub_v4_1_0_print_l2_protection_fault_status(struct amdgpu_device *adev,
988e9f1575SHawking Zhang 					      uint32_t status)
998e9f1575SHawking Zhang {
1008e9f1575SHawking Zhang 	uint32_t cid, rw;
1018e9f1575SHawking Zhang 	const char *mmhub_cid = NULL;
1028e9f1575SHawking Zhang 
1038e9f1575SHawking Zhang 	cid = REG_GET_FIELD(status,
1048e9f1575SHawking Zhang 			    MMVM_L2_PROTECTION_FAULT_STATUS_LO32, CID);
1058e9f1575SHawking Zhang 	rw = REG_GET_FIELD(status,
1068e9f1575SHawking Zhang 			   MMVM_L2_PROTECTION_FAULT_STATUS_LO32, RW);
1078e9f1575SHawking Zhang 
1088e9f1575SHawking Zhang 	dev_err(adev->dev,
1098e9f1575SHawking Zhang 		"MMVM_L2_PROTECTION_FAULT_STATUS_LO32:0x%08X\n",
1108e9f1575SHawking Zhang 		status);
1118e9f1575SHawking Zhang 	switch (adev->ip_versions[MMHUB_HWIP][0]) {
1128e9f1575SHawking Zhang 	case IP_VERSION(4, 1, 0):
1138e9f1575SHawking Zhang 		mmhub_cid = mmhub_client_ids_v4_1_0[cid][rw];
1148e9f1575SHawking Zhang 		break;
1158e9f1575SHawking Zhang 	default:
1168e9f1575SHawking Zhang 		mmhub_cid = NULL;
1178e9f1575SHawking Zhang 		break;
1188e9f1575SHawking Zhang 	}
1198e9f1575SHawking Zhang 	dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
1208e9f1575SHawking Zhang 		mmhub_cid ? mmhub_cid : "unknown", cid);
1218e9f1575SHawking Zhang 	dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
1228e9f1575SHawking Zhang 		REG_GET_FIELD(status,
1238e9f1575SHawking Zhang 		MMVM_L2_PROTECTION_FAULT_STATUS_LO32, MORE_FAULTS));
1248e9f1575SHawking Zhang 	dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n",
1258e9f1575SHawking Zhang 		REG_GET_FIELD(status,
1268e9f1575SHawking Zhang 		MMVM_L2_PROTECTION_FAULT_STATUS_LO32, WALKER_ERROR));
1278e9f1575SHawking Zhang 	dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n",
1288e9f1575SHawking Zhang 		REG_GET_FIELD(status,
1298e9f1575SHawking Zhang 		MMVM_L2_PROTECTION_FAULT_STATUS_LO32, PERMISSION_FAULTS));
1308e9f1575SHawking Zhang 	dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n",
1318e9f1575SHawking Zhang 		REG_GET_FIELD(status,
1328e9f1575SHawking Zhang 		MMVM_L2_PROTECTION_FAULT_STATUS_LO32, MAPPING_ERROR));
1338e9f1575SHawking Zhang 	dev_err(adev->dev, "\t RW: 0x%x\n", rw);
1348e9f1575SHawking Zhang }
1358e9f1575SHawking Zhang 
mmhub_v4_1_0_setup_vm_pt_regs(struct amdgpu_device * adev,uint32_t vmid,uint64_t page_table_base)1368e9f1575SHawking Zhang static void mmhub_v4_1_0_setup_vm_pt_regs(struct amdgpu_device *adev,
1378e9f1575SHawking Zhang 					  uint32_t vmid, uint64_t page_table_base)
1388e9f1575SHawking Zhang {
1398e9f1575SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB0(0)];
1408e9f1575SHawking Zhang 
1418e9f1575SHawking Zhang 	WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32,
1428e9f1575SHawking Zhang 			    hub->ctx_addr_distance * vmid,
1438e9f1575SHawking Zhang 			    lower_32_bits(page_table_base));
1448e9f1575SHawking Zhang 
1458e9f1575SHawking Zhang 	WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32,
1468e9f1575SHawking Zhang 			    hub->ctx_addr_distance * vmid,
1478e9f1575SHawking Zhang 			    upper_32_bits(page_table_base));
1488e9f1575SHawking Zhang }
1498e9f1575SHawking Zhang 
mmhub_v4_1_0_init_gart_aperture_regs(struct amdgpu_device * adev)1508e9f1575SHawking Zhang static void mmhub_v4_1_0_init_gart_aperture_regs(struct amdgpu_device *adev)
1518e9f1575SHawking Zhang {
1528e9f1575SHawking Zhang 	uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo);
1538e9f1575SHawking Zhang 
1548e9f1575SHawking Zhang 	mmhub_v4_1_0_setup_vm_pt_regs(adev, 0, pt_base);
1558e9f1575SHawking Zhang 
1568e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
1578e9f1575SHawking Zhang 		     (u32)(adev->gmc.gart_start >> 12));
1588e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
1598e9f1575SHawking Zhang 		     (u32)(adev->gmc.gart_start >> 44));
1608e9f1575SHawking Zhang 
1618e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
1628e9f1575SHawking Zhang 		     (u32)(adev->gmc.gart_end >> 12));
1638e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
1648e9f1575SHawking Zhang 		     (u32)(adev->gmc.gart_end >> 44));
1658e9f1575SHawking Zhang }
1668e9f1575SHawking Zhang 
mmhub_v4_1_0_init_system_aperture_regs(struct amdgpu_device * adev)1678e9f1575SHawking Zhang static void mmhub_v4_1_0_init_system_aperture_regs(struct amdgpu_device *adev)
1688e9f1575SHawking Zhang {
1698e9f1575SHawking Zhang 	uint64_t value;
1708e9f1575SHawking Zhang 	uint32_t tmp;
1718e9f1575SHawking Zhang 
1728e9f1575SHawking Zhang 	/*
1738e9f1575SHawking Zhang 	 * the new L1 policy will block SRIOV guest from writing
1748e9f1575SHawking Zhang 	 * these regs, and they will be programed at host.
1758e9f1575SHawking Zhang 	 * so skip programing these regs.
1768e9f1575SHawking Zhang 	 */
1778e9f1575SHawking Zhang 	if (amdgpu_sriov_vf(adev))
1788e9f1575SHawking Zhang 		return;
1798e9f1575SHawking Zhang 
1808e9f1575SHawking Zhang 	/* Program the AGP BAR */
1818e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
1828e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, adev->gmc.agp_start >> 24);
1838e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, adev->gmc.agp_end >> 24);
1848e9f1575SHawking Zhang 
1858e9f1575SHawking Zhang 	/* Program the system aperture low logical page number. */
1868e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
1878e9f1575SHawking Zhang 		     min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18);
1888e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_HIGH_ADDR,
1898e9f1575SHawking Zhang 		     max(adev->gmc.fb_end, adev->gmc.agp_end) >> 18);
1908e9f1575SHawking Zhang 
1918e9f1575SHawking Zhang 	/* Set default page address. */
1928e9f1575SHawking Zhang 	value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start +
1938e9f1575SHawking Zhang 		adev->vm_manager.vram_base_offset;
1948e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB,
1958e9f1575SHawking Zhang 		     (u32)(value >> 12));
1968e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB,
1978e9f1575SHawking Zhang 		     (u32)(value >> 44));
1988e9f1575SHawking Zhang 
1998e9f1575SHawking Zhang 	/* Program "protection fault". */
2008e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32,
2018e9f1575SHawking Zhang 		     (u32)(adev->dummy_page_addr >> 12));
2028e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32,
2038e9f1575SHawking Zhang 		     (u32)((u64)adev->dummy_page_addr >> 44));
2048e9f1575SHawking Zhang 
2058e9f1575SHawking Zhang 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL2);
2068e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL2,
2078e9f1575SHawking Zhang 			    ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1);
2088e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL2, tmp);
2098e9f1575SHawking Zhang }
2108e9f1575SHawking Zhang 
mmhub_v4_1_0_init_tlb_regs(struct amdgpu_device * adev)2118e9f1575SHawking Zhang static void mmhub_v4_1_0_init_tlb_regs(struct amdgpu_device *adev)
2128e9f1575SHawking Zhang {
2138e9f1575SHawking Zhang 	uint32_t tmp;
2148e9f1575SHawking Zhang 
2158e9f1575SHawking Zhang 	/* Setup TLB control */
2168e9f1575SHawking Zhang 	tmp = RREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL);
2178e9f1575SHawking Zhang 
2188e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1);
2198e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3);
2208e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
2218e9f1575SHawking Zhang 			    ENABLE_ADVANCED_DRIVER_MODEL, 1);
2228e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
2238e9f1575SHawking Zhang 			    SYSTEM_APERTURE_UNMAPPED_ACCESS, 0);
2248e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0);
2258e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
2268e9f1575SHawking Zhang 			    MTYPE, MTYPE_UC); /* UC, uncached */
2278e9f1575SHawking Zhang 
2288e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL, tmp);
2298e9f1575SHawking Zhang }
2308e9f1575SHawking Zhang 
mmhub_v4_1_0_init_cache_regs(struct amdgpu_device * adev)2318e9f1575SHawking Zhang static void mmhub_v4_1_0_init_cache_regs(struct amdgpu_device *adev)
2328e9f1575SHawking Zhang {
2338e9f1575SHawking Zhang 	uint32_t tmp;
2348e9f1575SHawking Zhang 
2358e9f1575SHawking Zhang 	/* These registers are not accessible to VF-SRIOV.
2368e9f1575SHawking Zhang 	 * The PF will program them instead.
2378e9f1575SHawking Zhang 	 */
2388e9f1575SHawking Zhang 	if (amdgpu_sriov_vf(adev))
2398e9f1575SHawking Zhang 		return;
2408e9f1575SHawking Zhang 
2418e9f1575SHawking Zhang 	/* Setup L2 cache */
2428e9f1575SHawking Zhang 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL);
2438e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 1);
2448e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
2458e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL,
2468e9f1575SHawking Zhang 			    ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1);
2478e9f1575SHawking Zhang 	/* XXX for emulation, Refer to closed source code.*/
2488e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE,
2498e9f1575SHawking Zhang 			    0);
2508e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0);
2518e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1);
2528e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0);
2538e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL, tmp);
2548e9f1575SHawking Zhang 
2558e9f1575SHawking Zhang 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL2);
2568e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
2578e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
2588e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL2, tmp);
2598e9f1575SHawking Zhang 
2608e9f1575SHawking Zhang 	tmp = regMMVM_L2_CNTL3_DEFAULT;
2618e9f1575SHawking Zhang 	if (adev->gmc.translate_further) {
2628e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 12);
2638e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
2648e9f1575SHawking Zhang 				    L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
2658e9f1575SHawking Zhang 	} else {
2668e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 9);
2678e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3,
2688e9f1575SHawking Zhang 				    L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
2698e9f1575SHawking Zhang 	}
2708e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL3, tmp);
2718e9f1575SHawking Zhang 
2728e9f1575SHawking Zhang 	tmp = regMMVM_L2_CNTL4_DEFAULT;
2738e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0);
2748e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0);
2758e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL4, tmp);
2768e9f1575SHawking Zhang 
2778e9f1575SHawking Zhang 	tmp = regMMVM_L2_CNTL5_DEFAULT;
2788e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
2798e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL5, tmp);
2808e9f1575SHawking Zhang }
2818e9f1575SHawking Zhang 
mmhub_v4_1_0_enable_system_domain(struct amdgpu_device * adev)2828e9f1575SHawking Zhang static void mmhub_v4_1_0_enable_system_domain(struct amdgpu_device *adev)
2838e9f1575SHawking Zhang {
2848e9f1575SHawking Zhang 	uint32_t tmp;
2858e9f1575SHawking Zhang 
2868e9f1575SHawking Zhang 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_CNTL);
2878e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
2888e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
2898e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL,
2908e9f1575SHawking Zhang 			    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
2918e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_CNTL, tmp);
2928e9f1575SHawking Zhang }
2938e9f1575SHawking Zhang 
mmhub_v4_1_0_disable_identity_aperture(struct amdgpu_device * adev)2948e9f1575SHawking Zhang static void mmhub_v4_1_0_disable_identity_aperture(struct amdgpu_device *adev)
2958e9f1575SHawking Zhang {
2968e9f1575SHawking Zhang 	/* These registers are not accessible to VF-SRIOV.
2978e9f1575SHawking Zhang 	 * The PF will program them instead.
2988e9f1575SHawking Zhang 	 */
2998e9f1575SHawking Zhang 	if (amdgpu_sriov_vf(adev))
3008e9f1575SHawking Zhang 		return;
3018e9f1575SHawking Zhang 
3028e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0,
3038e9f1575SHawking Zhang 		     regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32,
3048e9f1575SHawking Zhang 		     0xFFFFFFFF);
3058e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0,
3068e9f1575SHawking Zhang 		     regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32,
3078e9f1575SHawking Zhang 		     0x0000000F);
3088e9f1575SHawking Zhang 
3098e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0,
3108e9f1575SHawking Zhang 		     regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32, 0);
3118e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0,
3128e9f1575SHawking Zhang 		     regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32, 0);
3138e9f1575SHawking Zhang 
3148e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32,
3158e9f1575SHawking Zhang 		     0);
3168e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32,
3178e9f1575SHawking Zhang 		     0);
3188e9f1575SHawking Zhang }
3198e9f1575SHawking Zhang 
mmhub_v4_1_0_setup_vmid_config(struct amdgpu_device * adev)3208e9f1575SHawking Zhang static void mmhub_v4_1_0_setup_vmid_config(struct amdgpu_device *adev)
3218e9f1575SHawking Zhang {
3228e9f1575SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB0(0)];
3238e9f1575SHawking Zhang 	int i;
3248e9f1575SHawking Zhang 	uint32_t tmp;
3258e9f1575SHawking Zhang 
3268e9f1575SHawking Zhang 	for (i = 0; i <= 14; i++) {
3278e9f1575SHawking Zhang 		tmp = RREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_CNTL, i);
3288e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1);
3298e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH,
3308e9f1575SHawking Zhang 				    adev->vm_manager.num_level);
3318e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3328e9f1575SHawking Zhang 				    RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
3338e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3348e9f1575SHawking Zhang 				    DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT,
3358e9f1575SHawking Zhang 				    1);
3368e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3378e9f1575SHawking Zhang 				    PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
3388e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3398e9f1575SHawking Zhang 				    VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
3408e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3418e9f1575SHawking Zhang 				    READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
3428e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3438e9f1575SHawking Zhang 				    WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
3448e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3458e9f1575SHawking Zhang 				    EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1);
3468e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3478e9f1575SHawking Zhang 				    PAGE_TABLE_BLOCK_SIZE,
3488e9f1575SHawking Zhang 				    adev->vm_manager.block_size - 9);
3498e9f1575SHawking Zhang 		/* Send no-retry XNACK on fault to suppress VM fault storm. */
3508e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL,
3518e9f1575SHawking Zhang 				    RETRY_PERMISSION_OR_INVALID_PAGE_FAULT,
3528e9f1575SHawking Zhang 				    !amdgpu_noretry);
3538e9f1575SHawking Zhang 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_CNTL,
3548e9f1575SHawking Zhang 				    i * hub->ctx_distance, tmp);
3558e9f1575SHawking Zhang 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32,
3568e9f1575SHawking Zhang 				    i * hub->ctx_addr_distance, 0);
3578e9f1575SHawking Zhang 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32,
3588e9f1575SHawking Zhang 				    i * hub->ctx_addr_distance, 0);
3598e9f1575SHawking Zhang 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32,
3608e9f1575SHawking Zhang 				    i * hub->ctx_addr_distance,
3618e9f1575SHawking Zhang 				    lower_32_bits(adev->vm_manager.max_pfn - 1));
3628e9f1575SHawking Zhang 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32,
3638e9f1575SHawking Zhang 				    i * hub->ctx_addr_distance,
3648e9f1575SHawking Zhang 				    upper_32_bits(adev->vm_manager.max_pfn - 1));
3658e9f1575SHawking Zhang 	}
3668e9f1575SHawking Zhang 
3678e9f1575SHawking Zhang 	hub->vm_cntx_cntl = tmp;
3688e9f1575SHawking Zhang }
3698e9f1575SHawking Zhang 
mmhub_v4_1_0_program_invalidation(struct amdgpu_device * adev)3708e9f1575SHawking Zhang static void mmhub_v4_1_0_program_invalidation(struct amdgpu_device *adev)
3718e9f1575SHawking Zhang {
3728e9f1575SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB0(0)];
3738e9f1575SHawking Zhang 	unsigned i;
3748e9f1575SHawking Zhang 
3758e9f1575SHawking Zhang 	for (i = 0; i < 18; ++i) {
3768e9f1575SHawking Zhang 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32,
3778e9f1575SHawking Zhang 				    i * hub->eng_addr_distance, 0xffffffff);
3788e9f1575SHawking Zhang 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ADDR_RANGE_HI32,
3798e9f1575SHawking Zhang 				    i * hub->eng_addr_distance, 0x1f);
3808e9f1575SHawking Zhang 	}
3818e9f1575SHawking Zhang }
3828e9f1575SHawking Zhang 
mmhub_v4_1_0_gart_enable(struct amdgpu_device * adev)3838e9f1575SHawking Zhang static int mmhub_v4_1_0_gart_enable(struct amdgpu_device *adev)
3848e9f1575SHawking Zhang {
3858e9f1575SHawking Zhang 	/* GART Enable. */
3868e9f1575SHawking Zhang 	mmhub_v4_1_0_init_gart_aperture_regs(adev);
3878e9f1575SHawking Zhang 	mmhub_v4_1_0_init_system_aperture_regs(adev);
3888e9f1575SHawking Zhang 	mmhub_v4_1_0_init_tlb_regs(adev);
3898e9f1575SHawking Zhang 	mmhub_v4_1_0_init_cache_regs(adev);
3908e9f1575SHawking Zhang 
3918e9f1575SHawking Zhang 	mmhub_v4_1_0_enable_system_domain(adev);
3928e9f1575SHawking Zhang 	mmhub_v4_1_0_disable_identity_aperture(adev);
3938e9f1575SHawking Zhang 	mmhub_v4_1_0_setup_vmid_config(adev);
3948e9f1575SHawking Zhang 	mmhub_v4_1_0_program_invalidation(adev);
3958e9f1575SHawking Zhang 
3968e9f1575SHawking Zhang 	return 0;
3978e9f1575SHawking Zhang }
3988e9f1575SHawking Zhang 
mmhub_v4_1_0_gart_disable(struct amdgpu_device * adev)3998e9f1575SHawking Zhang static void mmhub_v4_1_0_gart_disable(struct amdgpu_device *adev)
4008e9f1575SHawking Zhang {
4018e9f1575SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB0(0)];
4028e9f1575SHawking Zhang 	u32 tmp;
4038e9f1575SHawking Zhang 	u32 i;
4048e9f1575SHawking Zhang 
4058e9f1575SHawking Zhang 	/* Disable all tables */
4068e9f1575SHawking Zhang 	for (i = 0; i < 16; i++)
4078e9f1575SHawking Zhang 		WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_CNTL,
4088e9f1575SHawking Zhang 				    i * hub->ctx_distance, 0);
4098e9f1575SHawking Zhang 
4108e9f1575SHawking Zhang 	/* Setup TLB control */
4118e9f1575SHawking Zhang 	tmp = RREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL);
4128e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0);
4138e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL,
4148e9f1575SHawking Zhang 			    ENABLE_ADVANCED_DRIVER_MODEL, 0);
4158e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL, tmp);
4168e9f1575SHawking Zhang 
4178e9f1575SHawking Zhang 	/* Setup L2 cache */
4188e9f1575SHawking Zhang 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL);
4198e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 0);
4208e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL, tmp);
4218e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL3, 0);
4228e9f1575SHawking Zhang }
4238e9f1575SHawking Zhang 
4248e9f1575SHawking Zhang /**
4258e9f1575SHawking Zhang  * mmhub_v4_1_0_set_fault_enable_default - update GART/VM fault handling
4268e9f1575SHawking Zhang  *
4278e9f1575SHawking Zhang  * @adev: amdgpu_device pointer
4288e9f1575SHawking Zhang  * @value: true redirects VM faults to the default page
4298e9f1575SHawking Zhang  */
4308e9f1575SHawking Zhang static void
mmhub_v4_1_0_set_fault_enable_default(struct amdgpu_device * adev,bool value)4318e9f1575SHawking Zhang mmhub_v4_1_0_set_fault_enable_default(struct amdgpu_device *adev, bool value)
4328e9f1575SHawking Zhang {
4338e9f1575SHawking Zhang 	u32 tmp;
4348e9f1575SHawking Zhang 
4358e9f1575SHawking Zhang 	/* These registers are not accessible to VF-SRIOV.
4368e9f1575SHawking Zhang 	 * The PF will program them instead.
4378e9f1575SHawking Zhang 	 */
4388e9f1575SHawking Zhang 	if (amdgpu_sriov_vf(adev))
4398e9f1575SHawking Zhang 		return;
4408e9f1575SHawking Zhang 
4418e9f1575SHawking Zhang 	tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL);
4428e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4438e9f1575SHawking Zhang 			    RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4448e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4458e9f1575SHawking Zhang 			    PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4468e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4478e9f1575SHawking Zhang 			    PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4488e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4498e9f1575SHawking Zhang 			    PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4508e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4518e9f1575SHawking Zhang 			    TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT,
4528e9f1575SHawking Zhang 			    value);
4538e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4548e9f1575SHawking Zhang 			    NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4558e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4568e9f1575SHawking Zhang 			    DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4578e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4588e9f1575SHawking Zhang 			    VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4598e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4608e9f1575SHawking Zhang 			    READ_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4618e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4628e9f1575SHawking Zhang 			    WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4638e9f1575SHawking Zhang 	tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4648e9f1575SHawking Zhang 			    EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value);
4658e9f1575SHawking Zhang 	if (!value) {
4668e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4678e9f1575SHawking Zhang 				CRASH_ON_NO_RETRY_FAULT, 1);
4688e9f1575SHawking Zhang 		tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL,
4698e9f1575SHawking Zhang 				CRASH_ON_RETRY_FAULT, 1);
4708e9f1575SHawking Zhang 	}
4718e9f1575SHawking Zhang 	WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL, tmp);
4728e9f1575SHawking Zhang }
4738e9f1575SHawking Zhang 
4748e9f1575SHawking Zhang static const struct amdgpu_vmhub_funcs mmhub_v4_1_0_vmhub_funcs = {
4758e9f1575SHawking Zhang 	.print_l2_protection_fault_status = mmhub_v4_1_0_print_l2_protection_fault_status,
4768e9f1575SHawking Zhang 	.get_invalidate_req = mmhub_v4_1_0_get_invalidate_req,
4778e9f1575SHawking Zhang };
4788e9f1575SHawking Zhang 
mmhub_v4_1_0_init(struct amdgpu_device * adev)4798e9f1575SHawking Zhang static void mmhub_v4_1_0_init(struct amdgpu_device *adev)
4808e9f1575SHawking Zhang {
4818e9f1575SHawking Zhang 	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB0(0)];
4828e9f1575SHawking Zhang 
4838e9f1575SHawking Zhang 	hub->ctx0_ptb_addr_lo32 =
4848e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0,
4858e9f1575SHawking Zhang 				 regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32);
4868e9f1575SHawking Zhang 	hub->ctx0_ptb_addr_hi32 =
4878e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0,
4888e9f1575SHawking Zhang 				 regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32);
4898e9f1575SHawking Zhang 	hub->vm_inv_eng0_sem =
4908e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_SEM);
4918e9f1575SHawking Zhang 	hub->vm_inv_eng0_req =
4928e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_REQ);
4938e9f1575SHawking Zhang 	hub->vm_inv_eng0_ack =
4948e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ACK);
4958e9f1575SHawking Zhang 	hub->vm_context0_cntl =
4968e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_CNTL);
4978e9f1575SHawking Zhang 	hub->vm_l2_pro_fault_status =
4988e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_STATUS_LO32);
4998e9f1575SHawking Zhang 	hub->vm_l2_pro_fault_cntl =
5008e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL);
5018e9f1575SHawking Zhang 
5028e9f1575SHawking Zhang 	hub->ctx_distance = regMMVM_CONTEXT1_CNTL - regMMVM_CONTEXT0_CNTL;
5038e9f1575SHawking Zhang 	hub->ctx_addr_distance = regMMVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 -
5048e9f1575SHawking Zhang 		regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32;
5058e9f1575SHawking Zhang 	hub->eng_distance = regMMVM_INVALIDATE_ENG1_REQ -
5068e9f1575SHawking Zhang 		regMMVM_INVALIDATE_ENG0_REQ;
5078e9f1575SHawking Zhang 	hub->eng_addr_distance = regMMVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 -
5088e9f1575SHawking Zhang 		regMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32;
5098e9f1575SHawking Zhang 
5108e9f1575SHawking Zhang 	hub->vm_cntx_cntl_vm_fault = MMVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
5118e9f1575SHawking Zhang 		MMVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
5128e9f1575SHawking Zhang 		MMVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
5138e9f1575SHawking Zhang 		MMVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
5148e9f1575SHawking Zhang 		MMVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
5158e9f1575SHawking Zhang 		MMVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK |
5168e9f1575SHawking Zhang 		MMVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK;
5178e9f1575SHawking Zhang 
5188e9f1575SHawking Zhang 	hub->vm_l2_bank_select_reserved_cid2 =
5198e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_BANK_SELECT_RESERVED_CID2);
5208e9f1575SHawking Zhang 
5218e9f1575SHawking Zhang 	hub->vm_contexts_disable =
5228e9f1575SHawking Zhang 		SOC15_REG_OFFSET(MMHUB, 0, regMMVM_CONTEXTS_DISABLE);
5238e9f1575SHawking Zhang 
5248e9f1575SHawking Zhang 	hub->vmhub_funcs = &mmhub_v4_1_0_vmhub_funcs;
5258e9f1575SHawking Zhang }
5268e9f1575SHawking Zhang 
mmhub_v4_1_0_get_fb_location(struct amdgpu_device * adev)5278e9f1575SHawking Zhang static u64 mmhub_v4_1_0_get_fb_location(struct amdgpu_device *adev)
5288e9f1575SHawking Zhang {
5298e9f1575SHawking Zhang 	u64 base;
5308e9f1575SHawking Zhang 
5318e9f1575SHawking Zhang 	base = RREG32_SOC15(MMHUB, 0, regMMMC_VM_FB_LOCATION_BASE);
5328e9f1575SHawking Zhang 
5338e9f1575SHawking Zhang 	base &= MMMC_VM_FB_LOCATION_BASE__FB_BASE_MASK;
5348e9f1575SHawking Zhang 	base <<= 24;
5358e9f1575SHawking Zhang 
5368e9f1575SHawking Zhang 	return base;
5378e9f1575SHawking Zhang }
5388e9f1575SHawking Zhang 
mmhub_v4_1_0_get_mc_fb_offset(struct amdgpu_device * adev)5398e9f1575SHawking Zhang static u64 mmhub_v4_1_0_get_mc_fb_offset(struct amdgpu_device *adev)
5408e9f1575SHawking Zhang {
5418e9f1575SHawking Zhang 	return (u64)RREG32_SOC15(MMHUB, 0, regMMMC_VM_FB_OFFSET) << 24;
5428e9f1575SHawking Zhang }
5438e9f1575SHawking Zhang 
5448e9f1575SHawking Zhang static void
mmhub_v4_1_0_update_medium_grain_clock_gating(struct amdgpu_device * adev,bool enable)5458e9f1575SHawking Zhang mmhub_v4_1_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,
5468e9f1575SHawking Zhang 					      bool enable)
5478e9f1575SHawking Zhang {
5488e9f1575SHawking Zhang #if 0
5498e9f1575SHawking Zhang 	uint32_t def, data;
5508e9f1575SHawking Zhang #endif
5518e9f1575SHawking Zhang 	uint32_t def1, data1, def2 = 0, data2 = 0;
5528e9f1575SHawking Zhang #if 0
5538e9f1575SHawking Zhang 	def  = data  = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG);
5548e9f1575SHawking Zhang #endif
5558e9f1575SHawking Zhang 	def1 = data1 = RREG32_SOC15(MMHUB, 0, regDAGB0_CNTL_MISC2);
5568e9f1575SHawking Zhang 	def2 = data2 = RREG32_SOC15(MMHUB, 0, regDAGB1_CNTL_MISC2);
5578e9f1575SHawking Zhang 
5588e9f1575SHawking Zhang 	if (enable) {
5598e9f1575SHawking Zhang #if 0
5608e9f1575SHawking Zhang 		data |= MM_ATC_L2_MISC_CG__ENABLE_MASK;
5618e9f1575SHawking Zhang #endif
5628e9f1575SHawking Zhang 		data1 &= ~(DAGB0_CNTL_MISC2__DISABLE_RDRET_TAP_CHAIN_FGCG_MASK |
5638e9f1575SHawking Zhang 			   DAGB0_CNTL_MISC2__DISABLE_WRRET_TAP_CHAIN_FGCG_MASK);
5648e9f1575SHawking Zhang 
5658e9f1575SHawking Zhang 		data2 &= ~(DAGB1_CNTL_MISC2__DISABLE_RDRET_TAP_CHAIN_FGCG_MASK |
5668e9f1575SHawking Zhang 			   DAGB1_CNTL_MISC2__DISABLE_WRRET_TAP_CHAIN_FGCG_MASK);
5678e9f1575SHawking Zhang 	} else {
5688e9f1575SHawking Zhang #if 0
5698e9f1575SHawking Zhang 		data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK;
5708e9f1575SHawking Zhang #endif
5718e9f1575SHawking Zhang 		data1 |= (DAGB0_CNTL_MISC2__DISABLE_RDRET_TAP_CHAIN_FGCG_MASK |
5728e9f1575SHawking Zhang 			  DAGB0_CNTL_MISC2__DISABLE_WRRET_TAP_CHAIN_FGCG_MASK);
5738e9f1575SHawking Zhang 
5748e9f1575SHawking Zhang 		data2 |= (DAGB1_CNTL_MISC2__DISABLE_RDRET_TAP_CHAIN_FGCG_MASK |
5758e9f1575SHawking Zhang 			  DAGB1_CNTL_MISC2__DISABLE_WRRET_TAP_CHAIN_FGCG_MASK);
5768e9f1575SHawking Zhang 	}
5778e9f1575SHawking Zhang 
5788e9f1575SHawking Zhang #if 0
5798e9f1575SHawking Zhang 	if (def != data)
5808e9f1575SHawking Zhang 		WREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG, data);
5818e9f1575SHawking Zhang #endif
5828e9f1575SHawking Zhang 	if (def1 != data1)
5838e9f1575SHawking Zhang 		WREG32_SOC15(MMHUB, 0, regDAGB0_CNTL_MISC2, data1);
5848e9f1575SHawking Zhang 
5858e9f1575SHawking Zhang 	if (def2 != data2)
5868e9f1575SHawking Zhang 		WREG32_SOC15(MMHUB, 0, regDAGB1_CNTL_MISC2, data2);
5878e9f1575SHawking Zhang }
5888e9f1575SHawking Zhang 
5898e9f1575SHawking Zhang static void
mmhub_v4_1_0_update_medium_grain_light_sleep(struct amdgpu_device * adev,bool enable)5908e9f1575SHawking Zhang mmhub_v4_1_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,
5918e9f1575SHawking Zhang 					     bool enable)
5928e9f1575SHawking Zhang {
5938e9f1575SHawking Zhang #if 0
5948e9f1575SHawking Zhang 	uint32_t def, data;
5958e9f1575SHawking Zhang 
5968e9f1575SHawking Zhang 	def = data = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG);
5978e9f1575SHawking Zhang 
5988e9f1575SHawking Zhang 	if (enable)
5998e9f1575SHawking Zhang 		data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
6008e9f1575SHawking Zhang 	else
6018e9f1575SHawking Zhang 		data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
6028e9f1575SHawking Zhang 
6038e9f1575SHawking Zhang 	if (def != data)
6048e9f1575SHawking Zhang 		WREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG, data);
6058e9f1575SHawking Zhang #endif
6068e9f1575SHawking Zhang }
6078e9f1575SHawking Zhang 
mmhub_v4_1_0_set_clockgating(struct amdgpu_device * adev,enum amd_clockgating_state state)6088e9f1575SHawking Zhang static int mmhub_v4_1_0_set_clockgating(struct amdgpu_device *adev,
6098e9f1575SHawking Zhang 					enum amd_clockgating_state state)
6108e9f1575SHawking Zhang {
6118e9f1575SHawking Zhang 	if (amdgpu_sriov_vf(adev))
6128e9f1575SHawking Zhang 		return 0;
6138e9f1575SHawking Zhang 
6148e9f1575SHawking Zhang 	if (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)
6158e9f1575SHawking Zhang 		mmhub_v4_1_0_update_medium_grain_clock_gating(adev,
6168e9f1575SHawking Zhang 				state == AMD_CG_STATE_GATE);
6178e9f1575SHawking Zhang 
6188e9f1575SHawking Zhang 	if (adev->cg_flags & AMD_CG_SUPPORT_MC_LS)
6198e9f1575SHawking Zhang 		mmhub_v4_1_0_update_medium_grain_light_sleep(adev,
6208e9f1575SHawking Zhang 				state == AMD_CG_STATE_GATE);
6218e9f1575SHawking Zhang 
6228e9f1575SHawking Zhang 	return 0;
6238e9f1575SHawking Zhang }
6248e9f1575SHawking Zhang 
mmhub_v4_1_0_get_clockgating(struct amdgpu_device * adev,u64 * flags)6258e9f1575SHawking Zhang static void mmhub_v4_1_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
6268e9f1575SHawking Zhang {
6278e9f1575SHawking Zhang #if 0
6288e9f1575SHawking Zhang 	int data;
6298e9f1575SHawking Zhang 
6308e9f1575SHawking Zhang 	if (amdgpu_sriov_vf(adev))
6318e9f1575SHawking Zhang 		*flags = 0;
6328e9f1575SHawking Zhang 
6338e9f1575SHawking Zhang 	data = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG);
6348e9f1575SHawking Zhang 
6358e9f1575SHawking Zhang 	/* AMD_CG_SUPPORT_MC_MGCG */
6368e9f1575SHawking Zhang 	if (data & MM_ATC_L2_MISC_CG__ENABLE_MASK)
6378e9f1575SHawking Zhang 		*flags |= AMD_CG_SUPPORT_MC_MGCG;
6388e9f1575SHawking Zhang 
6398e9f1575SHawking Zhang 	/* AMD_CG_SUPPORT_MC_LS */
6408e9f1575SHawking Zhang 	if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK)
6418e9f1575SHawking Zhang 		*flags |= AMD_CG_SUPPORT_MC_LS;
6428e9f1575SHawking Zhang #endif
6438e9f1575SHawking Zhang }
6448e9f1575SHawking Zhang 
6458e9f1575SHawking Zhang const struct amdgpu_mmhub_funcs mmhub_v4_1_0_funcs = {
6468e9f1575SHawking Zhang 	.init = mmhub_v4_1_0_init,
6478e9f1575SHawking Zhang 	.get_fb_location = mmhub_v4_1_0_get_fb_location,
6488e9f1575SHawking Zhang 	.get_mc_fb_offset = mmhub_v4_1_0_get_mc_fb_offset,
6498e9f1575SHawking Zhang 	.gart_enable = mmhub_v4_1_0_gart_enable,
6508e9f1575SHawking Zhang 	.set_fault_enable_default = mmhub_v4_1_0_set_fault_enable_default,
6518e9f1575SHawking Zhang 	.gart_disable = mmhub_v4_1_0_gart_disable,
6528e9f1575SHawking Zhang 	.set_clockgating = mmhub_v4_1_0_set_clockgating,
6538e9f1575SHawking Zhang 	.get_clockgating = mmhub_v4_1_0_get_clockgating,
6548e9f1575SHawking Zhang 	.setup_vm_pt_regs = mmhub_v4_1_0_setup_vm_pt_regs,
6558e9f1575SHawking Zhang };
656