162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2016 Advanced Micro Devices, Inc. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1262306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#ifndef __SOC15_COMMON_H__ 2562306a36Sopenharmony_ci#define __SOC15_COMMON_H__ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* GET_INST returns the physical instance corresponding to a logical instance */ 2862306a36Sopenharmony_ci#define GET_INST(ip, inst) \ 2962306a36Sopenharmony_ci (adev->ip_map.logical_to_dev_inst ? \ 3062306a36Sopenharmony_ci adev->ip_map.logical_to_dev_inst(adev, ip##_HWIP, inst) : inst) 3162306a36Sopenharmony_ci#define GET_MASK(ip, mask) \ 3262306a36Sopenharmony_ci (adev->ip_map.logical_to_dev_mask ? \ 3362306a36Sopenharmony_ci adev->ip_map.logical_to_dev_mask(adev, ip##_HWIP, mask) : mask) 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/* Register Access Macros */ 3662306a36Sopenharmony_ci#define SOC15_REG_OFFSET(ip, inst, reg) (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) 3762306a36Sopenharmony_ci#define SOC15_REG_OFFSET1(ip, inst, reg, offset) \ 3862306a36Sopenharmony_ci (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + (reg)+(offset)) 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define __WREG32_SOC15_RLC__(reg, value, flag, hwip, inst) \ 4162306a36Sopenharmony_ci ((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs && adev->gfx.rlc.rlcg_reg_access_supported) ? \ 4262306a36Sopenharmony_ci amdgpu_sriov_wreg(adev, reg, value, flag, hwip, inst) : \ 4362306a36Sopenharmony_ci WREG32(reg, value)) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define __RREG32_SOC15_RLC__(reg, flag, hwip, inst) \ 4662306a36Sopenharmony_ci ((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs && adev->gfx.rlc.rlcg_reg_access_supported) ? \ 4762306a36Sopenharmony_ci amdgpu_sriov_rreg(adev, reg, flag, hwip, inst) : \ 4862306a36Sopenharmony_ci RREG32(reg)) 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define WREG32_FIELD15(ip, idx, reg, field, val) \ 5162306a36Sopenharmony_ci __WREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, \ 5262306a36Sopenharmony_ci (__RREG32_SOC15_RLC__( \ 5362306a36Sopenharmony_ci adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, \ 5462306a36Sopenharmony_ci 0, ip##_HWIP, idx) & \ 5562306a36Sopenharmony_ci ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field), \ 5662306a36Sopenharmony_ci 0, ip##_HWIP, idx) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define WREG32_FIELD15_PREREG(ip, idx, reg_name, field, val) \ 5962306a36Sopenharmony_ci __WREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][idx][reg##reg_name##_BASE_IDX] + reg##reg_name, \ 6062306a36Sopenharmony_ci (__RREG32_SOC15_RLC__( \ 6162306a36Sopenharmony_ci adev->reg_offset[ip##_HWIP][idx][reg##reg_name##_BASE_IDX] + reg##reg_name, \ 6262306a36Sopenharmony_ci 0, ip##_HWIP, idx) & \ 6362306a36Sopenharmony_ci ~REG_FIELD_MASK(reg_name, field)) | (val) << REG_FIELD_SHIFT(reg_name, field), \ 6462306a36Sopenharmony_ci 0, ip##_HWIP, idx) 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#define RREG32_SOC15(ip, inst, reg) \ 6762306a36Sopenharmony_ci __RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \ 6862306a36Sopenharmony_ci 0, ip##_HWIP, inst) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#define RREG32_SOC15_IP(ip, reg) __RREG32_SOC15_RLC__(reg, 0, ip##_HWIP, 0) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define RREG32_SOC15_IP_NO_KIQ(ip, reg) __RREG32_SOC15_RLC__(reg, AMDGPU_REGS_NO_KIQ, ip##_HWIP, 0) 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci#define RREG32_SOC15_NO_KIQ(ip, inst, reg) \ 7562306a36Sopenharmony_ci __RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \ 7662306a36Sopenharmony_ci AMDGPU_REGS_NO_KIQ, ip##_HWIP, inst) 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#define RREG32_SOC15_OFFSET(ip, inst, reg, offset) \ 7962306a36Sopenharmony_ci __RREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + (reg)) + \ 8062306a36Sopenharmony_ci (offset), 0, ip##_HWIP, inst) 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci#define WREG32_SOC15(ip, inst, reg, value) \ 8362306a36Sopenharmony_ci __WREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), \ 8462306a36Sopenharmony_ci value, 0, ip##_HWIP, inst) 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci#define WREG32_SOC15_IP(ip, reg, value) \ 8762306a36Sopenharmony_ci __WREG32_SOC15_RLC__(reg, value, 0, ip##_HWIP, 0) 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci#define WREG32_SOC15_IP_NO_KIQ(ip, reg, value) \ 9062306a36Sopenharmony_ci __WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ, ip##_HWIP, 0) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \ 9362306a36Sopenharmony_ci __WREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \ 9462306a36Sopenharmony_ci value, AMDGPU_REGS_NO_KIQ, ip##_HWIP, inst) 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci#define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \ 9762306a36Sopenharmony_ci __WREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, \ 9862306a36Sopenharmony_ci value, 0, ip##_HWIP, inst) 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci#define SOC15_WAIT_ON_RREG(ip, inst, reg, expected_value, mask) \ 10162306a36Sopenharmony_ci amdgpu_device_wait_on_rreg(adev, inst, \ 10262306a36Sopenharmony_ci (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + (reg)), \ 10362306a36Sopenharmony_ci #reg, expected_value, mask) 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci#define SOC15_WAIT_ON_RREG_OFFSET(ip, inst, reg, offset, expected_value, mask) \ 10662306a36Sopenharmony_ci amdgpu_device_wait_on_rreg(adev, inst, \ 10762306a36Sopenharmony_ci (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + (reg) + (offset)), \ 10862306a36Sopenharmony_ci #reg, expected_value, mask) 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci#define WREG32_RLC(reg, value) \ 11162306a36Sopenharmony_ci __WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_RLC, GC_HWIP, 0) 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci#define WREG32_RLC_EX(prefix, reg, value, inst) \ 11462306a36Sopenharmony_ci do { \ 11562306a36Sopenharmony_ci if (amdgpu_sriov_fullaccess(adev)) { \ 11662306a36Sopenharmony_ci uint32_t i = 0; \ 11762306a36Sopenharmony_ci uint32_t retries = 50000; \ 11862306a36Sopenharmony_ci uint32_t r0 = adev->reg_offset[GC_HWIP][inst][prefix##SCRATCH_REG0_BASE_IDX] + prefix##SCRATCH_REG0; \ 11962306a36Sopenharmony_ci uint32_t r1 = adev->reg_offset[GC_HWIP][inst][prefix##SCRATCH_REG1_BASE_IDX] + prefix##SCRATCH_REG1; \ 12062306a36Sopenharmony_ci uint32_t spare_int = adev->reg_offset[GC_HWIP][inst][prefix##RLC_SPARE_INT_BASE_IDX] + prefix##RLC_SPARE_INT; \ 12162306a36Sopenharmony_ci WREG32(r0, value); \ 12262306a36Sopenharmony_ci WREG32(r1, (reg | 0x80000000)); \ 12362306a36Sopenharmony_ci WREG32(spare_int, 0x1); \ 12462306a36Sopenharmony_ci for (i = 0; i < retries; i++) { \ 12562306a36Sopenharmony_ci u32 tmp = RREG32(r1); \ 12662306a36Sopenharmony_ci if (!(tmp & 0x80000000)) \ 12762306a36Sopenharmony_ci break; \ 12862306a36Sopenharmony_ci udelay(10); \ 12962306a36Sopenharmony_ci } \ 13062306a36Sopenharmony_ci if (i >= retries) \ 13162306a36Sopenharmony_ci pr_err("timeout: rlcg program reg:0x%05x failed !\n", reg); \ 13262306a36Sopenharmony_ci } else { \ 13362306a36Sopenharmony_ci WREG32(reg, value); \ 13462306a36Sopenharmony_ci } \ 13562306a36Sopenharmony_ci } while (0) 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci/* shadow the registers in the callback function */ 13862306a36Sopenharmony_ci#define WREG32_SOC15_RLC_SHADOW(ip, inst, reg, value) \ 13962306a36Sopenharmony_ci __WREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value, AMDGPU_REGS_RLC, GC_HWIP, inst) 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* for GC only */ 14262306a36Sopenharmony_ci#define RREG32_RLC(reg) \ 14362306a36Sopenharmony_ci __RREG32_SOC15_RLC__(reg, AMDGPU_REGS_RLC, GC_HWIP) 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci#define WREG32_RLC_NO_KIQ(reg, value, hwip) \ 14662306a36Sopenharmony_ci __WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ | AMDGPU_REGS_RLC, hwip, 0) 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci#define RREG32_RLC_NO_KIQ(reg, hwip) \ 14962306a36Sopenharmony_ci __RREG32_SOC15_RLC__(reg, AMDGPU_REGS_NO_KIQ | AMDGPU_REGS_RLC, hwip, 0) 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci#define WREG32_SOC15_RLC_SHADOW_EX(prefix, ip, inst, reg, value) \ 15262306a36Sopenharmony_ci do { \ 15362306a36Sopenharmony_ci uint32_t target_reg = adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg;\ 15462306a36Sopenharmony_ci if (amdgpu_sriov_fullaccess(adev)) { \ 15562306a36Sopenharmony_ci uint32_t r2 = adev->reg_offset[GC_HWIP][inst][prefix##SCRATCH_REG1_BASE_IDX] + prefix##SCRATCH_REG2; \ 15662306a36Sopenharmony_ci uint32_t r3 = adev->reg_offset[GC_HWIP][inst][prefix##SCRATCH_REG1_BASE_IDX] + prefix##SCRATCH_REG3; \ 15762306a36Sopenharmony_ci uint32_t grbm_cntl = adev->reg_offset[GC_HWIP][inst][prefix##GRBM_GFX_CNTL_BASE_IDX] + prefix##GRBM_GFX_CNTL; \ 15862306a36Sopenharmony_ci uint32_t grbm_idx = adev->reg_offset[GC_HWIP][inst][prefix##GRBM_GFX_INDEX_BASE_IDX] + prefix##GRBM_GFX_INDEX; \ 15962306a36Sopenharmony_ci if (target_reg == grbm_cntl) \ 16062306a36Sopenharmony_ci WREG32(r2, value); \ 16162306a36Sopenharmony_ci else if (target_reg == grbm_idx) \ 16262306a36Sopenharmony_ci WREG32(r3, value); \ 16362306a36Sopenharmony_ci WREG32(target_reg, value); \ 16462306a36Sopenharmony_ci } else { \ 16562306a36Sopenharmony_ci WREG32(target_reg, value); \ 16662306a36Sopenharmony_ci } \ 16762306a36Sopenharmony_ci } while (0) 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci#define RREG32_SOC15_RLC(ip, inst, reg) \ 17062306a36Sopenharmony_ci __RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, AMDGPU_REGS_RLC, ip##_HWIP, inst) 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci#define WREG32_SOC15_RLC(ip, inst, reg, value) \ 17362306a36Sopenharmony_ci do { \ 17462306a36Sopenharmony_ci uint32_t target_reg = adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg;\ 17562306a36Sopenharmony_ci __WREG32_SOC15_RLC__(target_reg, value, AMDGPU_REGS_RLC, ip##_HWIP, inst); \ 17662306a36Sopenharmony_ci } while (0) 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci#define WREG32_SOC15_RLC_EX(prefix, ip, inst, reg, value) \ 17962306a36Sopenharmony_ci do { \ 18062306a36Sopenharmony_ci uint32_t target_reg = adev->reg_offset[GC_HWIP][inst][reg##_BASE_IDX] + reg;\ 18162306a36Sopenharmony_ci WREG32_RLC_EX(prefix, target_reg, value, inst); \ 18262306a36Sopenharmony_ci } while (0) 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci#define WREG32_FIELD15_RLC(ip, idx, reg, field, val) \ 18562306a36Sopenharmony_ci __WREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg), \ 18662306a36Sopenharmony_ci (__RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, \ 18762306a36Sopenharmony_ci AMDGPU_REGS_RLC, ip##_HWIP, idx) & \ 18862306a36Sopenharmony_ci ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field), \ 18962306a36Sopenharmony_ci AMDGPU_REGS_RLC, ip##_HWIP, idx) 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci#define WREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset, value) \ 19262306a36Sopenharmony_ci __WREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value, AMDGPU_REGS_RLC, ip##_HWIP, inst) 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#define RREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset) \ 19562306a36Sopenharmony_ci __RREG32_SOC15_RLC__((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, AMDGPU_REGS_RLC, ip##_HWIP, inst) 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/* inst equals to ext for some IPs */ 19862306a36Sopenharmony_ci#define RREG32_SOC15_EXT(ip, inst, reg, ext) \ 19962306a36Sopenharmony_ci RREG32_PCIE_EXT((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) * 4 \ 20062306a36Sopenharmony_ci + adev->asic_funcs->encode_ext_smn_addressing(ext)) \ 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci#define WREG32_SOC15_EXT(ip, inst, reg, ext, value) \ 20362306a36Sopenharmony_ci WREG32_PCIE_EXT((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) * 4 \ 20462306a36Sopenharmony_ci + adev->asic_funcs->encode_ext_smn_addressing(ext), \ 20562306a36Sopenharmony_ci value) \ 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci#endif 208