1*591689ccSHawking Zhang /* 2*591689ccSHawking Zhang * Copyright 2025 Advanced Micro Devices, Inc. 3*591689ccSHawking Zhang * 4*591689ccSHawking Zhang * Permission is hereby granted, free of charge, to any person obtaining a 5*591689ccSHawking Zhang * copy of this software and associated documentation files (the "Software"), 6*591689ccSHawking Zhang * to deal in the Software without restriction, including without limitation 7*591689ccSHawking Zhang * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*591689ccSHawking Zhang * and/or sell copies of the Software, and to permit persons to whom the 9*591689ccSHawking Zhang * Software is furnished to do so, subject to the following conditions: 10*591689ccSHawking Zhang * 11*591689ccSHawking Zhang * The above copyright notice and this permission notice shall be included in 12*591689ccSHawking Zhang * all copies or substantial portions of the Software. 13*591689ccSHawking Zhang * 14*591689ccSHawking Zhang * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15*591689ccSHawking Zhang * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16*591689ccSHawking Zhang * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17*591689ccSHawking Zhang * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18*591689ccSHawking Zhang * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19*591689ccSHawking Zhang * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20*591689ccSHawking Zhang * OTHER DEALINGS IN THE SOFTWARE. 21*591689ccSHawking Zhang * 22*591689ccSHawking Zhang */ 23*591689ccSHawking Zhang #include "amdgpu.h" 24*591689ccSHawking Zhang #include "smuio_v15_0_8.h" 25*591689ccSHawking Zhang #include "smuio/smuio_15_0_8_offset.h" 26*591689ccSHawking Zhang #include "smuio/smuio_15_0_8_sh_mask.h" 27*591689ccSHawking Zhang 28*591689ccSHawking Zhang #define SMUIO_MCM_CONFIG__HOST_GPU_XGMI_MASK 0x00000001L 29*591689ccSHawking Zhang #define SMUIO_MCM_CONFIG__ETHERNET_SWITCH_MASK 0x00000008L 30*591689ccSHawking Zhang #define SMUIO_MCM_CONFIG__CUSTOM_HBM_MASK 0x00000001L 31*591689ccSHawking Zhang 32*591689ccSHawking Zhang static u32 smuio_v15_0_8_get_rom_index_offset(struct amdgpu_device *adev) 33*591689ccSHawking Zhang { 34*591689ccSHawking Zhang return SOC15_REG_OFFSET(SMUIO, 0, regROM_INDEX); 35*591689ccSHawking Zhang } 36*591689ccSHawking Zhang 37*591689ccSHawking Zhang static u32 smuio_v15_0_8_get_rom_data_offset(struct amdgpu_device *adev) 38*591689ccSHawking Zhang { 39*591689ccSHawking Zhang return SOC15_REG_OFFSET(SMUIO, 0, regROM_DATA); 40*591689ccSHawking Zhang } 41*591689ccSHawking Zhang 42*591689ccSHawking Zhang static void smuio_v15_0_8_update_rom_clock_gating(struct amdgpu_device *adev, bool enable) 43*591689ccSHawking Zhang { 44*591689ccSHawking Zhang return; 45*591689ccSHawking Zhang } 46*591689ccSHawking Zhang 47*591689ccSHawking Zhang static u64 smuio_v15_0_8_get_gpu_clock_counter(struct amdgpu_device *adev) 48*591689ccSHawking Zhang { 49*591689ccSHawking Zhang u64 clock; 50*591689ccSHawking Zhang u64 clock_counter_lo, clock_counter_hi_pre, clock_counter_hi_after; 51*591689ccSHawking Zhang 52*591689ccSHawking Zhang preempt_disable(); 53*591689ccSHawking Zhang clock_counter_hi_pre = (u64)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER); 54*591689ccSHawking Zhang clock_counter_lo = (u64)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER); 55*591689ccSHawking Zhang /* the clock counter may be udpated during polling the counters */ 56*591689ccSHawking Zhang clock_counter_hi_after = (u64)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER); 57*591689ccSHawking Zhang if (clock_counter_hi_pre != clock_counter_hi_after) 58*591689ccSHawking Zhang clock_counter_lo = (u64)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER); 59*591689ccSHawking Zhang preempt_enable(); 60*591689ccSHawking Zhang 61*591689ccSHawking Zhang clock = clock_counter_lo | (clock_counter_hi_after << 32ULL); 62*591689ccSHawking Zhang 63*591689ccSHawking Zhang return clock; 64*591689ccSHawking Zhang } 65*591689ccSHawking Zhang 66*591689ccSHawking Zhang static void smuio_v15_0_8_get_clock_gating_state(struct amdgpu_device *adev, u64 *flags) 67*591689ccSHawking Zhang { 68*591689ccSHawking Zhang u32 data; 69*591689ccSHawking Zhang 70*591689ccSHawking Zhang /* CGTT_ROM_CLK_CTRL0 is not available for APU */ 71*591689ccSHawking Zhang if (adev->flags & AMD_IS_APU) 72*591689ccSHawking Zhang return; 73*591689ccSHawking Zhang 74*591689ccSHawking Zhang data = RREG32_SOC15(SMUIO, 0, regCGTT_ROM_CLK_CTRL0); 75*591689ccSHawking Zhang if (!(data & CGTT_ROM_CLK_CTRL0__SOFT_OVERRIDE0_MASK)) 76*591689ccSHawking Zhang *flags |= AMD_CG_SUPPORT_ROM_MGCG; 77*591689ccSHawking Zhang } 78*591689ccSHawking Zhang 79*591689ccSHawking Zhang /** 80*591689ccSHawking Zhang * smuio_v15_0_8_get_die_id - query die id from FCH. 81*591689ccSHawking Zhang * 82*591689ccSHawking Zhang * @adev: amdgpu device pointer 83*591689ccSHawking Zhang * 84*591689ccSHawking Zhang * Returns die id 85*591689ccSHawking Zhang */ 86*591689ccSHawking Zhang static u32 smuio_v15_0_8_get_die_id(struct amdgpu_device *adev) 87*591689ccSHawking Zhang { 88*591689ccSHawking Zhang u32 data, die_id; 89*591689ccSHawking Zhang 90*591689ccSHawking Zhang data = RREG32_SOC15(SMUIO, 0, regSMUIO_MCM_CONFIG); 91*591689ccSHawking Zhang die_id = REG_GET_FIELD(data, SMUIO_MCM_CONFIG, DIE_ID); 92*591689ccSHawking Zhang 93*591689ccSHawking Zhang return die_id; 94*591689ccSHawking Zhang } 95*591689ccSHawking Zhang 96*591689ccSHawking Zhang /** 97*591689ccSHawking Zhang * smuio_v15_0_8_get_socket_id - query socket id from FCH 98*591689ccSHawking Zhang * 99*591689ccSHawking Zhang * @adev: amdgpu device pointer 100*591689ccSHawking Zhang * 101*591689ccSHawking Zhang * Returns socket id 102*591689ccSHawking Zhang */ 103*591689ccSHawking Zhang static u32 smuio_v15_0_8_get_socket_id(struct amdgpu_device *adev) 104*591689ccSHawking Zhang { 105*591689ccSHawking Zhang u32 data, socket_id; 106*591689ccSHawking Zhang 107*591689ccSHawking Zhang data = RREG32_SOC15(SMUIO, 0, regSMUIO_MCM_CONFIG); 108*591689ccSHawking Zhang socket_id = REG_GET_FIELD(data, SMUIO_MCM_CONFIG, SOCKET_ID); 109*591689ccSHawking Zhang 110*591689ccSHawking Zhang return socket_id; 111*591689ccSHawking Zhang } 112*591689ccSHawking Zhang 113*591689ccSHawking Zhang /** 114*591689ccSHawking Zhang * smuio_v15_0_8_is_host_gpu_xgmi_supported - detect xgmi interface between cpu and gpu/s. 115*591689ccSHawking Zhang * 116*591689ccSHawking Zhang * @adev: amdgpu device pointer 117*591689ccSHawking Zhang * 118*591689ccSHawking Zhang * Returns true on success or false otherwise. 119*591689ccSHawking Zhang */ 120*591689ccSHawking Zhang static bool smuio_v15_0_8_is_host_gpu_xgmi_supported(struct amdgpu_device *adev) 121*591689ccSHawking Zhang { 122*591689ccSHawking Zhang u32 data; 123*591689ccSHawking Zhang 124*591689ccSHawking Zhang data = RREG32_SOC15(SMUIO, 0, regSMUIO_MCM_CONFIG); 125*591689ccSHawking Zhang data = REG_GET_FIELD(data, SMUIO_MCM_CONFIG, TOPOLOGY_ID); 126*591689ccSHawking Zhang /* data[4:0] 127*591689ccSHawking Zhang * bit 0 == 0 host-gpu interface is PCIE 128*591689ccSHawking Zhang * bit 0 == 1 host-gpu interface is Alternate Protocal 129*591689ccSHawking Zhang * for AMD, this is XGMI 130*591689ccSHawking Zhang */ 131*591689ccSHawking Zhang data &= SMUIO_MCM_CONFIG__HOST_GPU_XGMI_MASK; 132*591689ccSHawking Zhang 133*591689ccSHawking Zhang return data ? true : false; 134*591689ccSHawking Zhang } 135*591689ccSHawking Zhang 136*591689ccSHawking Zhang #if 0 137*591689ccSHawking Zhang /* 138*591689ccSHawking Zhang * smuio_v15_0_8_is_connected_with_ethernet_switch - detect systems connected with ethernet switch 139*591689ccSHawking Zhang * 140*591689ccSHawking Zhang * @adev: amdgpu device pointer 141*591689ccSHawking Zhang * 142*591689ccSHawking Zhang * Returns true on success or false otherwise. 143*591689ccSHawking Zhang */ 144*591689ccSHawking Zhang static bool smuio_v15_0_8_is_connected_with_ethernet_switch(struct amdgpu_device *adev) 145*591689ccSHawking Zhang { 146*591689ccSHawking Zhang u32 data; 147*591689ccSHawking Zhang 148*591689ccSHawking Zhang if (!(adev->flags & AMD_IS_APU)) 149*591689ccSHawking Zhang return false; 150*591689ccSHawking Zhang 151*591689ccSHawking Zhang data = RREG32_SOC15(SMUIO, 0, regSMUIO_MCM_CONFIG); 152*591689ccSHawking Zhang data = REG_GET_FIELD(data, SMUIO_MCM_CONFIG, TOPOLOGY_ID); 153*591689ccSHawking Zhang /* data[4:0] 154*591689ccSHawking Zhang * bit 3 == 0 systems connected with ethernet switch 155*591689ccSHawking Zhang */ 156*591689ccSHawking Zhang data &= SMUIO_MCM_CONFIG__ETHERNET_SWITCH_MASK; 157*591689ccSHawking Zhang 158*591689ccSHawking Zhang return data ? false : true; 159*591689ccSHawking Zhang } 160*591689ccSHawking Zhang #endif 161*591689ccSHawking Zhang 162*591689ccSHawking Zhang static enum amdgpu_pkg_type smuio_v15_0_8_get_pkg_type(struct amdgpu_device *adev) 163*591689ccSHawking Zhang { 164*591689ccSHawking Zhang enum amdgpu_pkg_type pkg_type; 165*591689ccSHawking Zhang u32 data; 166*591689ccSHawking Zhang 167*591689ccSHawking Zhang data = RREG32_SOC15(SMUIO, 0, regSMUIO_MCM_CONFIG); 168*591689ccSHawking Zhang data = REG_GET_FIELD(data, SMUIO_MCM_CONFIG, PKG_TYPE); 169*591689ccSHawking Zhang 170*591689ccSHawking Zhang /* data [3:0] 171*591689ccSHawking Zhang bit 2 and bit 3 identifies the pkg type */ 172*591689ccSHawking Zhang switch (data & 0xC) { 173*591689ccSHawking Zhang case 0x0: 174*591689ccSHawking Zhang pkg_type = AMDGPU_PKG_TYPE_BB; 175*591689ccSHawking Zhang break; 176*591689ccSHawking Zhang case 0x8: 177*591689ccSHawking Zhang pkg_type = AMDGPU_PKG_TYPE_CEM; 178*591689ccSHawking Zhang break; 179*591689ccSHawking Zhang default: 180*591689ccSHawking Zhang pkg_type = AMDGPU_PKG_TYPE_UNKNOWN; 181*591689ccSHawking Zhang break; 182*591689ccSHawking Zhang } 183*591689ccSHawking Zhang 184*591689ccSHawking Zhang return pkg_type; 185*591689ccSHawking Zhang } 186*591689ccSHawking Zhang 187*591689ccSHawking Zhang #if 0 188*591689ccSHawking Zhang static bool smuio_v15_0_8_is_custom_hbm_supported(struct amdgpu_device *adev) 189*591689ccSHawking Zhang { 190*591689ccSHawking Zhang u32 data; 191*591689ccSHawking Zhang 192*591689ccSHawking Zhang data = RREG32_SOC15(SMUIO, 0, regSMUIO_MCM_CONFIG); 193*591689ccSHawking Zhang data = REG_GET_FIELD(data, SMUIO_MCM_CONFIG, PKG_TYPE); 194*591689ccSHawking Zhang 195*591689ccSHawking Zhang /* data [3:0] 196*591689ccSHawking Zhang * bit 0 identifies custom HBM module */ 197*591689ccSHawking Zhang data &= SMUIO_MCM_CONFIG__CUSTOM_HBM_MASK; 198*591689ccSHawking Zhang 199*591689ccSHawking Zhang return data ? true : false; 200*591689ccSHawking Zhang } 201*591689ccSHawking Zhang #endif 202*591689ccSHawking Zhang 203*591689ccSHawking Zhang const struct amdgpu_smuio_funcs smuio_v15_0_8_funcs = { 204*591689ccSHawking Zhang .get_rom_index_offset = smuio_v15_0_8_get_rom_index_offset, 205*591689ccSHawking Zhang .get_rom_data_offset = smuio_v15_0_8_get_rom_data_offset, 206*591689ccSHawking Zhang .get_gpu_clock_counter = smuio_v15_0_8_get_gpu_clock_counter, 207*591689ccSHawking Zhang .get_die_id = smuio_v15_0_8_get_die_id, 208*591689ccSHawking Zhang .get_socket_id = smuio_v15_0_8_get_socket_id, 209*591689ccSHawking Zhang .is_host_gpu_xgmi_supported = smuio_v15_0_8_is_host_gpu_xgmi_supported, 210*591689ccSHawking Zhang .update_rom_clock_gating = smuio_v15_0_8_update_rom_clock_gating, 211*591689ccSHawking Zhang .get_clock_gating_state = smuio_v15_0_8_get_clock_gating_state, 212*591689ccSHawking Zhang .get_pkg_type = smuio_v15_0_8_get_pkg_type, 213*591689ccSHawking Zhang }; 214