pvtmon.c (9148B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: pvtmon.c 8 * Purpose: 9 * Requires: 10 */ 11 12 #include <shared/bsl.h> 13 #include <soc/katana2.h> 14 #include <soc/saber2.h> 15 #include <soc/drv.h> 16 #include <soc/error.h> 17 #include <soc/debug.h> 18 #ifdef INCLUDE_AVS 19 #include <soc/avs.h> 20 #endif 21 22 #ifdef BCM_SABER2_SUPPORT 23 static int sb2_temperature_init[SOC_MAX_NUM_DEVICES] = {0}; 24 25 static const soc_reg_t sb2_pvtmon_result_reg[] = { 26 TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r 27 }; 28 29 int 30 _soc_saber2_temperature_monitor_init(int unit) { 31 uint32 rval; 32 33 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval)); 34 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RSTBf, 1); 35 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 36 37 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_0r(unit, &rval)); 38 soc_reg_field_set(unit, TOP_PVTMON_CTRL_0r, &rval, BG_ADJf, 3); 39 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_0r(unit, rval)); 40 41 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval)); 42 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RSTBf, 0); 43 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 44 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_SELECTf, 0); 45 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 46 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_RSTBf, 1); 47 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 48 49 sal_usleep(1000); 50 51 /* Bring PVTMON max and min data out of reset */ 52 SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_0r(unit, &rval)); 53 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 54 THERMAL_PVTMON1_MAX_DATA_RST_Lf, 1); 55 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 56 THERMAL_PVTMON1_MIN_DATA_RST_Lf, 1); 57 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 58 THERMAL_PVTMON0_MAX_DATA_RST_Lf, 1); 59 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 60 THERMAL_PVTMON0_MIN_DATA_RST_Lf, 1); 61 SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval)); 62 63 64 sb2_temperature_init[unit] = 1; 65 return SOC_E_NONE; 66 } 67 68 int 69 soc_sb2_temperature_monitor_get(int unit, 70 int temperature_max, 71 soc_switch_temperature_monitor_t *temperature_array, 72 int *temperature_count) 73 { 74 uint32 rval; 75 soc_reg_t reg; 76 int index; 77 int fval, cur, peak; 78 int num_entries_out; 79 80 *temperature_count = 0; 81 if (COUNTOF(sb2_pvtmon_result_reg) > temperature_max) { 82 num_entries_out = temperature_max; 83 } else { 84 num_entries_out = COUNTOF(sb2_pvtmon_result_reg); 85 } 86 87 /* Check to see if the thermal monitor is initialized */ 88 if(sb2_temperature_init[unit] == 0) { 89 SOC_IF_ERROR_RETURN(_soc_saber2_temperature_monitor_init(unit)); 90 } 91 92 for (index = 0; index < num_entries_out; index++) { 93 reg = sb2_pvtmon_result_reg[index]; 94 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 95 fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf); 96 cur = (41004000 - (48505 * fval)) / 10000; 97 fval = soc_reg_field_get(unit, reg, rval, PEAK_TEMP_DATAf); 98 peak = (41004000 - (48505 * fval)) / 10000; 99 (temperature_array + index)->curr = cur; 100 (temperature_array + index)->peak = peak; 101 } 102 103 SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_0r(unit, &rval)); 104 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 105 THERMAL_PVTMON1_MAX_DATA_RST_Lf, 0); 106 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 107 THERMAL_PVTMON1_MIN_DATA_RST_Lf, 0); 108 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 109 THERMAL_PVTMON0_MAX_DATA_RST_Lf, 0); 110 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 111 THERMAL_PVTMON0_MIN_DATA_RST_Lf, 0); 112 SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval)); 113 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 114 THERMAL_PVTMON1_MAX_DATA_RST_Lf, 1); 115 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 116 THERMAL_PVTMON1_MIN_DATA_RST_Lf, 1); 117 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 118 THERMAL_PVTMON0_MAX_DATA_RST_Lf, 1); 119 soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, 120 THERMAL_PVTMON0_MIN_DATA_RST_Lf, 1); 121 SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval)); 122 *temperature_count=num_entries_out; 123 124 return SOC_E_NONE; 125 } 126 127 #ifdef INCLUDE_AVS 128 int soc_sb2_volt_reading_reset(int unit) 129 { 130 uint32 rval, rval1; 131 uint32 m_init_pvt_mntr, m_init_pvt_mntr_orig; 132 133 SOC_IF_ERROR_RETURN(READ_AVS_REG_HW_MNTR_SEQUENCER_INITr(unit, &rval1)); 134 soc_reg_field_set(unit, AVS_REG_HW_MNTR_SEQUENCER_INITr, &rval1, 135 SEQUENCER_INITf, 1); 136 SOC_IF_ERROR_RETURN(WRITE_AVS_REG_HW_MNTR_SEQUENCER_INITr(unit, rval1)); 137 138 SOC_IF_ERROR_RETURN( 139 READ_AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr(unit, &rval)); 140 m_init_pvt_mntr = (soc_reg_field_get(unit, 141 AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr, 142 rval, M_INIT_PVT_MNTRf)); 143 m_init_pvt_mntr_orig = m_init_pvt_mntr; 144 145 /* Set bits corresponding to required voltage */ 146 m_init_pvt_mntr |= 0x78; /* 1V(0), 1V(1), 1.8V, 3.3V*/ 147 soc_reg_field_set(unit, AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr, 148 &rval, M_INIT_PVT_MNTRf, m_init_pvt_mntr); 149 SOC_IF_ERROR_RETURN( 150 WRITE_AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr(unit, rval)); 151 152 /* Clear the fields */ 153 soc_reg_field_set(unit, AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr, 154 &rval, M_INIT_PVT_MNTRf, m_init_pvt_mntr_orig); 155 SOC_IF_ERROR_RETURN( 156 WRITE_AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr(unit, rval)); 157 158 soc_reg_field_set(unit, AVS_REG_HW_MNTR_SEQUENCER_INITr, &rval1, 159 SEQUENCER_INITf, 0); 160 SOC_IF_ERROR_RETURN(WRITE_AVS_REG_HW_MNTR_SEQUENCER_INITr(unit, rval1)); 161 162 return SOC_E_NONE; 163 } 164 165 int soc_sb2_volt_get(int unit, int pvtmon, int *volt_reading) 166 { 167 uint32 rval; 168 int valid = 0, done = 0, volt_data, volt_data_sum; 169 int i, num_readings = 10; 170 soc_reg_t reg; 171 soc_timeout_t to; 172 int timeout_val = 10000; /* in usecs */ 173 int div; 174 soc_timeout_init(&to, timeout_val, 0); 175 176 switch(pvtmon) { 177 case SOC_AVS_PVT_1V_0: 178 reg = AVS_REG_RO_REGISTERS_0_PVT_1V_0_MNTR_STATUSr; 179 div = 7; 180 break; 181 case SOC_AVS_PVT_1V_1: 182 reg = AVS_REG_RO_REGISTERS_0_PVT_1V_1_MNTR_STATUSr; 183 div = 7; 184 break; 185 case SOC_AVS_PVT_1P8V: 186 reg = AVS_REG_RO_REGISTERS_0_PVT_1P8V_MNTR_STATUSr; 187 div = 4; 188 break; 189 case SOC_AVS_PVT_3P3V: 190 reg = AVS_REG_RO_REGISTERS_0_PVT_3P3V_MNTR_STATUSr; 191 div = 2; 192 break; 193 default: 194 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit,"Invalid PVTMON\n"))); 195 return SOC_E_FAIL; 196 } 197 do { 198 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 199 valid = soc_reg_field_get(unit, reg, rval, VALID_DATAf); 200 done = soc_reg_field_get(unit, reg, rval, DONEf); 201 if((valid == 1) && (done == 1)) { 202 break; 203 } 204 205 if (soc_timeout_check(&to)) { 206 LOG_WARN(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 207 "PVTMON %d monitor timeout\n"), pvtmon)); 208 break; 209 } 210 } while(TRUE); 211 212 if((valid == 1) && (done == 1)) { 213 volt_data_sum = 0; 214 for(i = 0; i < num_readings; i++) { 215 volt_data = soc_reg_field_get(unit, reg, rval, DATAf); 216 volt_data_sum += volt_data; 217 sal_udelay(10); 218 } 219 volt_data = volt_data_sum / num_readings; 220 *volt_reading = ((volt_data * 880 * 10) / (1024 * div)); 221 } 222 return SOC_E_NONE; 223 } 224 225 226 int 227 soc_sb2_show_voltage(int unit) 228 { 229 int pvtmon; 230 int avg; 231 int pvtmon_list[] = {SOC_AVS_PVT_1V_0, SOC_AVS_PVT_1V_1, 232 SOC_AVS_PVT_1P8V, SOC_AVS_PVT_3P3V}; 233 char *pvtmon_str[] = {"ROV_PVTMON_CORE_1P0 1 - 1.0V(0)", 234 "ROV_PVTMON_1P0 1 - 1.0V(1)", 235 "ROV_PVTMON_1P8 1 - 1.8V ", 236 "ROV_PVTMON_3P3 1 - 3.3V "}; 237 238 SOC_IF_ERROR_RETURN(soc_sb2_volt_reading_reset(unit)); 239 /* Read Voltages */ 240 for (pvtmon = 0; pvtmon < COUNTOF(pvtmon_list); pvtmon++) { 241 SOC_IF_ERROR_RETURN(soc_sb2_volt_get(unit, pvtmon_list[pvtmon], &avg)); 242 LOG_CLI((BSL_META_U(unit, 243 "%s : Average = %d.%03dV\n"), pvtmon_str[pvtmon], 244 (avg/1000), (avg %1000))); 245 } 246 247 return SOC_E_NONE; 248 } 249 #else 250 int 251 soc_sb2_show_voltage(int unit) 252 { 253 LOG_WARN(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 254 "AVS needs to be included to display voltage\n"))); 255 return SOC_E_UNAVAIL; 256 } 257 #endif 258 259 #endif