1 /* 2 * Copyright 2021 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 #include "amdgpu.h" 24 #include "nbio_v7_7.h" 25 26 #include "nbio/nbio_7_7_0_offset.h" 27 #include "nbio/nbio_7_7_0_sh_mask.h" 28 #include <uapi/linux/kfd_ioctl.h> 29 30 static void nbio_v7_7_remap_hdp_registers(struct amdgpu_device *adev) 31 { 32 WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL, 33 adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL); 34 WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL, 35 adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL); 36 } 37 38 static u32 nbio_v7_7_get_rev_id(struct amdgpu_device *adev) 39 { 40 u32 tmp; 41 42 tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0); 43 tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; 44 tmp >>= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; 45 46 return tmp; 47 } 48 49 static void nbio_v7_7_mc_access_enable(struct amdgpu_device *adev, bool enable) 50 { 51 if (enable) 52 WREG32_SOC15(NBIO, 0, regBIF_BX1_BIF_FB_EN, 53 BIF_BX1_BIF_FB_EN__FB_READ_EN_MASK | 54 BIF_BX1_BIF_FB_EN__FB_WRITE_EN_MASK); 55 else 56 WREG32_SOC15(NBIO, 0, regBIF_BX1_BIF_FB_EN, 0); 57 } 58 59 static u32 nbio_v7_7_get_memsize(struct amdgpu_device *adev) 60 { 61 return RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_CONFIG_MEMSIZE); 62 } 63 64 static void nbio_v7_7_sdma_doorbell_range(struct amdgpu_device *adev, int instance, 65 bool use_doorbell, int doorbell_index, 66 int doorbell_size) 67 { 68 u32 reg = SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_CSDMA_DOORBELL_RANGE); 69 u32 doorbell_range = RREG32_PCIE_PORT(reg); 70 71 if (use_doorbell) { 72 doorbell_range = REG_SET_FIELD(doorbell_range, 73 GDC0_BIF_CSDMA_DOORBELL_RANGE, 74 OFFSET, doorbell_index); 75 doorbell_range = REG_SET_FIELD(doorbell_range, 76 GDC0_BIF_CSDMA_DOORBELL_RANGE, 77 SIZE, doorbell_size); 78 } else { 79 doorbell_range = REG_SET_FIELD(doorbell_range, 80 GDC0_BIF_SDMA0_DOORBELL_RANGE, 81 SIZE, 0); 82 } 83 84 WREG32_PCIE_PORT(reg, doorbell_range); 85 } 86 87 static void nbio_v7_7_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell, 88 int doorbell_index, int instance) 89 { 90 u32 reg = SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_VCN0_DOORBELL_RANGE); 91 u32 doorbell_range = RREG32_PCIE_PORT(reg); 92 93 if (use_doorbell) { 94 doorbell_range = REG_SET_FIELD(doorbell_range, 95 GDC0_BIF_VCN0_DOORBELL_RANGE, OFFSET, 96 doorbell_index); 97 doorbell_range = REG_SET_FIELD(doorbell_range, 98 GDC0_BIF_VCN0_DOORBELL_RANGE, SIZE, 8); 99 } else { 100 doorbell_range = REG_SET_FIELD(doorbell_range, 101 GDC0_BIF_VCN0_DOORBELL_RANGE, SIZE, 0); 102 } 103 104 WREG32_PCIE_PORT(reg, doorbell_range); 105 } 106 107 static void nbio_v7_7_enable_doorbell_aperture(struct amdgpu_device *adev, 108 bool enable) 109 { 110 u32 reg; 111 112 reg = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN); 113 reg = REG_SET_FIELD(reg, RCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN, 114 BIF_DOORBELL_APER_EN, enable ? 1 : 0); 115 116 WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN, reg); 117 } 118 119 static void nbio_v7_7_enable_doorbell_selfring_aperture(struct amdgpu_device *adev, 120 bool enable) 121 { 122 u32 tmp = 0; 123 124 if (enable) { 125 tmp = REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, 126 DOORBELL_SELFRING_GPA_APER_EN, 1) | 127 REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, 128 DOORBELL_SELFRING_GPA_APER_MODE, 1) | 129 REG_SET_FIELD(tmp, BIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, 130 DOORBELL_SELFRING_GPA_APER_SIZE, 0); 131 132 WREG32_SOC15(NBIO, 0, 133 regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_LOW, 134 lower_32_bits(adev->doorbell.base)); 135 WREG32_SOC15(NBIO, 0, 136 regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_BASE_HIGH, 137 upper_32_bits(adev->doorbell.base)); 138 } 139 140 WREG32_SOC15(NBIO, 0, regBIF_BX_PF0_DOORBELL_SELFRING_GPA_APER_CNTL, 141 tmp); 142 } 143 144 145 static void nbio_v7_7_ih_doorbell_range(struct amdgpu_device *adev, 146 bool use_doorbell, int doorbell_index) 147 { 148 u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0, 149 regGDC0_BIF_IH_DOORBELL_RANGE); 150 151 if (use_doorbell) { 152 ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, 153 GDC0_BIF_IH_DOORBELL_RANGE, OFFSET, 154 doorbell_index); 155 ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, 156 GDC0_BIF_IH_DOORBELL_RANGE, SIZE, 157 2); 158 } else { 159 ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, 160 GDC0_BIF_IH_DOORBELL_RANGE, SIZE, 161 0); 162 } 163 164 WREG32_SOC15(NBIO, 0, regGDC0_BIF_IH_DOORBELL_RANGE, 165 ih_doorbell_range); 166 } 167 168 static void nbio_v7_7_ih_control(struct amdgpu_device *adev) 169 { 170 u32 interrupt_cntl; 171 172 /* setup interrupt control */ 173 WREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL2, 174 adev->dummy_page_addr >> 8); 175 176 interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL); 177 /* 178 * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi 179 * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN 180 */ 181 interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX1_INTERRUPT_CNTL, 182 IH_DUMMY_RD_OVERRIDE, 0); 183 184 /* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */ 185 interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX1_INTERRUPT_CNTL, 186 IH_REQ_NONSNOOP_EN, 0); 187 188 WREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL, interrupt_cntl); 189 } 190 191 static u32 nbio_v7_7_get_hdp_flush_req_offset(struct amdgpu_device *adev) 192 { 193 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_REQ); 194 } 195 196 static u32 nbio_v7_7_get_hdp_flush_done_offset(struct amdgpu_device *adev) 197 { 198 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_GPU_HDP_FLUSH_DONE); 199 } 200 201 static u32 nbio_v7_7_get_pcie_index_offset(struct amdgpu_device *adev) 202 { 203 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_INDEX2); 204 } 205 206 static u32 nbio_v7_7_get_pcie_data_offset(struct amdgpu_device *adev) 207 { 208 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX0_PCIE_DATA2); 209 } 210 211 static u32 nbio_v7_7_get_pcie_port_index_offset(struct amdgpu_device *adev) 212 { 213 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_RSMU_INDEX); 214 } 215 216 static u32 nbio_v7_7_get_pcie_port_data_offset(struct amdgpu_device *adev) 217 { 218 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF0_RSMU_DATA); 219 } 220 221 const struct nbio_hdp_flush_reg nbio_v7_7_hdp_flush_reg = { 222 .ref_and_mask_cp0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP0_MASK, 223 .ref_and_mask_cp1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP1_MASK, 224 .ref_and_mask_cp2 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP2_MASK, 225 .ref_and_mask_cp3 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP3_MASK, 226 .ref_and_mask_cp4 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP4_MASK, 227 .ref_and_mask_cp5 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP5_MASK, 228 .ref_and_mask_cp6 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP6_MASK, 229 .ref_and_mask_cp7 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP7_MASK, 230 .ref_and_mask_cp8 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP8_MASK, 231 .ref_and_mask_cp9 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__CP9_MASK, 232 .ref_and_mask_sdma0 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA0_MASK, 233 .ref_and_mask_sdma1 = BIF_BX_PF0_GPU_HDP_FLUSH_DONE__SDMA1_MASK, 234 }; 235 236 static void nbio_v7_7_init_registers(struct amdgpu_device *adev) 237 { 238 uint32_t def, data; 239 240 def = data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_MST_CTRL_3); 241 data = REG_SET_FIELD(data, BIF0_PCIE_MST_CTRL_3, 242 CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1); 243 data = REG_SET_FIELD(data, BIF0_PCIE_MST_CTRL_3, 244 CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV, 1); 245 246 if (def != data) 247 WREG32_SOC15(NBIO, 0, regBIF0_PCIE_MST_CTRL_3, data); 248 249 switch (amdgpu_ip_version(adev, NBIO_HWIP, 0)) { 250 case IP_VERSION(7, 7, 0): 251 data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4) & ~BIT(23); 252 WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4, data); 253 break; 254 } 255 } 256 257 static void nbio_v7_7_update_medium_grain_clock_gating(struct amdgpu_device *adev, 258 bool enable) 259 { 260 uint32_t def, data; 261 262 if (!(adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG)) 263 return; 264 265 def = data = RREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL); 266 if (enable) { 267 data |= (BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK | 268 BIF0_CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK | 269 BIF0_CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK | 270 BIF0_CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK | 271 BIF0_CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK | 272 BIF0_CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK); 273 } else { 274 data &= ~(BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK | 275 BIF0_CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK | 276 BIF0_CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK | 277 BIF0_CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK | 278 BIF0_CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK | 279 BIF0_CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK); 280 } 281 282 if (def != data) 283 WREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL, data); 284 } 285 286 static void nbio_v7_7_update_medium_grain_light_sleep(struct amdgpu_device *adev, 287 bool enable) 288 { 289 uint32_t def, data; 290 291 if (!(adev->cg_flags & AMD_CG_SUPPORT_BIF_LS)) 292 return; 293 294 def = data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2); 295 if (enable) 296 data |= BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK; 297 else 298 data &= ~BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK; 299 300 if (def != data) 301 WREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2, data); 302 303 def = data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_TX_POWER_CTRL_1); 304 if (enable) { 305 data |= (BIF0_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK | 306 BIF0_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK); 307 } else { 308 data &= ~(BIF0_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK | 309 BIF0_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK); 310 } 311 312 if (def != data) 313 WREG32_SOC15(NBIO, 0, regBIF0_PCIE_TX_POWER_CTRL_1, data); 314 } 315 316 static void nbio_v7_7_get_clockgating_state(struct amdgpu_device *adev, 317 u64 *flags) 318 { 319 uint32_t data; 320 321 /* AMD_CG_SUPPORT_BIF_MGCG */ 322 data = RREG32_SOC15(NBIO, 0, regBIF0_CPM_CONTROL); 323 if (data & BIF0_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK) 324 *flags |= AMD_CG_SUPPORT_BIF_MGCG; 325 326 /* AMD_CG_SUPPORT_BIF_LS */ 327 data = RREG32_SOC15(NBIO, 0, regBIF0_PCIE_CNTL2); 328 if (data & BIF0_PCIE_CNTL2__SLV_MEM_LS_EN_MASK) 329 *flags |= AMD_CG_SUPPORT_BIF_LS; 330 } 331 332 #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) 333 334 static void nbio_v7_7_set_reg_remap(struct amdgpu_device *adev) 335 { 336 if (!amdgpu_sriov_vf(adev) && (PAGE_SIZE <= 4096)) { 337 adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; 338 adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; 339 } else { 340 adev->rmmio_remap.reg_offset = 341 SOC15_REG_OFFSET(NBIO, 0, 342 regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; 343 adev->rmmio_remap.bus_addr = 0; 344 } 345 } 346 347 const struct amdgpu_nbio_funcs nbio_v7_7_funcs = { 348 .get_hdp_flush_req_offset = nbio_v7_7_get_hdp_flush_req_offset, 349 .get_hdp_flush_done_offset = nbio_v7_7_get_hdp_flush_done_offset, 350 .get_pcie_index_offset = nbio_v7_7_get_pcie_index_offset, 351 .get_pcie_data_offset = nbio_v7_7_get_pcie_data_offset, 352 .get_pcie_port_index_offset = nbio_v7_7_get_pcie_port_index_offset, 353 .get_pcie_port_data_offset = nbio_v7_7_get_pcie_port_data_offset, 354 .get_rev_id = nbio_v7_7_get_rev_id, 355 .mc_access_enable = nbio_v7_7_mc_access_enable, 356 .get_memsize = nbio_v7_7_get_memsize, 357 .sdma_doorbell_range = nbio_v7_7_sdma_doorbell_range, 358 .vcn_doorbell_range = nbio_v7_7_vcn_doorbell_range, 359 .enable_doorbell_aperture = nbio_v7_7_enable_doorbell_aperture, 360 .enable_doorbell_selfring_aperture = nbio_v7_7_enable_doorbell_selfring_aperture, 361 .ih_doorbell_range = nbio_v7_7_ih_doorbell_range, 362 .update_medium_grain_clock_gating = nbio_v7_7_update_medium_grain_clock_gating, 363 .update_medium_grain_light_sleep = nbio_v7_7_update_medium_grain_light_sleep, 364 .get_clockgating_state = nbio_v7_7_get_clockgating_state, 365 .ih_control = nbio_v7_7_ih_control, 366 .init_registers = nbio_v7_7_init_registers, 367 .remap_hdp_registers = nbio_v7_7_remap_hdp_registers, 368 .set_reg_remap = nbio_v7_7_set_reg_remap, 369 }; 370