openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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