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

avs.c (11869B)


      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:        avs.c
      8  * Purpose:
      9  * Requires:
     10  */
     11  
     12 #include <shared/bsl.h>
     13 
     14 #ifdef INCLUDE_AVS
     15 #include <soc/avs.h>
     16 #include <soc/i2c.h>
     17 #include <soc/saber2.h>
     18 #include <soc/drv.h>
     19 #include <soc/error.h>
     20 
     21 #include <bcm/error.h>
     22 
     23 #define SOC_AVS_SABER2_NUMBER_OF_CENTRALS 36
     24 #define SOC_AVS_SABER2_CENTRAL_XBMP0 0x0
     25 #define SOC_AVS_SABER2_CENTRAL_XBMP1 0xFFFFFFF0
     26 #define SOC_AVS_SABER2_FIRST_CENTRAL 0
     27 
     28 #define SOC_AVS_SABER2_NUMBER_OF_REMOTES 20
     29 #define SOC_AVS_SABER2_REMOTE_XBMP0 0x0
     30 #define SOC_AVS_SABER2_FIRST_REMOTE 0
     31 
     32 #define SOC_AVS_SABER2_VMIN_AVS SOC_AVS_DEFAULT_VMIN_AVS
     33 #define SOC_AVS_SABER2_VMAX_AVS SOC_AVS_DEFAULT_VMAX_AVS
     34 #define SOC_AVS_SABER2_VMARGIN_HIGH SOC_AVS_DEFAULT_VMARGIN_HIGH
     35 #define SOC_AVS_SABER2_VMARGIN_LOW SOC_AVS_DEFAULT_VMARGIN_LOW
     36 
     37 static soc_avs_reg_info_t _sb2_osc_cen_init_list[]={
     38 /* AVS_REG_HW_MNTR_ENABLE_DEFAULT_CEN_ROSC_0r */
     39 {AVS_REG_HW_MNTR_ENABLE_DEFAULT_CEN_ROSC_0r,CEN_ROSC_ENABLE_DEFAULTf},
     40 {AVS_REG_HW_MNTR_ENABLE_DEFAULT_CEN_ROSC_1r,CEN_ROSC_ENABLE_DEFAULTf},
     41 {-1,-1},
     42 };
     43 
     44 static soc_avs_reg_info_t _sb2_osc_cen_thr_en_list[]={
     45 {AVS_REG_ROSC_THRESHOLD_1_CEN_ROSC_THRESHOLD1_EN_0r,IRQ_ENf},
     46 {AVS_REG_ROSC_THRESHOLD_1_CEN_ROSC_THRESHOLD1_EN_1r,IRQ_ENf},
     47 {AVS_REG_ROSC_THRESHOLD_2_CEN_ROSC_THRESHOLD2_EN_0r,IRQ_ENf},
     48 {AVS_REG_ROSC_THRESHOLD_2_CEN_ROSC_THRESHOLD2_EN_1r,IRQ_ENf},
     49 {-1,-1},
     50 };
     51 
     52 /* reset osc measurement */
     53 static soc_avs_reg_info_t _sb2_osc_seq_reset_list[]={
     54 {AVS_REG_HW_MNTR_MEASUREMENTS_INIT_CEN_ROSC_0r,M_INIT_CEN_ROSCf},
     55 {AVS_REG_HW_MNTR_MEASUREMENTS_INIT_CEN_ROSC_1r,M_INIT_CEN_ROSCf},
     56 {AVS_REG_HW_MNTR_MEASUREMENTS_INIT_RMT_ROSC_0r,M_INIT_RMT_ROSCf},
     57 {AVS_REG_HW_MNTR_MEASUREMENTS_INIT_RMT_ROSC_1r,M_INIT_RMT_ROSCf},
     58 {-1,-1}
     59 };
     60 
     61 #ifndef SB2_AVS_I2C 
     62 int
     63 _soc_saber2_init_pvt(int unit) {
     64     uint32 rval;
     65 
     66     SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval));
     67     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_SELECTf, 3);
     68     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval));
     69 
     70     SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_0r(unit, &rval));
     71     soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, THERMAL_PVTMON0_MAX_DATA_RST_Lf, 0);
     72     SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval));
     73     
     74     soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, THERMAL_PVTMON0_MIN_DATA_RST_Lf, 0);
     75     SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval));
     76     
     77     soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, THERMAL_PVTMON0_MAX_DATA_RST_Lf, 1);
     78     SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval));
     79     
     80     soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, THERMAL_PVTMON0_MIN_DATA_RST_Lf, 1);
     81     SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval));
     82     
     83     soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, THERMAL_PVTMON1_MAX_DATA_RST_Lf, 0);
     84     SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval));
     85 
     86     soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, THERMAL_PVTMON1_MIN_DATA_RST_Lf, 0);
     87     SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval));
     88 
     89     soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, THERMAL_PVTMON1_MAX_DATA_RST_Lf, 1);
     90     SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval));
     91 
     92     soc_reg_field_set(unit, TOP_MISC_CONTROL_0r, &rval, THERMAL_PVTMON1_MIN_DATA_RST_Lf, 1);
     93     SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_0r(unit, rval));
     94 
     95     return SOC_E_NONE;
     96 }
     97 #endif
     98 
     99 #ifdef SB2_AVS_I2C
    100 static int dac[SOC_MAX_NUM_DEVICES], adc[SOC_MAX_NUM_DEVICES];
    101 
    102 static dac_calibrate_t dac_params[] = {
    103     {0, "Core", -1, 1, 0, 0,
    104     LTC3880_0_6V_MIN_DACVAL,
    105     LTC3880_0_6V_MAX_DACVAL,
    106     LTC3880_0_6V_MID_DACVAL,1},
    107 };
    108 
    109 
    110 STATIC int
    111 _soc_saber2_avs_i2c_voltage_set(int unit, uint32 val)
    112 {
    113     int rv = SOC_E_NONE;
    114 #ifdef COMPILER_HAS_DOUBLE
    115     double sb2_i2c_index = 6; /* Saber2 index in i2c device drivers */
    116     double volts = (double)val;
    117     volts = volts/10000;
    118 #else
    119     int volts = val * 100; /* 0.1mv to uV */
    120     int sb2_i2c_index = 6; /* Saber2 index in i2c device drivers */
    121 #endif
    122 
    123     /* Calulating voltage based on feedback ratio. */
    124     /* For 1V output, feedback voltage is 0.549 volts */
    125     volts = volts * 549 / 1000;
    126 
    127     if ((rv = soc_i2c_device(unit, dac[unit])->driver->ioctl(unit, dac[unit],
    128                 I2C_LTC_IOC_SET_CONFIG, &sb2_i2c_index, 0) < 0)){
    129         LOG_ERROR(BSL_LS_SOC_AVS,
    130                 (BSL_META_U(unit,
    131                             "Failed to set configure max and min\n")));
    132     }
    133 
    134     if ((rv = soc_i2c_device(unit, dac[unit])->driver->ioctl(unit, dac[unit],
    135                 I2C_DAC_IOC_SET_CALTAB, (void*)dac_params, 1) < 0)){
    136         LOG_ERROR(BSL_LS_SOC_AVS,
    137                 (BSL_META_U(unit,
    138                             "Failed to set DAC calibration\n")));
    139     }
    140 
    141     if ((rv = soc_i2c_device(unit, dac[unit])->driver->ioctl(unit, dac[unit],
    142                 I2C_LTC_IOC_SET_VOUT, &volts, 0)) < 0) {
    143         LOG_ERROR(BSL_LS_SOC_AVS,
    144                 (BSL_META_U(unit,
    145                             "Failed to set Voltage %f\n"), volts));
    146     }
    147 
    148     return rv;
    149 }
    150 
    151 STATIC int
    152 _soc_saber2_avs_i2c_voltage_get(int unit, uint32 *val)
    153 {
    154     int rv = SOC_E_NONE;
    155     
    156 #ifdef COMPILER_HAS_DOUBLE
    157     double volts =  0;
    158 #else
    159     int volts = 0;
    160 #endif
    161 
    162     if ((rv = soc_i2c_device(unit, dac[unit])->driver->ioctl(unit, adc[unit],
    163                 I2C_LTC_IOC_READ_VOUT, &volts, 0)) < 0) {
    164         LOG_ERROR(BSL_LS_SOC_AVS,
    165                 (BSL_META_U(unit,
    166                             "Failed to get Voltage\n")));
    167     }
    168     
    169     /* Calulating voltage based on feedback ratio. */
    170     /* For 1V output, feedback voltage is 0.549 volts */
    171     volts = volts * 1000 / 549;
    172 
    173 #ifdef COMPILER_HAS_DOUBLE
    174     *val = (float)volts * 10000;
    175 #else
    176     *val = adc_data.val;
    177 #endif
    178 
    179     return rv;
    180 }
    181 
    182 
    183 STATIC int sb2_dac_devs_init (int unit, char *dev_name)
    184 {
    185     int rv = 0;
    186     int flags = 0;
    187     uint8 data;
    188     int mux;
    189 
    190     if ( (mux = soc_i2c_devopen(unit, dev_name, flags, 0)) < 0) {
    191         cli_out("Could not open %s for mux selection:%s\n",
    192                 dev_name?dev_name:"MUX_DEV", bcm_errmsg(mux));
    193         return SOC_E_FAIL;
    194     }
    195 
    196     data = 1 << 7;
    197     if( (rv = soc_i2c_device(unit, mux)->driver->
    198                 write(unit, mux, 0,
    199                             &data, 1)) < 0) {
    200         cli_out("Error: write of mux device byte failed:%s\n",
    201                 bcm_errmsg(rv));
    202         return SOC_E_FAIL;
    203     }
    204 
    205     /* get dac diver's device id */
    206     if ((dac[unit] = soc_i2c_devopen(unit, I2C_LTC3880_41,
    207                             flags, 0)) < 0) {
    208         cli_out("Could not open %s:%s\n",
    209                 I2C_LTC3880_41, bcm_errmsg(dac[unit]));
    210         return SOC_E_FAIL;
    211     }
    212     soc_i2c_device(unit, dac[unit])->driver->load(unit,dac[unit],NULL,0);
    213 
    214     if ((adc[unit] = soc_i2c_devopen(unit, I2C_LTC3880_41,
    215                             flags, 0)) < 0) {
    216         cli_out("Could not open %s:%s\n",
    217                 I2C_LTC3880_41, bcm_errmsg(dac[unit]));
    218        return BCM_E_FAIL;
    219     }
    220     soc_i2c_device(unit, dac[unit])->driver->load(unit,adc[unit],NULL,0);
    221 
    222     return SOC_E_NONE;
    223 }
    224 #endif
    225 
    226 int
    227 _soc_saber2_avs_voltage_get(int unit, uint32 *val)
    228 {
    229 #ifdef SB2_AVS_I2C
    230     return _soc_saber2_avs_i2c_voltage_get(unit, val);
    231 #else
    232     return soc_avs_pvtmon_voltage_get(unit, val);
    233 #endif
    234 }
    235     
    236 int
    237 _soc_saber2_avs_voltage_set(int unit, uint32 val)
    238 {
    239 #ifdef SB2_AVS_I2C
    240     return _soc_saber2_avs_i2c_voltage_set(unit, val);
    241 #else
    242     return soc_avs_pvtmon_voltage_set(unit, val);
    243 #endif
    244 }
    245     
    246 int
    247 _soc_saber2_avs_info_ioctl(int unit, soc_avs_ioctl_t opcode, void* data, int len)
    248 {
    249     int rv = SOC_E_NONE;
    250 
    251 #ifndef SB2_AVS_I2C
    252     uint32 value;
    253     float v_dac;
    254     float v_bg[8] = {1.205, 1.200, 1.195, 1.191, 1.211, 1.215, 1.220, 1.226};
    255     uint32  bg_val, rval;
    256     float dac_val_temp, set_volt;
    257 
    258     switch (opcode) {
    259     case SOC_AVS_CTRL_PVTMON_VOLTAGE_GET:
    260         /* Should be called after soc_avs_pvtmon_voltage_get()
    261          * to make device/board specific adjustments.
    262          */
    263         value = *(uint32 *)data;
    264         *(uint32 *)data = (value * 880 * 1000) / (1024 * 70);
    265         break;
    266     
    267     case SOC_AVS_CTRL_PVTMON_TEMP_GET:
    268         value = *(uint32 *)data;
    269         *(int32 *)data = (41004000 - (48505 * value)) / 10000;
    270         break;
    271     
    272     case SOC_AVS_CTRL_QUERY_TRACK_STEP_SIZE:
    273         /* 5 mV */
    274         *(uint32 *)data = 50;
    275         break;
    276     
    277     case SOC_AVS_CTRL_PVTMON_VOLTAGE_SET:
    278         /* Should be called before soc_avs_pvtmon_voltage_set()
    279          * to calculate the dac value before updating pvtmon.
    280          */
    281         value = *(uint32 *)data;
    282         set_volt = (float)value / 10000;
    283         v_dac = (2 * (1 - set_volt)) +  0.549;
    284 
    285         /* Calculating Vbgu from OTP bits */
    286         SOC_IF_ERROR_RETURN(READ_TOP_SWITCH_FEATURE_ENABLE_7r(unit, &rval));
    287         bg_val = soc_reg_field_get(unit, TOP_SWITCH_FEATURE_ENABLE_7r, rval, BOND_PVTMON_BGf);
    288         
    289         /* Calulating DAC value based on V_dac */
    290         dac_val_temp = (4.188 * (285 - v_dac / v_bg[bg_val] * 241 ));
    291         *(uint32 *)data = (uint32)dac_val_temp;
    292         break;
    293     
    294     default:
    295         rv = SOC_E_UNAVAIL;
    296         break;
    297     }
    298 #endif
    299     
    300     return rv;
    301 }
    302 
    303 int
    304 _soc_saber2_avs_info_init(int unit, soc_avs_info_t *avs_info)
    305 {    
    306 #ifdef SB2_AVS_I2C
    307     if (sb2_dac_devs_init(unit, I2C_MUX_3) < 0) {
    308         LOG_ERROR(BSL_LS_APPL_I2C,
    309                 (BSL_META("ERROR: dac_devs_init fail\n")));
    310         return SOC_E_FAIL;
    311     }
    312 
    313 #else
    314     SOC_IF_ERROR_RETURN(_soc_saber2_init_pvt(unit));
    315 #endif
    316 
    317     if (avs_info == NULL) {
    318         return (SOC_E_PARAM);
    319     }
    320     
    321     avs_info->num_centrals = SOC_AVS_SABER2_NUMBER_OF_CENTRALS;
    322     avs_info->cent_xbmp[0] = SOC_AVS_SABER2_CENTRAL_XBMP0;
    323     avs_info->cent_xbmp[1] = SOC_AVS_SABER2_CENTRAL_XBMP1;
    324     avs_info->first_cent = SOC_AVS_SABER2_FIRST_CENTRAL;
    325 
    326     avs_info->num_remotes = SOC_AVS_SABER2_NUMBER_OF_REMOTES;
    327     avs_info->rmt_xbmp[0] = SOC_AVS_SABER2_REMOTE_XBMP0;
    328     avs_info->first_rmt = SOC_AVS_SABER2_FIRST_REMOTE;
    329 
    330     avs_info->vmin_avs = SOC_AVS_INT(SOC_AVS_SABER2_VMIN_AVS);
    331     avs_info->vmax_avs = SOC_AVS_INT(SOC_AVS_SABER2_VMAX_AVS);
    332     avs_info->vmargin_low  = SOC_AVS_INT(SOC_AVS_SABER2_VMARGIN_LOW);
    333     avs_info->vmargin_high = SOC_AVS_INT(SOC_AVS_SABER2_VMARGIN_HIGH);
    334     
    335     avs_info->rosc_count_mode = SOC_AVS_ROSC_COUNT_MODE_1EDGE;
    336     avs_info->ref_clk_freq = 25;
    337     avs_info->measurement_time_control = 127;
    338     avs_info->osc_cen_init_info = _sb2_osc_cen_init_list;
    339     avs_info->osc_cen_thr_en_info = _sb2_osc_cen_thr_en_list;
    340     avs_info->osc_seq_reset_info = _sb2_osc_seq_reset_list;
    341 
    342     avs_info->avs_flags = SOC_AVS_INFO_F_SET_THRESHOLDS |
    343                           SOC_AVS_INFO_F_RSOC_THRESHOLD_CACHE; 
    344 
    345 #ifdef BCM_SBUSDMA_SUPPORT
    346     if (soc_feature(unit, soc_feature_sbusdma)) {
    347         avs_info->avs_flags |= SOC_AVS_INFO_F_RSOC_COUNT_DMA;
    348         avs_info->cen_osc_reg = AVS_REG_RO_REGISTERS_0_CEN_ROSC_STATUSr;
    349         avs_info->rmt_osc_reg = AVS_REG_PMB_SLAVE_AVS_ROSC_COUNTr;
    350     }
    351 #endif
    352     return SOC_E_NONE;
    353 }
    354 
    355 int
    356 _soc_saber2_avs_info_deinit(int unit)
    357 {
    358     return SOC_E_NONE;
    359 }
    360 
    361 soc_avs_functions_t _sb2_avs_functions;
    362 
    363 int
    364 soc_saber2_avs_init(int unit)
    365 {
    366     /* register avs functions*/
    367     memset(&_sb2_avs_functions, 0, sizeof(soc_avs_functions_t));
    368     _sb2_avs_functions.info_init = &_soc_saber2_avs_info_init;
    369     _sb2_avs_functions.info_deinit = &_soc_saber2_avs_info_deinit;
    370     _sb2_avs_functions.ioctl = &_soc_saber2_avs_info_ioctl;
    371 #if 0
    372     _sb2_avs_functions.voltage_set = &_soc_saber2_avs_voltage_set;
    373     _sb2_avs_functions.voltage_get = &_soc_saber2_avs_voltage_get;
    374 #endif
    375     soc_avs_function_register(unit, &_sb2_avs_functions);
    376     return 0;
    377 }
    378 #endif /* INCLUDE_AVS */