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 "amdgpu_atombios.h" 25 #include "nbio_v7_11.h" 26 27 #include "nbio/nbio_7_11_0_offset.h" 28 #include "nbio/nbio_7_11_0_sh_mask.h" 29 #include <uapi/linux/kfd_ioctl.h> 30 31 static void nbio_v7_11_remap_hdp_registers(struct amdgpu_device *adev) 32 { 33 WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_MEM_FLUSH_CNTL, 34 adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL); 35 WREG32_SOC15(NBIO, 0, regBIF_BX0_REMAP_HDP_REG_FLUSH_CNTL, 36 adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL); 37 } 38 39 static u32 nbio_v7_11_get_rev_id(struct amdgpu_device *adev) 40 { 41 u32 tmp; 42 43 tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0); 44 tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; 45 tmp >>= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; 46 47 return tmp; 48 } 49 50 static void nbio_v7_11_mc_access_enable(struct amdgpu_device *adev, bool enable) 51 { 52 if (enable) 53 WREG32_SOC15(NBIO, 0, regBIF_BX1_BIF_FB_EN, 54 BIF_BX1_BIF_FB_EN__FB_READ_EN_MASK | 55 BIF_BX1_BIF_FB_EN__FB_WRITE_EN_MASK); 56 else 57 WREG32_SOC15(NBIO, 0, regBIF_BX1_BIF_FB_EN, 0); 58 } 59 60 static u32 nbio_v7_11_get_memsize(struct amdgpu_device *adev) 61 { 62 return RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_CONFIG_MEMSIZE); 63 } 64 65 static void nbio_v7_11_sdma_doorbell_range(struct amdgpu_device *adev, int instance, 66 bool use_doorbell, int doorbell_index, 67 int doorbell_size) 68 { 69 u32 reg = SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_CSDMA_DOORBELL_RANGE); 70 u32 doorbell_range = RREG32_PCIE_PORT(reg); 71 72 if (use_doorbell) { 73 doorbell_range = REG_SET_FIELD(doorbell_range, 74 GDC0_BIF_CSDMA_DOORBELL_RANGE, 75 OFFSET, doorbell_index); 76 doorbell_range = REG_SET_FIELD(doorbell_range, 77 GDC0_BIF_CSDMA_DOORBELL_RANGE, 78 SIZE, doorbell_size); 79 } else { 80 doorbell_range = REG_SET_FIELD(doorbell_range, 81 GDC0_BIF_CSDMA_DOORBELL_RANGE, 82 SIZE, 0); 83 } 84 85 WREG32_PCIE_PORT(reg, doorbell_range); 86 } 87 88 static void nbio_v7_11_vpe_doorbell_range(struct amdgpu_device *adev, int instance, 89 bool use_doorbell, int doorbell_index, 90 int doorbell_size) 91 { 92 u32 reg = instance == 0 ? 93 SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_VPE_DOORBELL_RANGE) : 94 SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_VPE1_DOORBELL_RANGE); 95 u32 doorbell_range = RREG32_PCIE_PORT(reg); 96 97 if (use_doorbell) { 98 doorbell_range = REG_SET_FIELD(doorbell_range, 99 GDC0_BIF_VPE_DOORBELL_RANGE, 100 OFFSET, doorbell_index); 101 doorbell_range = REG_SET_FIELD(doorbell_range, 102 GDC0_BIF_VPE_DOORBELL_RANGE, 103 SIZE, doorbell_size); 104 } else { 105 doorbell_range = REG_SET_FIELD(doorbell_range, 106 GDC0_BIF_VPE_DOORBELL_RANGE, 107 SIZE, 0); 108 } 109 110 WREG32_PCIE_PORT(reg, doorbell_range); 111 } 112 113 static void nbio_v7_11_vcn_doorbell_range(struct amdgpu_device *adev, 114 bool use_doorbell, 115 int doorbell_index, int instance) 116 { 117 u32 reg = instance == 0 ? 118 SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_VCN0_DOORBELL_RANGE): 119 SOC15_REG_OFFSET(NBIO, 0, regGDC0_BIF_VCN1_DOORBELL_RANGE); 120 121 u32 doorbell_range = RREG32_PCIE_PORT(reg); 122 123 if (use_doorbell) { 124 doorbell_range = REG_SET_FIELD(doorbell_range, 125 GDC0_BIF_VCN0_DOORBELL_RANGE, OFFSET, 126 doorbell_index); 127 doorbell_range = REG_SET_FIELD(doorbell_range, 128 GDC0_BIF_VCN0_DOORBELL_RANGE, SIZE, 8); 129 } else { 130 doorbell_range = REG_SET_FIELD(doorbell_range, 131 GDC0_BIF_VCN0_DOORBELL_RANGE, SIZE, 0); 132 } 133 134 WREG32_PCIE_PORT(reg, doorbell_range); 135 } 136 137 static void nbio_v7_11_enable_doorbell_aperture(struct amdgpu_device *adev, 138 bool enable) 139 { 140 u32 reg; 141 142 143 reg = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN); 144 reg = REG_SET_FIELD(reg, RCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN, 145 BIF_DOORBELL_APER_EN, enable ? 1 : 0); 146 147 WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF0_0_RCC_DOORBELL_APER_EN, reg); 148 } 149 150 static void nbio_v7_11_enable_doorbell_selfring_aperture(struct amdgpu_device *adev, 151 bool enable) 152 { 153 u32 tmp = 0; 154 155 if (enable) { 156 tmp = REG_SET_FIELD(tmp, BIF_BX_PF1_DOORBELL_SELFRING_GPA_APER_CNTL, 157 DOORBELL_SELFRING_GPA_APER_EN, 1) | 158 REG_SET_FIELD(tmp, BIF_BX_PF1_DOORBELL_SELFRING_GPA_APER_CNTL, 159 DOORBELL_SELFRING_GPA_APER_MODE, 1) | 160 REG_SET_FIELD(tmp, BIF_BX_PF1_DOORBELL_SELFRING_GPA_APER_CNTL, 161 DOORBELL_SELFRING_GPA_APER_SIZE, 0); 162 163 WREG32_SOC15(NBIO, 0, 164 regBIF_BX_PF1_DOORBELL_SELFRING_GPA_APER_BASE_LOW, 165 lower_32_bits(adev->doorbell.base)); 166 WREG32_SOC15(NBIO, 0, 167 regBIF_BX_PF1_DOORBELL_SELFRING_GPA_APER_BASE_HIGH, 168 upper_32_bits(adev->doorbell.base)); 169 } 170 171 WREG32_SOC15(NBIO, 0, regBIF_BX_PF1_DOORBELL_SELFRING_GPA_APER_CNTL, tmp); 172 } 173 174 175 static void nbio_v7_11_ih_doorbell_range(struct amdgpu_device *adev, 176 bool use_doorbell, int doorbell_index) 177 { 178 u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0,regGDC0_BIF_IH_DOORBELL_RANGE); 179 180 if (use_doorbell) { 181 ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, 182 GDC0_BIF_IH_DOORBELL_RANGE, OFFSET, 183 doorbell_index); 184 ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, 185 GDC0_BIF_IH_DOORBELL_RANGE, SIZE, 186 2); 187 } else { 188 ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, 189 GDC0_BIF_IH_DOORBELL_RANGE, SIZE, 190 0); 191 } 192 193 WREG32_SOC15(NBIO, 0, regGDC0_BIF_IH_DOORBELL_RANGE, 194 ih_doorbell_range); 195 } 196 197 static void nbio_v7_11_ih_control(struct amdgpu_device *adev) 198 { 199 u32 interrupt_cntl; 200 201 /* setup interrupt control */ 202 WREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL2, 203 adev->dummy_page_addr >> 8); 204 205 interrupt_cntl = RREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL); 206 /* 207 * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi 208 * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN 209 */ 210 interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX1_INTERRUPT_CNTL, 211 IH_DUMMY_RD_OVERRIDE, 0); 212 213 /* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */ 214 interrupt_cntl = REG_SET_FIELD(interrupt_cntl, BIF_BX1_INTERRUPT_CNTL, 215 IH_REQ_NONSNOOP_EN, 0); 216 217 WREG32_SOC15(NBIO, 0, regBIF_BX1_INTERRUPT_CNTL, interrupt_cntl); 218 } 219 220 static u32 nbio_v7_11_get_hdp_flush_req_offset(struct amdgpu_device *adev) 221 { 222 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_GPU_HDP_FLUSH_REQ); 223 } 224 225 static u32 nbio_v7_11_get_hdp_flush_done_offset(struct amdgpu_device *adev) 226 { 227 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_GPU_HDP_FLUSH_DONE); 228 } 229 230 static u32 nbio_v7_11_get_pcie_index_offset(struct amdgpu_device *adev) 231 { 232 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX1_PCIE_INDEX2); 233 } 234 235 static u32 nbio_v7_11_get_pcie_data_offset(struct amdgpu_device *adev) 236 { 237 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX1_PCIE_DATA2); 238 } 239 240 static u32 nbio_v7_11_get_pcie_port_index_offset(struct amdgpu_device *adev) 241 { 242 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_RSMU_INDEX); 243 } 244 245 static u32 nbio_v7_11_get_pcie_port_data_offset(struct amdgpu_device *adev) 246 { 247 return SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_RSMU_DATA); 248 } 249 250 const struct nbio_hdp_flush_reg nbio_v7_11_hdp_flush_reg = { 251 .ref_and_mask_cp0 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP0_MASK, 252 .ref_and_mask_cp1 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP1_MASK, 253 .ref_and_mask_cp2 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP2_MASK, 254 .ref_and_mask_cp3 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP3_MASK, 255 .ref_and_mask_cp4 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP4_MASK, 256 .ref_and_mask_cp5 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP5_MASK, 257 .ref_and_mask_cp6 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP6_MASK, 258 .ref_and_mask_cp7 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP7_MASK, 259 .ref_and_mask_cp8 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP8_MASK, 260 .ref_and_mask_cp9 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__CP9_MASK, 261 .ref_and_mask_sdma0 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__SDMA0_MASK, 262 .ref_and_mask_sdma1 = BIF_BX_PF1_GPU_HDP_FLUSH_DONE__SDMA1_MASK, 263 }; 264 265 static void nbio_v7_11_init_registers(struct amdgpu_device *adev) 266 { 267 uint32_t def, data; 268 269 def = data = RREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3); 270 data = REG_SET_FIELD(data, BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, 271 CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1); 272 data = REG_SET_FIELD(data, BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, 273 CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV, 1); 274 275 if (def != data) 276 WREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, data); 277 278 } 279 280 static void nbio_v7_11_update_medium_grain_clock_gating(struct amdgpu_device *adev, 281 bool enable) 282 { 283 uint32_t def, data; 284 285 if (!(adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG)) 286 return; 287 288 def = data = RREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL); 289 if (enable) { 290 data |= (BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK | 291 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK | 292 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK | 293 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK | 294 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK | 295 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK); 296 } else { 297 data &= ~(BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK | 298 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__TXCLK_DYN_GATE_ENABLE_MASK | 299 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__TXCLK_LCNT_GATE_ENABLE_MASK | 300 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__TXCLK_REGS_GATE_ENABLE_MASK | 301 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__TXCLK_PRBS_GATE_ENABLE_MASK | 302 BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__REFCLK_REGS_GATE_ENABLE_MASK); 303 } 304 305 if (def != data) 306 WREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL, data); 307 } 308 309 static void nbio_v7_11_update_medium_grain_light_sleep(struct amdgpu_device *adev, 310 bool enable) 311 { 312 uint32_t def, data; 313 314 if (!(adev->cg_flags & AMD_CG_SUPPORT_BIF_LS)) 315 return; 316 317 def = data = RREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_CNTL2); 318 if (enable) 319 data |= BIF_BIF256_CI256_RC3X4_USB4_PCIE_CNTL2__SLV_MEM_LS_EN_MASK; 320 else 321 data &= ~BIF_BIF256_CI256_RC3X4_USB4_PCIE_CNTL2__SLV_MEM_LS_EN_MASK; 322 323 if (def != data) 324 WREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_CNTL2, data); 325 326 def = data = RREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1); 327 if (enable) { 328 data |= (BIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK | 329 BIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK); 330 } else { 331 data &= ~(BIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK | 332 BIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK); 333 } 334 335 if (def != data) 336 WREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1, data); 337 } 338 339 static void nbio_v7_11_get_clockgating_state(struct amdgpu_device *adev, 340 u64 *flags) 341 { 342 uint32_t data; 343 344 /* AMD_CG_SUPPORT_BIF_MGCG */ 345 data = RREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL); 346 if (data & BIF_BIF256_CI256_RC3X4_USB4_CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK) 347 *flags |= AMD_CG_SUPPORT_BIF_MGCG; 348 349 /* AMD_CG_SUPPORT_BIF_LS */ 350 data = RREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_CNTL2); 351 if (data & BIF_BIF256_CI256_RC3X4_USB4_PCIE_CNTL2__SLV_MEM_LS_EN_MASK) 352 *flags |= AMD_CG_SUPPORT_BIF_LS; 353 } 354 355 #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) 356 357 static void nbio_v7_11_set_reg_remap(struct amdgpu_device *adev) 358 { 359 if (!amdgpu_sriov_vf(adev) && (PAGE_SIZE <= 4096)) { 360 adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; 361 adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; 362 } else { 363 adev->rmmio_remap.reg_offset = 364 SOC15_REG_OFFSET(NBIO, 0, regBIF_BX_PF1_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; 365 adev->rmmio_remap.bus_addr = 0; 366 } 367 } 368 369 const struct amdgpu_nbio_funcs nbio_v7_11_funcs = { 370 .get_hdp_flush_req_offset = nbio_v7_11_get_hdp_flush_req_offset, 371 .get_hdp_flush_done_offset = nbio_v7_11_get_hdp_flush_done_offset, 372 .get_pcie_index_offset = nbio_v7_11_get_pcie_index_offset, 373 .get_pcie_data_offset = nbio_v7_11_get_pcie_data_offset, 374 .get_pcie_port_index_offset = nbio_v7_11_get_pcie_port_index_offset, 375 .get_pcie_port_data_offset = nbio_v7_11_get_pcie_port_data_offset, 376 .get_rev_id = nbio_v7_11_get_rev_id, 377 .mc_access_enable = nbio_v7_11_mc_access_enable, 378 .get_memsize = nbio_v7_11_get_memsize, 379 .sdma_doorbell_range = nbio_v7_11_sdma_doorbell_range, 380 .vcn_doorbell_range = nbio_v7_11_vcn_doorbell_range, 381 .vpe_doorbell_range = nbio_v7_11_vpe_doorbell_range, 382 .enable_doorbell_aperture = nbio_v7_11_enable_doorbell_aperture, 383 .enable_doorbell_selfring_aperture = nbio_v7_11_enable_doorbell_selfring_aperture, 384 .ih_doorbell_range = nbio_v7_11_ih_doorbell_range, 385 .update_medium_grain_clock_gating = nbio_v7_11_update_medium_grain_clock_gating, 386 .update_medium_grain_light_sleep = nbio_v7_11_update_medium_grain_light_sleep, 387 .get_clockgating_state = nbio_v7_11_get_clockgating_state, 388 .ih_control = nbio_v7_11_ih_control, 389 .init_registers = nbio_v7_11_init_registers, 390 .remap_hdp_registers = nbio_v7_11_remap_hdp_registers, 391 .set_reg_remap = nbio_v7_11_set_reg_remap, 392 }; 393