110c4ad3aSHuang Rui /* 210c4ad3aSHuang Rui * Copyright 2022 Advanced Micro Devices, Inc. 310c4ad3aSHuang Rui * 410c4ad3aSHuang Rui * Permission is hereby granted, free of charge, to any person obtaining a 510c4ad3aSHuang Rui * copy of this software and associated documentation files (the "Software"), 610c4ad3aSHuang Rui * to deal in the Software without restriction, including without limitation 710c4ad3aSHuang Rui * the rights to use, copy, modify, merge, publish, distribute, sublicense, 810c4ad3aSHuang Rui * and/or sell copies of the Software, and to permit persons to whom the 910c4ad3aSHuang Rui * Software is furnished to do so, subject to the following conditions: 1010c4ad3aSHuang Rui * 1110c4ad3aSHuang Rui * The above copyright notice and this permission notice shall be included in 1210c4ad3aSHuang Rui * all copies or substantial portions of the Software. 1310c4ad3aSHuang Rui * 1410c4ad3aSHuang Rui * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1510c4ad3aSHuang Rui * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1610c4ad3aSHuang Rui * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1710c4ad3aSHuang Rui * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1810c4ad3aSHuang Rui * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1910c4ad3aSHuang Rui * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2010c4ad3aSHuang Rui * OTHER DEALINGS IN THE SOFTWARE. 2110c4ad3aSHuang Rui * 2210c4ad3aSHuang Rui */ 2310c4ad3aSHuang Rui 2410c4ad3aSHuang Rui #include "amdgpu.h" 2510c4ad3aSHuang Rui #include "mmhub_v3_0_1.h" 2610c4ad3aSHuang Rui 2710c4ad3aSHuang Rui #include "mmhub/mmhub_3_0_1_offset.h" 2810c4ad3aSHuang Rui #include "mmhub/mmhub_3_0_1_sh_mask.h" 2910c4ad3aSHuang Rui #include "navi10_enum.h" 3010c4ad3aSHuang Rui 3110c4ad3aSHuang Rui #include "soc15_common.h" 3210c4ad3aSHuang Rui 3310c4ad3aSHuang Rui #define regMMVM_L2_CNTL3_DEFAULT 0x80100007 3410c4ad3aSHuang Rui #define regMMVM_L2_CNTL4_DEFAULT 0x000000c1 3510c4ad3aSHuang Rui #define regMMVM_L2_CNTL5_DEFAULT 0x00003fe0 3610c4ad3aSHuang Rui 3710c4ad3aSHuang Rui static const char *mmhub_client_ids_v3_0_1[][2] = { 3810c4ad3aSHuang Rui [0][0] = "VMC", 3910c4ad3aSHuang Rui [4][0] = "DCEDMC", 4010c4ad3aSHuang Rui [5][0] = "DCEVGA", 4110c4ad3aSHuang Rui [6][0] = "MP0", 4210c4ad3aSHuang Rui [7][0] = "MP1", 4310c4ad3aSHuang Rui [8][0] = "MPIO", 4410c4ad3aSHuang Rui [16][0] = "HDP", 4510c4ad3aSHuang Rui [17][0] = "LSDMA", 4610c4ad3aSHuang Rui [18][0] = "JPEG", 4710c4ad3aSHuang Rui [19][0] = "VCNU0", 4810c4ad3aSHuang Rui [21][0] = "VSCH", 4910c4ad3aSHuang Rui [22][0] = "VCNU1", 5010c4ad3aSHuang Rui [23][0] = "VCN1", 5110c4ad3aSHuang Rui [32+20][0] = "VCN0", 5210c4ad3aSHuang Rui [2][1] = "DBGUNBIO", 5310c4ad3aSHuang Rui [3][1] = "DCEDWB", 5410c4ad3aSHuang Rui [4][1] = "DCEDMC", 5510c4ad3aSHuang Rui [5][1] = "DCEVGA", 5610c4ad3aSHuang Rui [6][1] = "MP0", 5710c4ad3aSHuang Rui [7][1] = "MP1", 5810c4ad3aSHuang Rui [8][1] = "MPIO", 5910c4ad3aSHuang Rui [10][1] = "DBGU0", 6010c4ad3aSHuang Rui [11][1] = "DBGU1", 6110c4ad3aSHuang Rui [12][1] = "DBGU2", 6210c4ad3aSHuang Rui [13][1] = "DBGU3", 6310c4ad3aSHuang Rui [14][1] = "XDP", 6410c4ad3aSHuang Rui [15][1] = "OSSSYS", 6510c4ad3aSHuang Rui [16][1] = "HDP", 6610c4ad3aSHuang Rui [17][1] = "LSDMA", 6710c4ad3aSHuang Rui [18][1] = "JPEG", 6810c4ad3aSHuang Rui [19][1] = "VCNU0", 6910c4ad3aSHuang Rui [20][1] = "VCN0", 7010c4ad3aSHuang Rui [21][1] = "VSCH", 7110c4ad3aSHuang Rui [22][1] = "VCNU1", 7210c4ad3aSHuang Rui [23][1] = "VCN1", 7310c4ad3aSHuang Rui }; 7410c4ad3aSHuang Rui 7510c4ad3aSHuang Rui static uint32_t mmhub_v3_0_1_get_invalidate_req(unsigned int vmid, 7610c4ad3aSHuang Rui uint32_t flush_type) 7710c4ad3aSHuang Rui { 7810c4ad3aSHuang Rui u32 req = 0; 7910c4ad3aSHuang Rui 8010c4ad3aSHuang Rui /* invalidate using legacy mode on vmid*/ 8110c4ad3aSHuang Rui req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, 8210c4ad3aSHuang Rui PER_VMID_INVALIDATE_REQ, 1 << vmid); 8310c4ad3aSHuang Rui req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, flush_type); 8410c4ad3aSHuang Rui req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1); 8510c4ad3aSHuang Rui req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1); 8610c4ad3aSHuang Rui req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE1, 1); 8710c4ad3aSHuang Rui req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE2, 1); 8810c4ad3aSHuang Rui req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, INVALIDATE_L1_PTES, 1); 8910c4ad3aSHuang Rui req = REG_SET_FIELD(req, MMVM_INVALIDATE_ENG0_REQ, 9010c4ad3aSHuang Rui CLEAR_PROTECTION_FAULT_STATUS_ADDR, 0); 9110c4ad3aSHuang Rui 9210c4ad3aSHuang Rui return req; 9310c4ad3aSHuang Rui } 9410c4ad3aSHuang Rui 9510c4ad3aSHuang Rui static void 9610c4ad3aSHuang Rui mmhub_v3_0_1_print_l2_protection_fault_status(struct amdgpu_device *adev, 9710c4ad3aSHuang Rui uint32_t status) 9810c4ad3aSHuang Rui { 9910c4ad3aSHuang Rui uint32_t cid, rw; 10010c4ad3aSHuang Rui const char *mmhub_cid = NULL; 10110c4ad3aSHuang Rui 10210c4ad3aSHuang Rui cid = REG_GET_FIELD(status, 10310c4ad3aSHuang Rui MMVM_L2_PROTECTION_FAULT_STATUS, CID); 10410c4ad3aSHuang Rui rw = REG_GET_FIELD(status, 10510c4ad3aSHuang Rui MMVM_L2_PROTECTION_FAULT_STATUS, RW); 10610c4ad3aSHuang Rui 10710c4ad3aSHuang Rui dev_err(adev->dev, 10810c4ad3aSHuang Rui "MMVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n", 10910c4ad3aSHuang Rui status); 11010c4ad3aSHuang Rui 11110c4ad3aSHuang Rui switch (adev->ip_versions[MMHUB_HWIP][0]) { 11210c4ad3aSHuang Rui case IP_VERSION(3, 0, 1): 11310c4ad3aSHuang Rui mmhub_cid = mmhub_client_ids_v3_0_1[cid][rw]; 11410c4ad3aSHuang Rui break; 11510c4ad3aSHuang Rui default: 11610c4ad3aSHuang Rui mmhub_cid = NULL; 11710c4ad3aSHuang Rui break; 11810c4ad3aSHuang Rui } 11910c4ad3aSHuang Rui 12010c4ad3aSHuang Rui dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", 12110c4ad3aSHuang Rui mmhub_cid ? mmhub_cid : "unknown", cid); 12210c4ad3aSHuang Rui dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n", 12310c4ad3aSHuang Rui REG_GET_FIELD(status, 12410c4ad3aSHuang Rui MMVM_L2_PROTECTION_FAULT_STATUS, MORE_FAULTS)); 12510c4ad3aSHuang Rui dev_err(adev->dev, "\t WALKER_ERROR: 0x%lx\n", 12610c4ad3aSHuang Rui REG_GET_FIELD(status, 12710c4ad3aSHuang Rui MMVM_L2_PROTECTION_FAULT_STATUS, WALKER_ERROR)); 12810c4ad3aSHuang Rui dev_err(adev->dev, "\t PERMISSION_FAULTS: 0x%lx\n", 12910c4ad3aSHuang Rui REG_GET_FIELD(status, 13010c4ad3aSHuang Rui MMVM_L2_PROTECTION_FAULT_STATUS, PERMISSION_FAULTS)); 13110c4ad3aSHuang Rui dev_err(adev->dev, "\t MAPPING_ERROR: 0x%lx\n", 13210c4ad3aSHuang Rui REG_GET_FIELD(status, 13310c4ad3aSHuang Rui MMVM_L2_PROTECTION_FAULT_STATUS, MAPPING_ERROR)); 13410c4ad3aSHuang Rui dev_err(adev->dev, "\t RW: 0x%x\n", rw); 13510c4ad3aSHuang Rui } 13610c4ad3aSHuang Rui 13710c4ad3aSHuang Rui static void mmhub_v3_0_1_setup_vm_pt_regs(struct amdgpu_device *adev, 13810c4ad3aSHuang Rui uint32_t vmid, 13910c4ad3aSHuang Rui uint64_t page_table_base) 14010c4ad3aSHuang Rui { 14110c4ad3aSHuang Rui struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; 14210c4ad3aSHuang Rui 14310c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32, 14410c4ad3aSHuang Rui hub->ctx_addr_distance * vmid, 14510c4ad3aSHuang Rui lower_32_bits(page_table_base)); 14610c4ad3aSHuang Rui 14710c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32, 14810c4ad3aSHuang Rui hub->ctx_addr_distance * vmid, 14910c4ad3aSHuang Rui upper_32_bits(page_table_base)); 15010c4ad3aSHuang Rui } 15110c4ad3aSHuang Rui 15210c4ad3aSHuang Rui static void mmhub_v3_0_1_init_gart_aperture_regs(struct amdgpu_device *adev) 15310c4ad3aSHuang Rui { 15410c4ad3aSHuang Rui uint64_t pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); 15510c4ad3aSHuang Rui 15610c4ad3aSHuang Rui mmhub_v3_0_1_setup_vm_pt_regs(adev, 0, pt_base); 15710c4ad3aSHuang Rui 15810c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32, 15910c4ad3aSHuang Rui (u32)(adev->gmc.gart_start >> 12)); 16010c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32, 16110c4ad3aSHuang Rui (u32)(adev->gmc.gart_start >> 44)); 16210c4ad3aSHuang Rui 16310c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32, 16410c4ad3aSHuang Rui (u32)(adev->gmc.gart_end >> 12)); 16510c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32, 16610c4ad3aSHuang Rui (u32)(adev->gmc.gart_end >> 44)); 16710c4ad3aSHuang Rui } 16810c4ad3aSHuang Rui 16910c4ad3aSHuang Rui static void mmhub_v3_0_1_init_system_aperture_regs(struct amdgpu_device *adev) 17010c4ad3aSHuang Rui { 17110c4ad3aSHuang Rui uint64_t value; 17210c4ad3aSHuang Rui uint32_t tmp; 17310c4ad3aSHuang Rui 17410c4ad3aSHuang Rui /* Program the AGP BAR */ 17510c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0); 17610c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, adev->gmc.agp_start >> 24); 17710c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, adev->gmc.agp_end >> 24); 17810c4ad3aSHuang Rui 17910c4ad3aSHuang Rui /* 18010c4ad3aSHuang Rui * the new L1 policy will block SRIOV guest from writing 18110c4ad3aSHuang Rui * these regs, and they will be programed at host. 18210c4ad3aSHuang Rui * so skip programing these regs. 18310c4ad3aSHuang Rui */ 18410c4ad3aSHuang Rui /* Program the system aperture low logical page number. */ 18510c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR, 18610c4ad3aSHuang Rui adev->gmc.vram_start >> 18); 18710c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_HIGH_ADDR, 18810c4ad3aSHuang Rui adev->gmc.vram_end >> 18); 18910c4ad3aSHuang Rui 19010c4ad3aSHuang Rui /* Set default page address. */ 191*7ccfd79fSChristian König value = adev->mem_scratch.gpu_addr - adev->gmc.vram_start + 19210c4ad3aSHuang Rui adev->vm_manager.vram_base_offset; 19310c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, 19410c4ad3aSHuang Rui (u32)(value >> 12)); 19510c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, 19610c4ad3aSHuang Rui (u32)(value >> 44)); 19710c4ad3aSHuang Rui 19810c4ad3aSHuang Rui /* Program "protection fault". */ 19910c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_LO32, 20010c4ad3aSHuang Rui (u32)(adev->dummy_page_addr >> 12)); 20110c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_DEFAULT_ADDR_HI32, 20210c4ad3aSHuang Rui (u32)((u64)adev->dummy_page_addr >> 44)); 20310c4ad3aSHuang Rui 20410c4ad3aSHuang Rui tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL2); 20510c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL2, 20610c4ad3aSHuang Rui ACTIVE_PAGE_MIGRATION_PTE_READ_RETRY, 1); 20710c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL2, tmp); 20810c4ad3aSHuang Rui } 20910c4ad3aSHuang Rui 21010c4ad3aSHuang Rui static void mmhub_v3_0_1_init_tlb_regs(struct amdgpu_device *adev) 21110c4ad3aSHuang Rui { 21210c4ad3aSHuang Rui uint32_t tmp; 21310c4ad3aSHuang Rui 21410c4ad3aSHuang Rui /* Setup TLB control */ 21510c4ad3aSHuang Rui tmp = RREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL); 21610c4ad3aSHuang Rui 21710c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 1); 21810c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE, 3); 21910c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, 22010c4ad3aSHuang Rui ENABLE_ADVANCED_DRIVER_MODEL, 1); 22110c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, 22210c4ad3aSHuang Rui SYSTEM_APERTURE_UNMAPPED_ACCESS, 0); 22310c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ECO_BITS, 0); 22410c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, 22510c4ad3aSHuang Rui MTYPE, MTYPE_UC); /* UC, uncached */ 22610c4ad3aSHuang Rui 22710c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL, tmp); 22810c4ad3aSHuang Rui } 22910c4ad3aSHuang Rui 23010c4ad3aSHuang Rui static void mmhub_v3_0_1_init_cache_regs(struct amdgpu_device *adev) 23110c4ad3aSHuang Rui { 23210c4ad3aSHuang Rui uint32_t tmp; 23310c4ad3aSHuang Rui 23410c4ad3aSHuang Rui /* Setup L2 cache */ 23510c4ad3aSHuang Rui tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL); 23610c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 1); 23710c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0); 23810c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, 23910c4ad3aSHuang Rui ENABLE_DEFAULT_PAGE_OUT_TO_SYSTEM_MEMORY, 1); 24010c4ad3aSHuang Rui /* XXX for emulation, Refer to closed source code.*/ 24110c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE, 24210c4ad3aSHuang Rui 0); 24310c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, PDE_FAULT_CLASSIFICATION, 0); 24410c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, CONTEXT1_IDENTITY_ACCESS_MODE, 1); 24510c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, IDENTITY_MODE_FRAGMENT_SIZE, 0); 24610c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL, tmp); 24710c4ad3aSHuang Rui 24810c4ad3aSHuang Rui tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL2); 24910c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1); 25010c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL2, INVALIDATE_L2_CACHE, 1); 25110c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL2, tmp); 25210c4ad3aSHuang Rui 25310c4ad3aSHuang Rui tmp = regMMVM_L2_CNTL3_DEFAULT; 25410c4ad3aSHuang Rui if (adev->gmc.translate_further) { 25510c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 12); 25610c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, 25710c4ad3aSHuang Rui L2_CACHE_BIGK_FRAGMENT_SIZE, 9); 25810c4ad3aSHuang Rui } else { 25910c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 9); 26010c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, 26110c4ad3aSHuang Rui L2_CACHE_BIGK_FRAGMENT_SIZE, 6); 26210c4ad3aSHuang Rui } 26310c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL3, tmp); 26410c4ad3aSHuang Rui 26510c4ad3aSHuang Rui tmp = regMMVM_L2_CNTL4_DEFAULT; 26610c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PDE_REQUEST_PHYSICAL, 0); 26710c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL4, VMC_TAP_PTE_REQUEST_PHYSICAL, 0); 26810c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL4, tmp); 26910c4ad3aSHuang Rui 27010c4ad3aSHuang Rui tmp = regMMVM_L2_CNTL5_DEFAULT; 27110c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0); 272347fafe0SYang Wang WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL5, tmp); 27310c4ad3aSHuang Rui } 27410c4ad3aSHuang Rui 27510c4ad3aSHuang Rui static void mmhub_v3_0_1_enable_system_domain(struct amdgpu_device *adev) 27610c4ad3aSHuang Rui { 27710c4ad3aSHuang Rui uint32_t tmp; 27810c4ad3aSHuang Rui 27910c4ad3aSHuang Rui tmp = RREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_CNTL); 28010c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1); 28110c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0); 28210c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, 28310c4ad3aSHuang Rui RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0); 28410c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_CONTEXT0_CNTL, tmp); 28510c4ad3aSHuang Rui } 28610c4ad3aSHuang Rui 28710c4ad3aSHuang Rui static void mmhub_v3_0_1_disable_identity_aperture(struct amdgpu_device *adev) 28810c4ad3aSHuang Rui { 28910c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, 29010c4ad3aSHuang Rui regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_LO32, 29110c4ad3aSHuang Rui 0xFFFFFFFF); 29210c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, 29310c4ad3aSHuang Rui regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_LOW_ADDR_HI32, 29410c4ad3aSHuang Rui 0x0000000F); 29510c4ad3aSHuang Rui 29610c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, 29710c4ad3aSHuang Rui regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_LO32, 0); 29810c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, 29910c4ad3aSHuang Rui regMMVM_L2_CONTEXT1_IDENTITY_APERTURE_HIGH_ADDR_HI32, 0); 30010c4ad3aSHuang Rui 30110c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_LO32, 30210c4ad3aSHuang Rui 0); 30310c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_CONTEXT_IDENTITY_PHYSICAL_OFFSET_HI32, 30410c4ad3aSHuang Rui 0); 30510c4ad3aSHuang Rui } 30610c4ad3aSHuang Rui 30710c4ad3aSHuang Rui static void mmhub_v3_0_1_setup_vmid_config(struct amdgpu_device *adev) 30810c4ad3aSHuang Rui { 30910c4ad3aSHuang Rui struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; 31010c4ad3aSHuang Rui int i; 31110c4ad3aSHuang Rui uint32_t tmp; 31210c4ad3aSHuang Rui 31310c4ad3aSHuang Rui for (i = 0; i <= 14; i++) { 31410c4ad3aSHuang Rui tmp = RREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_CNTL, i); 31510c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, ENABLE_CONTEXT, 1); 31610c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, PAGE_TABLE_DEPTH, 31710c4ad3aSHuang Rui adev->vm_manager.num_level); 31810c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 31910c4ad3aSHuang Rui RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); 32010c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 32110c4ad3aSHuang Rui DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, 32210c4ad3aSHuang Rui 1); 32310c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 32410c4ad3aSHuang Rui PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, 1); 32510c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 32610c4ad3aSHuang Rui VALID_PROTECTION_FAULT_ENABLE_DEFAULT, 1); 32710c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 32810c4ad3aSHuang Rui READ_PROTECTION_FAULT_ENABLE_DEFAULT, 1); 32910c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 33010c4ad3aSHuang Rui WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); 33110c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 33210c4ad3aSHuang Rui EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, 1); 33310c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 33410c4ad3aSHuang Rui PAGE_TABLE_BLOCK_SIZE, 33510c4ad3aSHuang Rui adev->vm_manager.block_size - 9); 33610c4ad3aSHuang Rui /* Send no-retry XNACK on fault to suppress VM fault storm. */ 33710c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT1_CNTL, 33810c4ad3aSHuang Rui RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 33910c4ad3aSHuang Rui !amdgpu_noretry); 34010c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_CNTL, 34110c4ad3aSHuang Rui i * hub->ctx_distance, tmp); 34210c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, 34310c4ad3aSHuang Rui i * hub->ctx_addr_distance, 0); 34410c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32, 34510c4ad3aSHuang Rui i * hub->ctx_addr_distance, 0); 34610c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_LO32, 34710c4ad3aSHuang Rui i * hub->ctx_addr_distance, 34810c4ad3aSHuang Rui lower_32_bits(adev->vm_manager.max_pfn - 1)); 34910c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT1_PAGE_TABLE_END_ADDR_HI32, 35010c4ad3aSHuang Rui i * hub->ctx_addr_distance, 35110c4ad3aSHuang Rui upper_32_bits(adev->vm_manager.max_pfn - 1)); 35210c4ad3aSHuang Rui } 35310c4ad3aSHuang Rui 35410c4ad3aSHuang Rui hub->vm_cntx_cntl = tmp; 35510c4ad3aSHuang Rui } 35610c4ad3aSHuang Rui 35710c4ad3aSHuang Rui static void mmhub_v3_0_1_program_invalidation(struct amdgpu_device *adev) 35810c4ad3aSHuang Rui { 35910c4ad3aSHuang Rui struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; 36010c4ad3aSHuang Rui unsigned i; 36110c4ad3aSHuang Rui 36210c4ad3aSHuang Rui for (i = 0; i < 18; ++i) { 36310c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32, 36410c4ad3aSHuang Rui i * hub->eng_addr_distance, 0xffffffff); 36510c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ADDR_RANGE_HI32, 36610c4ad3aSHuang Rui i * hub->eng_addr_distance, 0x1f); 36710c4ad3aSHuang Rui } 36810c4ad3aSHuang Rui } 36910c4ad3aSHuang Rui 37010c4ad3aSHuang Rui static int mmhub_v3_0_1_gart_enable(struct amdgpu_device *adev) 37110c4ad3aSHuang Rui { 37210c4ad3aSHuang Rui /* GART Enable. */ 37310c4ad3aSHuang Rui mmhub_v3_0_1_init_gart_aperture_regs(adev); 37410c4ad3aSHuang Rui mmhub_v3_0_1_init_system_aperture_regs(adev); 37510c4ad3aSHuang Rui mmhub_v3_0_1_init_tlb_regs(adev); 37610c4ad3aSHuang Rui mmhub_v3_0_1_init_cache_regs(adev); 37710c4ad3aSHuang Rui 37810c4ad3aSHuang Rui mmhub_v3_0_1_enable_system_domain(adev); 37910c4ad3aSHuang Rui mmhub_v3_0_1_disable_identity_aperture(adev); 38010c4ad3aSHuang Rui mmhub_v3_0_1_setup_vmid_config(adev); 38110c4ad3aSHuang Rui mmhub_v3_0_1_program_invalidation(adev); 38210c4ad3aSHuang Rui 38310c4ad3aSHuang Rui return 0; 38410c4ad3aSHuang Rui } 38510c4ad3aSHuang Rui 38610c4ad3aSHuang Rui static void mmhub_v3_0_1_gart_disable(struct amdgpu_device *adev) 38710c4ad3aSHuang Rui { 38810c4ad3aSHuang Rui struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; 38910c4ad3aSHuang Rui u32 tmp; 39010c4ad3aSHuang Rui u32 i; 39110c4ad3aSHuang Rui 39210c4ad3aSHuang Rui /* Disable all tables */ 39310c4ad3aSHuang Rui for (i = 0; i < 16; i++) 39410c4ad3aSHuang Rui WREG32_SOC15_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_CNTL, 39510c4ad3aSHuang Rui i * hub->ctx_distance, 0); 39610c4ad3aSHuang Rui 39710c4ad3aSHuang Rui /* Setup TLB control */ 39810c4ad3aSHuang Rui tmp = RREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL); 39910c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0); 40010c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMMC_VM_MX_L1_TLB_CNTL, 40110c4ad3aSHuang Rui ENABLE_ADVANCED_DRIVER_MODEL, 0); 40210c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMMC_VM_MX_L1_TLB_CNTL, tmp); 40310c4ad3aSHuang Rui 40410c4ad3aSHuang Rui /* Setup L2 cache */ 40510c4ad3aSHuang Rui tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL); 40610c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL, ENABLE_L2_CACHE, 0); 40710c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL, tmp); 40810c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL3, 0); 40910c4ad3aSHuang Rui } 41010c4ad3aSHuang Rui 41110c4ad3aSHuang Rui /** 41210c4ad3aSHuang Rui * mmhub_v3_0_1_set_fault_enable_default - update GART/VM fault handling 41310c4ad3aSHuang Rui * 41410c4ad3aSHuang Rui * @adev: amdgpu_device pointer 41510c4ad3aSHuang Rui * @value: true redirects VM faults to the default page 41610c4ad3aSHuang Rui */ 41710c4ad3aSHuang Rui static void mmhub_v3_0_1_set_fault_enable_default(struct amdgpu_device *adev, 41810c4ad3aSHuang Rui bool value) 41910c4ad3aSHuang Rui { 42010c4ad3aSHuang Rui u32 tmp; 42110c4ad3aSHuang Rui 42210c4ad3aSHuang Rui tmp = RREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL); 42310c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 42410c4ad3aSHuang Rui RANGE_PROTECTION_FAULT_ENABLE_DEFAULT, value); 42510c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 42610c4ad3aSHuang Rui PDE0_PROTECTION_FAULT_ENABLE_DEFAULT, value); 42710c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 42810c4ad3aSHuang Rui PDE1_PROTECTION_FAULT_ENABLE_DEFAULT, value); 42910c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 43010c4ad3aSHuang Rui PDE2_PROTECTION_FAULT_ENABLE_DEFAULT, value); 43110c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 43210c4ad3aSHuang Rui TRANSLATE_FURTHER_PROTECTION_FAULT_ENABLE_DEFAULT, 43310c4ad3aSHuang Rui value); 43410c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 43510c4ad3aSHuang Rui NACK_PROTECTION_FAULT_ENABLE_DEFAULT, value); 43610c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 43710c4ad3aSHuang Rui DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT, value); 43810c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 43910c4ad3aSHuang Rui VALID_PROTECTION_FAULT_ENABLE_DEFAULT, value); 44010c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 44110c4ad3aSHuang Rui READ_PROTECTION_FAULT_ENABLE_DEFAULT, value); 44210c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 44310c4ad3aSHuang Rui WRITE_PROTECTION_FAULT_ENABLE_DEFAULT, value); 44410c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 44510c4ad3aSHuang Rui EXECUTE_PROTECTION_FAULT_ENABLE_DEFAULT, value); 44610c4ad3aSHuang Rui if (!value) { 44710c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 44810c4ad3aSHuang Rui CRASH_ON_NO_RETRY_FAULT, 1); 44910c4ad3aSHuang Rui tmp = REG_SET_FIELD(tmp, MMVM_L2_PROTECTION_FAULT_CNTL, 45010c4ad3aSHuang Rui CRASH_ON_RETRY_FAULT, 1); 45110c4ad3aSHuang Rui } 45210c4ad3aSHuang Rui WREG32_SOC15(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL, tmp); 45310c4ad3aSHuang Rui } 45410c4ad3aSHuang Rui 45510c4ad3aSHuang Rui static const struct amdgpu_vmhub_funcs mmhub_v3_0_1_vmhub_funcs = { 45610c4ad3aSHuang Rui .print_l2_protection_fault_status = mmhub_v3_0_1_print_l2_protection_fault_status, 45710c4ad3aSHuang Rui .get_invalidate_req = mmhub_v3_0_1_get_invalidate_req, 45810c4ad3aSHuang Rui }; 45910c4ad3aSHuang Rui 46010c4ad3aSHuang Rui static void mmhub_v3_0_1_init(struct amdgpu_device *adev) 46110c4ad3aSHuang Rui { 46210c4ad3aSHuang Rui struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB_0]; 46310c4ad3aSHuang Rui 46410c4ad3aSHuang Rui hub->ctx0_ptb_addr_lo32 = 46510c4ad3aSHuang Rui SOC15_REG_OFFSET(MMHUB, 0, 46610c4ad3aSHuang Rui regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32); 46710c4ad3aSHuang Rui hub->ctx0_ptb_addr_hi32 = 46810c4ad3aSHuang Rui SOC15_REG_OFFSET(MMHUB, 0, 46910c4ad3aSHuang Rui regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); 47010c4ad3aSHuang Rui hub->vm_inv_eng0_sem = 47110c4ad3aSHuang Rui SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_SEM); 47210c4ad3aSHuang Rui hub->vm_inv_eng0_req = 47310c4ad3aSHuang Rui SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_REQ); 47410c4ad3aSHuang Rui hub->vm_inv_eng0_ack = 47510c4ad3aSHuang Rui SOC15_REG_OFFSET(MMHUB, 0, regMMVM_INVALIDATE_ENG0_ACK); 47610c4ad3aSHuang Rui hub->vm_context0_cntl = 47710c4ad3aSHuang Rui SOC15_REG_OFFSET(MMHUB, 0, regMMVM_CONTEXT0_CNTL); 47810c4ad3aSHuang Rui hub->vm_l2_pro_fault_status = 47910c4ad3aSHuang Rui SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_STATUS); 48010c4ad3aSHuang Rui hub->vm_l2_pro_fault_cntl = 48110c4ad3aSHuang Rui SOC15_REG_OFFSET(MMHUB, 0, regMMVM_L2_PROTECTION_FAULT_CNTL); 48210c4ad3aSHuang Rui 48310c4ad3aSHuang Rui hub->ctx_distance = regMMVM_CONTEXT1_CNTL - regMMVM_CONTEXT0_CNTL; 48410c4ad3aSHuang Rui hub->ctx_addr_distance = regMMVM_CONTEXT1_PAGE_TABLE_BASE_ADDR_LO32 - 48510c4ad3aSHuang Rui regMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_LO32; 48610c4ad3aSHuang Rui hub->eng_distance = regMMVM_INVALIDATE_ENG1_REQ - 48710c4ad3aSHuang Rui regMMVM_INVALIDATE_ENG0_REQ; 48810c4ad3aSHuang Rui hub->eng_addr_distance = regMMVM_INVALIDATE_ENG1_ADDR_RANGE_LO32 - 48910c4ad3aSHuang Rui regMMVM_INVALIDATE_ENG0_ADDR_RANGE_LO32; 49010c4ad3aSHuang Rui 49110c4ad3aSHuang Rui hub->vm_cntx_cntl_vm_fault = MMVM_CONTEXT1_CNTL__RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | 49210c4ad3aSHuang Rui MMVM_CONTEXT1_CNTL__DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | 49310c4ad3aSHuang Rui MMVM_CONTEXT1_CNTL__PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | 49410c4ad3aSHuang Rui MMVM_CONTEXT1_CNTL__VALID_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | 49510c4ad3aSHuang Rui MMVM_CONTEXT1_CNTL__READ_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | 49610c4ad3aSHuang Rui MMVM_CONTEXT1_CNTL__WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK | 49710c4ad3aSHuang Rui MMVM_CONTEXT1_CNTL__EXECUTE_PROTECTION_FAULT_ENABLE_INTERRUPT_MASK; 49810c4ad3aSHuang Rui 49910c4ad3aSHuang Rui hub->vmhub_funcs = &mmhub_v3_0_1_vmhub_funcs; 50010c4ad3aSHuang Rui } 50110c4ad3aSHuang Rui 50210c4ad3aSHuang Rui static u64 mmhub_v3_0_1_get_fb_location(struct amdgpu_device *adev) 50310c4ad3aSHuang Rui { 50410c4ad3aSHuang Rui u64 base; 50510c4ad3aSHuang Rui 50610c4ad3aSHuang Rui base = RREG32_SOC15(MMHUB, 0, regMMMC_VM_FB_LOCATION_BASE); 50710c4ad3aSHuang Rui base &= MMMC_VM_FB_LOCATION_BASE__FB_BASE_MASK; 50810c4ad3aSHuang Rui base <<= 24; 50910c4ad3aSHuang Rui 51010c4ad3aSHuang Rui return base; 51110c4ad3aSHuang Rui } 51210c4ad3aSHuang Rui 51310c4ad3aSHuang Rui static u64 mmhub_v3_0_1_get_mc_fb_offset(struct amdgpu_device *adev) 51410c4ad3aSHuang Rui { 51510c4ad3aSHuang Rui return (u64)RREG32_SOC15(MMHUB, 0, regMMMC_VM_FB_OFFSET) << 24; 51610c4ad3aSHuang Rui } 51710c4ad3aSHuang Rui 51810c4ad3aSHuang Rui static void mmhub_v3_0_1_update_medium_grain_clock_gating(struct amdgpu_device *adev, 51910c4ad3aSHuang Rui bool enable) 52010c4ad3aSHuang Rui { 5218172cebaSTim Huang uint32_t def, data; 5228172cebaSTim Huang 5238172cebaSTim Huang def = data = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG); 5248172cebaSTim Huang 5258172cebaSTim Huang if (enable) 5268172cebaSTim Huang data |= MM_ATC_L2_MISC_CG__ENABLE_MASK; 5278172cebaSTim Huang else 5288172cebaSTim Huang data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK; 5298172cebaSTim Huang 5308172cebaSTim Huang if (def != data) 5318172cebaSTim Huang WREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG, data); 53210c4ad3aSHuang Rui } 53310c4ad3aSHuang Rui 53410c4ad3aSHuang Rui static void mmhub_v3_0_1_update_medium_grain_light_sleep(struct amdgpu_device *adev, 53510c4ad3aSHuang Rui bool enable) 53610c4ad3aSHuang Rui { 5378172cebaSTim Huang uint32_t def, data; 5388172cebaSTim Huang 5398172cebaSTim Huang def = data = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG); 5408172cebaSTim Huang 5418172cebaSTim Huang if (enable) 5428172cebaSTim Huang data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; 5438172cebaSTim Huang else 5448172cebaSTim Huang data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; 5458172cebaSTim Huang 5468172cebaSTim Huang if (def != data) 5478172cebaSTim Huang WREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG, data); 54810c4ad3aSHuang Rui } 54910c4ad3aSHuang Rui 55010c4ad3aSHuang Rui static int mmhub_v3_0_1_set_clockgating(struct amdgpu_device *adev, 55110c4ad3aSHuang Rui enum amd_clockgating_state state) 55210c4ad3aSHuang Rui { 5538172cebaSTim Huang if (amdgpu_sriov_vf(adev)) 5548172cebaSTim Huang return 0; 5558172cebaSTim Huang 55610c4ad3aSHuang Rui mmhub_v3_0_1_update_medium_grain_clock_gating(adev, 55710c4ad3aSHuang Rui state == AMD_CG_STATE_GATE); 55810c4ad3aSHuang Rui mmhub_v3_0_1_update_medium_grain_light_sleep(adev, 55910c4ad3aSHuang Rui state == AMD_CG_STATE_GATE); 56010c4ad3aSHuang Rui return 0; 56110c4ad3aSHuang Rui } 56210c4ad3aSHuang Rui 56310c4ad3aSHuang Rui static void mmhub_v3_0_1_get_clockgating(struct amdgpu_device *adev, u64 *flags) 56410c4ad3aSHuang Rui { 5658172cebaSTim Huang int data; 5668172cebaSTim Huang 5678172cebaSTim Huang if (amdgpu_sriov_vf(adev)) 5688172cebaSTim Huang *flags = 0; 5698172cebaSTim Huang 5708172cebaSTim Huang data = RREG32_SOC15(MMHUB, 0, regMM_ATC_L2_MISC_CG); 5718172cebaSTim Huang 5728172cebaSTim Huang /* AMD_CG_SUPPORT_MC_MGCG */ 5738172cebaSTim Huang if (data & MM_ATC_L2_MISC_CG__ENABLE_MASK) 5748172cebaSTim Huang *flags |= AMD_CG_SUPPORT_MC_MGCG; 5758172cebaSTim Huang 5768172cebaSTim Huang /* AMD_CG_SUPPORT_MC_LS */ 5778172cebaSTim Huang if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK) 5788172cebaSTim Huang *flags |= AMD_CG_SUPPORT_MC_LS; 57910c4ad3aSHuang Rui } 58010c4ad3aSHuang Rui 58110c4ad3aSHuang Rui const struct amdgpu_mmhub_funcs mmhub_v3_0_1_funcs = { 58210c4ad3aSHuang Rui .init = mmhub_v3_0_1_init, 58310c4ad3aSHuang Rui .get_fb_location = mmhub_v3_0_1_get_fb_location, 58410c4ad3aSHuang Rui .get_mc_fb_offset = mmhub_v3_0_1_get_mc_fb_offset, 58510c4ad3aSHuang Rui .gart_enable = mmhub_v3_0_1_gart_enable, 58610c4ad3aSHuang Rui .set_fault_enable_default = mmhub_v3_0_1_set_fault_enable_default, 58710c4ad3aSHuang Rui .gart_disable = mmhub_v3_0_1_gart_disable, 58810c4ad3aSHuang Rui .set_clockgating = mmhub_v3_0_1_set_clockgating, 58910c4ad3aSHuang Rui .get_clockgating = mmhub_v3_0_1_get_clockgating, 59010c4ad3aSHuang Rui .setup_vm_pt_regs = mmhub_v3_0_1_setup_vm_pt_regs, 59110c4ad3aSHuang Rui }; 592