Example #1
0
// Function Specification
//
// Name:  populate_pstate_to_sapphire_tbl
//
// Description:
//
// End Function Specification
void populate_pstate_to_sapphire_tbl()
{
    uint8_t                 i = 0;
    GlobalPstateTable      *l_gpst_ptr = NULL;
    uint16_t                l_turboFreq = 0;
    uint16_t                l_ultraturboFreq = 0;

    if(G_sysConfigData.sys_mode_freq.table[OCC_MODE_STURBO] == 0)
    {
        // In this case, there is no UltraTurbo frequency defined. For OPAL-OCC
        // interface, make UltraTurbo = Turbo frequency
        l_turboFreq = G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO];
        l_ultraturboFreq = G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO];
    }
    else
    {
        l_turboFreq = G_sysConfigData.sys_mode_freq.table[OCC_MODE_STURBO];
        l_ultraturboFreq = G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO];
    }

    memset(&G_sapphire_table, 0, sizeof(sapphire_table_t));

    l_gpst_ptr = gpsm_gpst();
    const int8_t l_pmax = (int8_t) l_gpst_ptr->pmin + l_gpst_ptr->entries - 1;
    G_sapphire_table.config.valid = 0x01; // default 0x01
    G_sapphire_table.config.version = 0x02; // default 0x02
    G_sapphire_table.config.throttle = NO_THROTTLE; // default 0x00
    G_sapphire_table.config.pmin = gpst_pmin(&G_global_pstate_table)+1; //Per David Du, we must use pmin+1 to avoid gpsa hang
    G_sapphire_table.config.pnominal = (int8_t)proc_freq2pstate(G_sysConfigData.sys_mode_freq.table[OCC_MODE_NOMINAL]);
    G_sapphire_table.config.turbo = (int8_t) proc_freq2pstate(l_turboFreq);
    G_sapphire_table.config.ultraTurbo = (int8_t) proc_freq2pstate(l_ultraturboFreq);

    int8_t l_tempPmax = gpst_pmax(&G_global_pstate_table);
    const uint16_t l_entries = l_tempPmax - G_sapphire_table.config.pmin + 1;
    const uint8_t l_idx = l_gpst_ptr->entries-1;

    for (i = 0; i < l_entries; i++)
    {
        G_sapphire_table.data[i].pstate = (int8_t) l_pmax - i;
        G_sapphire_table.data[i].flag = 0; // default 0x00
        if (i < l_gpst_ptr->entries)
        {
            G_sapphire_table.data[i].evid_vdd = l_gpst_ptr->pstate[i].fields.evid_vdd;
            G_sapphire_table.data[i].evid_vcs = l_gpst_ptr->pstate[i].fields.evid_vcs;
        }
        else
        {
            // leave the VDD & VCS Vids the same as the "Pstate Table Pmin"
            G_sapphire_table.data[i].evid_vdd = l_gpst_ptr->pstate[l_idx].fields.evid_vdd;
            G_sapphire_table.data[i].evid_vcs = l_gpst_ptr->pstate[l_idx].fields.evid_vcs;
        }
        // extrapolate the frequency
        G_sapphire_table.data[i].freq_khz = l_gpst_ptr->pstate0_frequency_khz + (G_sapphire_table.data[i].pstate * l_gpst_ptr->frequency_step_khz);
    }

    uint8_t l_core = 0;
    uint16_t l_maxFreq = l_turboFreq;

    //Write the max pstate for each possible number of active cores.
    for (l_core = 1; l_core <= MAX_CORES; l_core++)
    {
        //If wof is enabled, then use the wof uplift table to find the max freq for given # of active cores.
        if (g_amec->wof.enable_parm != 0)
        {
            l_maxFreq = amec_wof_get_max_freq(l_core);
        }

        //If the l_core (# of Active cores) is greater than G_wof_max_cores_per_chip
        //then return 0x01 for Pstate.
        if (l_core > G_wof_max_cores_per_chip)
        {
            G_sapphire_table.activeCore_max_pstate[l_core - 1] = 0x01;
        }
        else
        {
            G_sapphire_table.activeCore_max_pstate[l_core - 1] = (int8_t)proc_freq2pstate((uint32_t)l_maxFreq);
        }
    }

    //For Version 0x02 of the interface, we need to make the first four reserved bytes
    //equal to 0x01 to prevent confusion
    for(i=0; i<4; i++)
    {
        G_sapphire_table.pad[i] = 0x01;
    }
}
Example #2
0
void
gpst_print(FILE *stream, GlobalPstateTable *gpst)
{
    // Endian-corrected scalar Pstate fields

    uint32_t options;
    uint32_t pstate0_frequency_khz, frequency_step_khz;
    uint8_t entries, pstate_stepsize, vrm_stepdelay_range, vrm_stepdelay_value;
//    Pstate pmin, pvsafe, psafe;
    Pstate pvsafe, psafe;


    // Endian-corrected vector Pstate fields

    gpst_entry_t entry;

    // Other local variables

    int i;
    uint8_t evid_vdd, evid_vcs, evid_vdd_eff, evid_vcs_eff,
    maxreg_vdd, maxreg_vcs;
    int8_t pstate;
    char evid_vdd_str[FORMAT_10UV_STRLEN];
    char evid_vcs_str[FORMAT_10UV_STRLEN];
    char evid_vdd_eff_str[FORMAT_10UV_STRLEN];
    char evid_vcs_eff_str[FORMAT_10UV_STRLEN];
    char maxreg_vdd_str[FORMAT_10UV_STRLEN];
    char maxreg_vcs_str[FORMAT_10UV_STRLEN];
    char* ivrm_max_ps_str;
    char* ultraturbo_ps_str;
    char* turbo_ps_str;
    char* nominal_ps_str; 
    char* powersave_ps_str;

    
    // Get endian-corrected scalars

    options = revle32(gpst->options.options);
    pstate0_frequency_khz = revle32(gpst->pstate0_frequency_khz);
    frequency_step_khz = revle32(gpst->frequency_step_khz);
    entries = gpst->entries;
    pstate_stepsize = gpst->pstate_stepsize;
    vrm_stepdelay_range = gpst->vrm_stepdelay_range;
    vrm_stepdelay_value = gpst->vrm_stepdelay_value;
//    pmin = gpst->pmin;
    pvsafe = gpst->pvsafe;
    psafe = gpst->psafe;


    fprintf(stream,
        "---------------------------------------------------------------------------------------------------------\n");
    fprintf(stream, "Global Pstate Table @ %p\n", gpst);
    fprintf(stream,
        "---------------------------------------------------------------------------------------------------------\n");
    fprintf(stream, "%d Entries from %+d to %+d\n",
        entries, gpst_pmin(gpst), gpst_pmax(gpst));
    fprintf(stream, "Frequency Step = %u KHz\n", frequency_step_khz);
    fprintf(stream, "Pstate 0 Frequency = %u KHz\n", pstate0_frequency_khz);
    fprintf(stream, "Pstate 0 Frequency Code (per core) :");
    for (i = 0; i < PGP_NCORES; i++) {
        if ((i != 0) && ((i % 4) == 0)) {
            fprintf(stream, "\n                                    ");
        }
        fprintf(stream, " 0x%03x", revle16(gpst->pstate0_frequency_code[i]));
    }
    fprintf(stream, "\n");
    fprintf(stream, "DPLL Fmax Bias (per core)          :");
    for (i = 0; i < PGP_NCORES; i++) {
        fprintf(stream, " %d", gpst->dpll_fmax_bias[i]);
    }
    fprintf(stream, "\n");
    fprintf(stream, "Pstate Step Size %u, VRM Range %u, VRM Delay %u\n",
            pstate_stepsize, vrm_stepdelay_range, vrm_stepdelay_value);
    fprintf(stream, "Pvsafe %d, Psafe %d\n", pvsafe, psafe);
    
    fprintf(stream, "iVRM Maximum Pstate %d, Number of GPST entries (from Psafe) where iVRMs are enabled: %d\n", 
            gpst->ivrm_max_ps, gpst->ivrm_entries);
    

    if (options == 0) {
        fprintf(stream, "No Options\n");
    } else {
        fprintf(stream, "Options 0x%08x:\n", options);
        if (options & PSTATE_NO_COPY_GPST) {
            fprintf(stream, "    PSTATE_NO_COPY_GPST\n");
        }
        if (options & PSTATE_NO_INSTALL_GPST) {
            fprintf(stream, "    PSTATE_NO_INSTALL_GPST\n");
        }
        if (options & PSTATE_NO_INSTALL_LPSA) {
            fprintf(stream, "    PSTATE_NO_INSTALL_LPSA\n");
        }
        if (options & PSTATE_NO_INSTALL_RESCLK) {
            fprintf(stream, "    PSTATE_NO_INSTALL_RESCLK\n");
        }
        if (options & PSTATE_FORCE_INITIAL_PMIN) {
            fprintf(stream, "    PSTATE_FORCE_INITIAL_PMIN\n");
        }
        if (options & PSTATE_IDDQ_0P80V_VALID) {
            fprintf(stream, "    PSTATE_IDDQ_0P80V_VALID\n");
        }
    }
    fprintf(stream,
        "---------------------------------------------------------------------------------------------------------\n");
    fprintf(stream,
        "  I Pstate F(MHz) evid_vdd(V)  evid_vcs(V) evid_vdd_eff(V) evid_vcs_eff(V) maxreg_vdd(V)  maxreg_vcs(V)\n"
        "---------------------------------------------------------------------------------------------------------\n");

    for (i = gpst->entries - 1; i >= 0; i--) {

        entry.value = revle64(gpst->pstate[i].value);

    evid_vdd = entry.fields.evid_vdd;
    sprintf_vrm11(evid_vdd_str, evid_vdd);

    evid_vcs = entry.fields.evid_vcs;
    sprintf_vrm11(evid_vcs_str, evid_vcs);

    evid_vdd_eff = entry.fields.evid_vdd_eff;
    sprintf_ivid(evid_vdd_eff_str, evid_vdd_eff);

    evid_vcs_eff = entry.fields.evid_vcs_eff;
    sprintf_ivid(evid_vcs_eff_str, evid_vcs_eff);

    maxreg_vdd = entry.fields.maxreg_vdd;
    sprintf_ivid(maxreg_vdd_str, maxreg_vdd);

    maxreg_vcs = entry.fields.maxreg_vcs;
    sprintf_ivid(maxreg_vcs_str, maxreg_vcs);

    pstate = gpst_pmin(gpst) + i;
    
    ultraturbo_ps_str = "";
    if (pstate == 0 && gpst->turbo_ps != 0)
        ultraturbo_ps_str = " <--- UltraTurbo";
    
    turbo_ps_str = "";
    if (pstate == gpst->turbo_ps)
        turbo_ps_str = " <--- Turbo";
    
    nominal_ps_str = "";
    if (pstate == gpst->nominal_ps)
        nominal_ps_str = " <--- Nominal";   
        
    powersave_ps_str = "";
    if (pstate == gpst->powersave_ps)
        powersave_ps_str = " <--- PowerSave";   
    
    ivrm_max_ps_str = "";
    if (pstate == gpst->ivrm_max_ps)
        ivrm_max_ps_str = " <--- iVRM Maximum";
       
    fprintf(stream,
        "%3d %+4d    "
        "%4d  "
        "0x%02x %s  "
        "0x%02x %s  "
        "0x%02x %s    "
        "0x%02x %s   "
        "0x%02x %s   "
        "0x%02x %s "
        "%s%s%s%s%s\n",
        i, pstate,
        (pstate0_frequency_khz + (frequency_step_khz * pstate)) / 1000,
        evid_vdd, evid_vdd_str,
        evid_vcs, evid_vcs_str,
        evid_vdd_eff, evid_vdd_eff_str,
        evid_vcs_eff, evid_vcs_eff_str,
        maxreg_vdd, maxreg_vdd_str,
        maxreg_vcs, maxreg_vcs_str,
        ultraturbo_ps_str,
        turbo_ps_str,
        nominal_ps_str,
        powersave_ps_str,
        ivrm_max_ps_str);
    }
    fprintf(stream,
        "---------------------------------------------------------------------------------------------------------\n");
}
Example #3
0
// Function Specification
//
// Name:  proc_pstate_kvm_setup
//
// Description: Get everything set up for KVM mode
//
// End Function Specification
void proc_pstate_kvm_setup()
{
    int                                 l_core;
    int                                 l_rc = 0;
    uint32_t                            l_configured_cores;
    pcbs_pcbspm_mode_reg_t              l_ppmr;
    pcbs_pmgp1_reg_t                    l_pmgp1;
    pcbs_power_management_bounds_reg_t  l_pmbr;
    errlHndl_t                          l_errlHndl;

    do
    {
        //only run this in KVM mode
        if(!G_sysConfigData.system_type.kvm)
        {
            break;
        }

        l_configured_cores = ~in32(PMC_CORE_DECONFIGURATION_REG);

        // Do per-core configuration
        for(l_core = 0; l_core < PGP_NCORES; l_core++, l_configured_cores <<= 1)
        {
            if(!(l_configured_cores & 0x80000000)) continue;

            //do read-modify-write to allow pmax clip to also clip voltage (not just frequency)
            l_rc = getscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PCBSPM_MODE_REG, l_core),
                       &(l_ppmr.value), NULL); //commit errors internally
            if(l_rc)
            {
                TRAC_ERR("proc_pstate_kvm_setup: getscom(PCBS_PCBSPM_MODE_REG) failed. rc=%d, hw_core=%d",
                         l_rc, l_core);
                break;
            }
            l_ppmr.fields.enable_clipping_of_global_pstate_req = 1;
            l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PCBSPM_MODE_REG, l_core),
                 l_ppmr.value, NULL); //commit errors internally
            if(l_rc)
            {
                TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_PCBSPM_MODE_REG) failed. rc=%d, hw_core=%d",
                         l_rc, l_core);
                break;
            }

            //per Vaidy Srinivasan, clear bit 11 in the Power Management GP1 register
            l_pmgp1.value = 0;
            l_pmgp1.fields.pm_spr_override_en = 1;
            l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PMGP1_REG_AND, l_core),
                           ~l_pmgp1.value, NULL); //commit errors internally
            if(l_rc)
            {
                TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_PMGB1_REG_OR) failed. rc=0x%08x, hw_core=%d",
                         l_rc, l_core);
                break;
            }

            //set pmax/pmin clip initial settings
            l_pmbr.value = 0;
            l_pmbr.fields.pmin_clip = gpst_pmin(&G_global_pstate_table)+1; //Per David Du, we must use pmin+1 to avoid gpsa hang
            l_pmbr.fields.pmax_clip = gpst_pmax(&G_global_pstate_table);
            l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_POWER_MANAGEMENT_BOUNDS_REG, l_core),
                           l_pmbr.value, NULL); //commit errors internally
            if(l_rc)
            {
                TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_POWER_MANAGEMENT_BOUNDS_REG) failed. rc=0x%08x, hw_core=%d",
                         l_rc, l_core);
                break;
            }

        }// end of per-core config

        if(l_rc)
        {
            break;
        }

        // Set the voltage clipping register to match the pmax/pmin clip values set above.
        pmc_rail_bounds_register_t prbr;
        prbr.value = in32(PMC_RAIL_BOUNDS_REGISTER);
        prbr.fields.pmin_rail = gpst_pmin(&G_global_pstate_table);
        prbr.fields.pmax_rail = gpst_pmax(&G_global_pstate_table);
        TRAC_IMP("pmin clip pstate = %d, pmax clip pstate = %d", prbr.fields.pmin_rail, prbr.fields.pmax_rail);
        out32(PMC_RAIL_BOUNDS_REGISTER, prbr.value);

        // Initialize the sapphire table in SRAM (sets valid bit)
        populate_pstate_to_sapphire_tbl();

        // copy sram image into mainstore HOMER
        populate_sapphire_tbl_to_mem();
        TRAC_IMP("proc_pstate_kvm_setup: RUNNING IN KVM MODE");
    }while(0);

    if(l_rc)
    {
        // Create Error Log and request reset
        /* @
         * @errortype
         * @moduleid    PROC_PSTATE_KVM_SETUP_MOD
         * @reasoncode  PROC_SCOM_ERROR
         * @userdata1   l_configured_cores
         * @userdata2   Return Code of call that failed
         * @userdata4   OCC_NO_EXTENDED_RC
         * @devdesc     OCC failed to scom a core register
         */
        l_errlHndl = createErrl(
                PROC_PSTATE_KVM_SETUP_MOD,          //modId
                PROC_SCOM_ERROR,                    //reasoncode
                OCC_NO_EXTENDED_RC,                 //Extended reason code
                ERRL_SEV_PREDICTIVE,                //Severity
                NULL,                               //Trace Buf
                DEFAULT_TRACE_SIZE,                 //Trace Size
                l_configured_cores,                 //userdata1
                l_rc                                //userdata2
                );

        addCalloutToErrl(l_errlHndl,
                ERRL_CALLOUT_TYPE_HUID,
                G_sysConfigData.proc_huid,
                ERRL_CALLOUT_PRIORITY_HIGH);
        addCalloutToErrl(l_errlHndl,
                ERRL_CALLOUT_TYPE_COMPONENT_ID,
                ERRL_COMPONENT_ID_FIRMWARE,
                ERRL_CALLOUT_PRIORITY_MED);

        REQUEST_RESET(l_errlHndl);
    }
}