Home | History | Annotate | Line # | Download | only in amdgpu
      1 /*	$NetBSD: amdgpu_nbio_v7_0.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2016 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  */
     25 #include <sys/cdefs.h>
     26 __KERNEL_RCSID(0, "$NetBSD: amdgpu_nbio_v7_0.c,v 1.2 2021/12/18 23:44:58 riastradh Exp $");
     27 
     28 #include "amdgpu.h"
     29 #include "amdgpu_atombios.h"
     30 #include "nbio_v7_0.h"
     31 
     32 #include "nbio/nbio_7_0_default.h"
     33 #include "nbio/nbio_7_0_offset.h"
     34 #include "nbio/nbio_7_0_sh_mask.h"
     35 #include "nbio/nbio_7_0_smn.h"
     36 #include "vega10_enum.h"
     37 #include <uapi/linux/kfd_ioctl.h>
     38 
     39 #define smnNBIF_MGCG_CTRL_LCLK	0x1013a05c
     40 
     41 static void nbio_v7_0_remap_hdp_registers(struct amdgpu_device *adev)
     42 {
     43 	WREG32_SOC15(NBIO, 0, mmREMAP_HDP_MEM_FLUSH_CNTL,
     44 		adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL);
     45 	WREG32_SOC15(NBIO, 0, mmREMAP_HDP_REG_FLUSH_CNTL,
     46 		adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL);
     47 }
     48 
     49 static u32 nbio_v7_0_get_rev_id(struct amdgpu_device *adev)
     50 {
     51         u32 tmp = RREG32_SOC15(NBIO, 0, mmRCC_DEV0_EPF0_STRAP0);
     52 
     53 	tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
     54 	tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
     55 
     56 	return tmp;
     57 }
     58 
     59 static void nbio_v7_0_mc_access_enable(struct amdgpu_device *adev, bool enable)
     60 {
     61 	if (enable)
     62 		WREG32_SOC15(NBIO, 0, mmBIF_FB_EN,
     63 			BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK);
     64 	else
     65 		WREG32_SOC15(NBIO, 0, mmBIF_FB_EN, 0);
     66 }
     67 
     68 static void nbio_v7_0_hdp_flush(struct amdgpu_device *adev,
     69 				struct amdgpu_ring *ring)
     70 {
     71 	if (!ring || !ring->funcs->emit_wreg)
     72 		WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
     73 	else
     74 		amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
     75 }
     76 
     77 static u32 nbio_v7_0_get_memsize(struct amdgpu_device *adev)
     78 {
     79 	return RREG32_SOC15(NBIO, 0, mmRCC_CONFIG_MEMSIZE);
     80 }
     81 
     82 static void nbio_v7_0_sdma_doorbell_range(struct amdgpu_device *adev, int instance,
     83 			bool use_doorbell, int doorbell_index, int doorbell_size)
     84 {
     85 	u32 reg = instance == 0 ? SOC15_REG_OFFSET(NBIO, 0, mmBIF_SDMA0_DOORBELL_RANGE) :
     86 			SOC15_REG_OFFSET(NBIO, 0, mmBIF_SDMA1_DOORBELL_RANGE);
     87 
     88 	u32 doorbell_range = RREG32(reg);
     89 
     90 	if (use_doorbell) {
     91 		doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, OFFSET, doorbell_index);
     92 		doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, doorbell_size);
     93 	} else
     94 		doorbell_range = REG_SET_FIELD(doorbell_range, BIF_SDMA0_DOORBELL_RANGE, SIZE, 0);
     95 
     96 	WREG32(reg, doorbell_range);
     97 }
     98 
     99 static void nbio_v7_0_vcn_doorbell_range(struct amdgpu_device *adev, bool use_doorbell,
    100 					 int doorbell_index, int instance)
    101 {
    102 	u32 reg = SOC15_REG_OFFSET(NBIO, 0, mmBIF_MMSCH0_DOORBELL_RANGE);
    103 
    104 	u32 doorbell_range = RREG32(reg);
    105 
    106 	if (use_doorbell) {
    107 		doorbell_range = REG_SET_FIELD(doorbell_range,
    108 					       BIF_MMSCH0_DOORBELL_RANGE, OFFSET,
    109 					       doorbell_index);
    110 		doorbell_range = REG_SET_FIELD(doorbell_range,
    111 					       BIF_MMSCH0_DOORBELL_RANGE, SIZE, 8);
    112 	} else
    113 		doorbell_range = REG_SET_FIELD(doorbell_range,
    114 					       BIF_MMSCH0_DOORBELL_RANGE, SIZE, 0);
    115 
    116 	WREG32(reg, doorbell_range);
    117 }
    118 
    119 static void nbio_v7_0_enable_doorbell_aperture(struct amdgpu_device *adev,
    120 					       bool enable)
    121 {
    122 	WREG32_FIELD15(NBIO, 0, RCC_DOORBELL_APER_EN, BIF_DOORBELL_APER_EN, enable ? 1 : 0);
    123 }
    124 
    125 static void nbio_v7_0_enable_doorbell_selfring_aperture(struct amdgpu_device *adev,
    126 							bool enable)
    127 {
    128 
    129 }
    130 
    131 static void nbio_v7_0_ih_doorbell_range(struct amdgpu_device *adev,
    132 					bool use_doorbell, int doorbell_index)
    133 {
    134 	u32 ih_doorbell_range = RREG32_SOC15(NBIO, 0 , mmBIF_IH_DOORBELL_RANGE);
    135 
    136 	if (use_doorbell) {
    137 		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index);
    138 		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 2);
    139 	} else
    140 		ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, SIZE, 0);
    141 
    142 	WREG32_SOC15(NBIO, 0, mmBIF_IH_DOORBELL_RANGE, ih_doorbell_range);
    143 }
    144 
    145 static uint32_t nbio_7_0_read_syshub_ind_mmr(struct amdgpu_device *adev, uint32_t offset)
    146 {
    147 	uint32_t data;
    148 
    149 	WREG32_SOC15(NBIO, 0, mmSYSHUB_INDEX, offset);
    150 	data = RREG32_SOC15(NBIO, 0, mmSYSHUB_DATA);
    151 
    152 	return data;
    153 }
    154 
    155 static void nbio_7_0_write_syshub_ind_mmr(struct amdgpu_device *adev, uint32_t offset,
    156 				       uint32_t data)
    157 {
    158 	WREG32_SOC15(NBIO, 0, mmSYSHUB_INDEX, offset);
    159 	WREG32_SOC15(NBIO, 0, mmSYSHUB_DATA, data);
    160 }
    161 
    162 static void nbio_v7_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,
    163 						       bool enable)
    164 {
    165 	uint32_t def, data;
    166 
    167 	/* NBIF_MGCG_CTRL_LCLK */
    168 	def = data = RREG32_PCIE(smnNBIF_MGCG_CTRL_LCLK);
    169 
    170 	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG))
    171 		data |= NBIF_MGCG_CTRL_LCLK__NBIF_MGCG_EN_LCLK_MASK;
    172 	else
    173 		data &= ~NBIF_MGCG_CTRL_LCLK__NBIF_MGCG_EN_LCLK_MASK;
    174 
    175 	if (def != data)
    176 		WREG32_PCIE(smnNBIF_MGCG_CTRL_LCLK, data);
    177 
    178 	/* SYSHUB_MGCG_CTRL_SOCCLK */
    179 	def = data = nbio_7_0_read_syshub_ind_mmr(adev, ixSYSHUB_MMREG_IND_SYSHUB_MGCG_CTRL_SOCCLK);
    180 
    181 	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG))
    182 		data |= SYSHUB_MMREG_DIRECT_SYSHUB_MGCG_CTRL_SOCCLK__SYSHUB_MGCG_EN_SOCCLK_MASK;
    183 	else
    184 		data &= ~SYSHUB_MMREG_DIRECT_SYSHUB_MGCG_CTRL_SOCCLK__SYSHUB_MGCG_EN_SOCCLK_MASK;
    185 
    186 	if (def != data)
    187 		nbio_7_0_write_syshub_ind_mmr(adev, ixSYSHUB_MMREG_IND_SYSHUB_MGCG_CTRL_SOCCLK, data);
    188 
    189 	/* SYSHUB_MGCG_CTRL_SHUBCLK */
    190 	def = data = nbio_7_0_read_syshub_ind_mmr(adev, ixSYSHUB_MMREG_IND_SYSHUB_MGCG_CTRL_SHUBCLK);
    191 
    192 	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_MGCG))
    193 		data |= SYSHUB_MMREG_DIRECT_SYSHUB_MGCG_CTRL_SHUBCLK__SYSHUB_MGCG_EN_SHUBCLK_MASK;
    194 	else
    195 		data &= ~SYSHUB_MMREG_DIRECT_SYSHUB_MGCG_CTRL_SHUBCLK__SYSHUB_MGCG_EN_SHUBCLK_MASK;
    196 
    197 	if (def != data)
    198 		nbio_7_0_write_syshub_ind_mmr(adev, ixSYSHUB_MMREG_IND_SYSHUB_MGCG_CTRL_SHUBCLK, data);
    199 }
    200 
    201 static void nbio_v7_0_update_medium_grain_light_sleep(struct amdgpu_device *adev,
    202 						      bool enable)
    203 {
    204 	uint32_t def, data;
    205 
    206 	def = data = RREG32_PCIE(smnPCIE_CNTL2);
    207 	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_BIF_LS)) {
    208 		data |= (PCIE_CNTL2__SLV_MEM_LS_EN_MASK |
    209 			 PCIE_CNTL2__MST_MEM_LS_EN_MASK |
    210 			 PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK);
    211 	} else {
    212 		data &= ~(PCIE_CNTL2__SLV_MEM_LS_EN_MASK |
    213 			  PCIE_CNTL2__MST_MEM_LS_EN_MASK |
    214 			  PCIE_CNTL2__REPLAY_MEM_LS_EN_MASK);
    215 	}
    216 
    217 	if (def != data)
    218 		WREG32_PCIE(smnPCIE_CNTL2, data);
    219 }
    220 
    221 static void nbio_v7_0_get_clockgating_state(struct amdgpu_device *adev,
    222 					    u32 *flags)
    223 {
    224 	int data;
    225 
    226 	/* AMD_CG_SUPPORT_BIF_MGCG */
    227 	data = RREG32_PCIE(smnCPM_CONTROL);
    228 	if (data & CPM_CONTROL__LCLK_DYN_GATE_ENABLE_MASK)
    229 		*flags |= AMD_CG_SUPPORT_BIF_MGCG;
    230 
    231 	/* AMD_CG_SUPPORT_BIF_LS */
    232 	data = RREG32_PCIE(smnPCIE_CNTL2);
    233 	if (data & PCIE_CNTL2__SLV_MEM_LS_EN_MASK)
    234 		*flags |= AMD_CG_SUPPORT_BIF_LS;
    235 }
    236 
    237 static void nbio_v7_0_ih_control(struct amdgpu_device *adev)
    238 {
    239 	u32 interrupt_cntl;
    240 
    241 	/* setup interrupt control */
    242 	WREG32_SOC15(NBIO, 0, mmINTERRUPT_CNTL2, adev->dummy_page_addr >> 8);
    243 	interrupt_cntl = RREG32_SOC15(NBIO, 0, mmINTERRUPT_CNTL);
    244 	/* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi
    245 	 * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN
    246 	 */
    247 	interrupt_cntl = REG_SET_FIELD(interrupt_cntl, INTERRUPT_CNTL, IH_DUMMY_RD_OVERRIDE, 0);
    248 	/* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */
    249 	interrupt_cntl = REG_SET_FIELD(interrupt_cntl, INTERRUPT_CNTL, IH_REQ_NONSNOOP_EN, 0);
    250 	WREG32_SOC15(NBIO, 0, mmINTERRUPT_CNTL, interrupt_cntl);
    251 }
    252 
    253 static u32 nbio_v7_0_get_hdp_flush_req_offset(struct amdgpu_device *adev)
    254 {
    255 	return SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_REQ);
    256 }
    257 
    258 static u32 nbio_v7_0_get_hdp_flush_done_offset(struct amdgpu_device *adev)
    259 {
    260 	return SOC15_REG_OFFSET(NBIO, 0, mmGPU_HDP_FLUSH_DONE);
    261 }
    262 
    263 static u32 nbio_v7_0_get_pcie_index_offset(struct amdgpu_device *adev)
    264 {
    265 	return SOC15_REG_OFFSET(NBIO, 0, mmPCIE_INDEX2);
    266 }
    267 
    268 static u32 nbio_v7_0_get_pcie_data_offset(struct amdgpu_device *adev)
    269 {
    270 	return SOC15_REG_OFFSET(NBIO, 0, mmPCIE_DATA2);
    271 }
    272 
    273 const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = {
    274 	.ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK,
    275 	.ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK,
    276 	.ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK,
    277 	.ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK,
    278 	.ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK,
    279 	.ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK,
    280 	.ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK,
    281 	.ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK,
    282 	.ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK,
    283 	.ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK,
    284 	.ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__SDMA0_MASK,
    285 	.ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK,
    286 };
    287 
    288 static void nbio_v7_0_detect_hw_virt(struct amdgpu_device *adev)
    289 {
    290 	if (is_virtual_machine())	/* passthrough mode exclus sriov mod */
    291 		adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
    292 }
    293 
    294 static void nbio_v7_0_init_registers(struct amdgpu_device *adev)
    295 {
    296 
    297 }
    298 
    299 const struct amdgpu_nbio_funcs nbio_v7_0_funcs = {
    300 	.get_hdp_flush_req_offset = nbio_v7_0_get_hdp_flush_req_offset,
    301 	.get_hdp_flush_done_offset = nbio_v7_0_get_hdp_flush_done_offset,
    302 	.get_pcie_index_offset = nbio_v7_0_get_pcie_index_offset,
    303 	.get_pcie_data_offset = nbio_v7_0_get_pcie_data_offset,
    304 	.get_rev_id = nbio_v7_0_get_rev_id,
    305 	.mc_access_enable = nbio_v7_0_mc_access_enable,
    306 	.hdp_flush = nbio_v7_0_hdp_flush,
    307 	.get_memsize = nbio_v7_0_get_memsize,
    308 	.sdma_doorbell_range = nbio_v7_0_sdma_doorbell_range,
    309 	.vcn_doorbell_range = nbio_v7_0_vcn_doorbell_range,
    310 	.enable_doorbell_aperture = nbio_v7_0_enable_doorbell_aperture,
    311 	.enable_doorbell_selfring_aperture = nbio_v7_0_enable_doorbell_selfring_aperture,
    312 	.ih_doorbell_range = nbio_v7_0_ih_doorbell_range,
    313 	.update_medium_grain_clock_gating = nbio_v7_0_update_medium_grain_clock_gating,
    314 	.update_medium_grain_light_sleep = nbio_v7_0_update_medium_grain_light_sleep,
    315 	.get_clockgating_state = nbio_v7_0_get_clockgating_state,
    316 	.ih_control = nbio_v7_0_ih_control,
    317 	.init_registers = nbio_v7_0_init_registers,
    318 	.detect_hw_virt = nbio_v7_0_detect_hw_virt,
    319 	.remap_hdp_registers = nbio_v7_0_remap_hdp_registers,
    320 };
    321