/* ------------------------------------------------------------------------*//** * @FUNCTION irq_occurred_list_sort * @BRIEF sort list by irq occurrence decreasing order * @RETURNS 0 in case of success * IRQ_ERR_ARG * IRQ_ERR_INTERNAL * @param[in,out] list: populated list of IRQ stats. * @DESCRIPTION sort list by irq occurrence decreasing order. * Use bubble sort algorithm. *//*------------------------------------------------------------------------ */ int irq_occurred_list_sort(genlist *list) { unsigned int i, max, tmpmax; irq_info inf1, inf2; if (list == NULL) { fprintf(stderr, "%s(): list = NULL!\n", __func__); return IRQ_ERR_ARG; } max = genlist_getcount(list); while (max > 0) { tmpmax = 0; for (i = 0; i < max - 1; i++) { genlist_get(list, i, (irq_info *) &inf1); genlist_get(list, i + 1, (irq_info *) &inf2); if (inf1.count < inf2.count) { genlist_add(list, (void *) &inf2, sizeof(irq_info), i); genlist_remove(list, i + 2); tmpmax = i + 1; } } max = tmpmax; } return 0; }
/* ------------------------------------------------------------------------*//** * @FUNCTION powerdm_init * @BRIEF initialize internal data * @DESCRIPTION initialize internal data (architecture dependent) *//*------------------------------------------------------------------------ */ void powerdm_init(void) { #ifdef PWRDM_DEBUG int i, count; const genlist *pwrdm_list; powerdm_info pwrdm; #endif if (cpu_is_omap44xx()) { pwrdm44xx_init(); } else if (cpu_is_omap54xx()) { pwrdm54xx_init(); } else { fprintf(stderr, "omapconf: %s(): cpu not supported!!!\n", __func__); } #ifdef PWRDM_DEBUG pwrdm_list = powerdm_list_get(); count = genlist_getcount((genlist *) pwrdm_list); printf("Power Domain List:\n"); for (i = 0; i < count; i++) { genlist_get((genlist *) pwrdm_list, i, (powerdm_info *) &pwrdm); printf(" %s:\n", pwrdm.name); printf(" ID:%d\n", pwrdm.id); printf(" VoltDM: %s\n", pwrdm.voltdm); printf(" PWRSTCTRL REG: %s\n", (pwrdm.pwrstctrl)->name); printf(" PWRSTST REG: %s\n", (pwrdm.pwrstst)->name); printf(" Properties: %d\n", pwrdm.properties); printf("\n\n"); } printf("Power Domain count: %d\n\n", count); #endif }
/************************************************************************** Called when the return key is pressed. **************************************************************************/ static void inputline_return(GtkEntry *w, gpointer data) { const char *theinput; theinput = gtk_entry_get_text(w); if (*theinput) { if (client_state() == C_S_RUNNING && gui_gtk2_allied_chat_only && is_plain_public_message(theinput)) { char buf[MAX_LEN_MSG]; fc_snprintf(buf, sizeof(buf), ". %s", theinput); send_chat(buf); } else { send_chat(theinput); } if (genlist_size(history_list) >= MAX_CHATLINE_HISTORY) { void *data; data = genlist_get(history_list, -1); genlist_remove(history_list, data); free(data); } genlist_prepend(history_list, fc_strdup(theinput)); history_pos=-1; } gtk_entry_set_text(w, ""); }
/***************************************************************************** Called when the return key is pressed. *****************************************************************************/ static void luaconsole_input_return(GtkEntry *w, gpointer data) { const char *theinput; struct luaconsole_data *pdialog = luaconsole_dialog_get(); fc_assert_ret(pdialog); fc_assert_ret(pdialog->history_list); theinput = gtk_entry_get_text(w); if (*theinput) { luaconsole_printf(ftc_luaconsole_input, "(input)> %s", theinput); script_client_do_string(theinput); if (genlist_size(pdialog->history_list) >= MAX_LUACONSOLE_HISTORY) { void *data; data = genlist_get(pdialog->history_list, -1); genlist_remove(pdialog->history_list, data); free(data); } genlist_prepend(pdialog->history_list, fc_strdup(theinput)); pdialog->history_pos = -1; } gtk_entry_set_text(w, ""); }
/***************************************************************************** Called when a key is pressed. *****************************************************************************/ static gboolean luaconsole_input_handler(GtkWidget *w, GdkEventKey *ev) { struct luaconsole_data *pdialog = luaconsole_dialog_get(); fc_assert_ret_val(pdialog, FALSE); fc_assert_ret_val(pdialog->history_list, FALSE); switch (ev->keyval) { case GDK_Up: if (pdialog->history_pos < genlist_size(pdialog->history_list) - 1) { gtk_entry_set_text(GTK_ENTRY(w), genlist_get(pdialog->history_list, ++pdialog->history_pos)); gtk_editable_set_position(GTK_EDITABLE(w), -1); } return TRUE; case GDK_Down: if (pdialog->history_pos >= 0) { pdialog->history_pos--; } if (pdialog->history_pos >= 0) { gtk_entry_set_text(GTK_ENTRY(w), genlist_get(pdialog->history_list, pdialog->history_pos)); } else { gtk_entry_set_text(GTK_ENTRY(w), ""); } gtk_editable_set_position(GTK_EDITABLE(w), -1); return TRUE; default: break; } return FALSE; }
/* ------------------------------------------------------------------------*//** * @FUNCTION mod_dra7xx_deinit * @BRIEF free dynamically allocated internal data. * @DESCRIPTION free dynamically allocated internal data. * MUST BE CALLED AT END OF EXECUTION. *//*------------------------------------------------------------------------ */ void mod_dra7xx_deinit(void) { int i, count; mod_info mod; if (mod_dra7xx_init_done) { count = genlist_getcount(&mod_dra7xx_list); for (i = 0; i < count; i++) { genlist_get(&mod_dra7xx_list, i, (mod_info *) &mod); genlist_free(&(mod.mod_opp_list)); } genlist_free(&mod_dra7xx_list); mod_dra7xx_init_done = 0; } dprintf("%s(): deinit done.\n", __func__); }
/* ------------------------------------------------------------------------*//** * @FUNCTION _powerdm_info_get * @BRIEF return the saved informations of a given power domain. * @RETURNS 0 in case of success * -1 in case of error * @param[in] powerdm: power domain name * @param[in,out] data: power domain details * @DESCRIPTION return the saved informations of a given power domain. *//*------------------------------------------------------------------------ */ static int _powerdm_info_get(const char *powerdm, powerdm_info *data) { const genlist *pwrdm_list; int i, count; CHECK_NULL_ARG(powerdm, -1); CHECK_NULL_ARG(data, -1); pwrdm_list = powerdm_list_get(); count = genlist_getcount((genlist *) pwrdm_list); for (i = 0; i < count; i++) { genlist_get((genlist *) pwrdm_list, i, (void *) data); if (strcmp(data->name, powerdm) == 0) { dprintf("%s(%s): found.\n", __func__, powerdm); return 0; } } dprintf("%s(%s): not found!\n", __func__, powerdm); return -1; }
/* ------------------------------------------------------------------------*//** * @FUNCTION voltdm_init * @BRIEF initialize internal data * @DESCRIPTION initialize internal data (architecture dependent) *//*------------------------------------------------------------------------ */ void voltdm_init(void) { #ifdef VOLTDM_DEBUG int i, count; const genlist *voltdm_list; voltdm_info voltdm; #endif if (cpu_is_omap44xx()) { voltdm44xx_init(); } else if (cpu_is_omap54xx()) { voltdm54xx_init(); } else { fprintf(stderr, "omapconf: %s(): cpu not supported!!!\n", __func__); } #ifdef VOLTDM_DEBUG voltdm_list = voltdm_list_get(); count = genlist_getcount((genlist *) voltdm_list); printf("Voltage Domain List:\n"); for (i = 0; i < count; i++) { genlist_get((genlist *) voltdm_list, i, (voltdm_info *) &voltdm); printf(" %s:\n", voltdm.name); printf(" ID:%d\n", voltdm.id); if (voltdm.voltst == NULL) printf(" Status Register: does not exist\n"); else printf(" Status Register: %s\n", reg_name_get(voltdm.voltst)); printf("\n\n"); } printf("Voltage Domain count: %d\n\n", count); #endif }
/* ------------------------------------------------------------------------*//** * @FUNCTION temp_sensor_show * @BRIEF display all available temperatures formatted in a table. * @RETURNS temperatures formatted in a table * OMAPCONF_ERR_CPU * OMAPCONF_ERR_ARG * OMAPCONF_ERR_INTERNAL * OMAPCONF_ERR_NOT_AVAILABLE * @param[in,out] stream: output file * @param[in,out] sensor: generic temperature sensor name * Use "all" to show all temperatures * @param[in] hw: use s/w (driver based) read or hw_sensor read? * @DESCRIPTION display all available temperatures formatted in a table. * Display both Celcius and Fahrenheit degrees. *//*------------------------------------------------------------------------ */ static int _temp_sensor_show(FILE *stream, const char *sensor, const char hw) { char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row = 0; int i, count, temp, temp_f; char temp_s[EMIF_TEMP_MAX_NAME_LENGTH]; const char sensor2[TEMP_SENSOR_MAX_NAME_LENGTH]; const genlist *list; CHECK_NULL_ARG(stream, OMAPCONF_ERR_ARG); CHECK_NULL_ARG(sensor, OMAPCONF_ERR_ARG); if (strcasecmp(sensor, "all") != 0) { if (!temp_sensor_is_available(sensor)) { fprintf(stderr, "omapconf: '%s' temperature sensor is not available!\n", sensor); return OMAPCONF_ERR_NOT_AVAILABLE; } if (hw) temp = hwtemp_sensor_get(sensor); else temp = temp_sensor_get(sensor); if (temp == TEMP_ABSOLUTE_ZERO) { fprintf(stderr, "omapconf: could not retrieve '%s' temperature!\n", sensor); return OMAPCONF_ERR_INTERNAL; } else if ((strcasecmp(sensor, TEMP_SENSOR_MEM1) == 0) || (strcasecmp(sensor, TEMP_SENSOR_MEM2) == 0)) { fprintf(stream, "%s\n", emif_mr4_convert((emif_mr4_code) temp, TEMP_CELCIUS_DEGREES)); return 0; } else { fprintf(stream, "%d\n", temp); return 0; } } /* Retrieve temperature sensor list */ list = temp_sensor_list_get(); if (list == NULL) { fprintf(stderr, "omapconf: CPU not yet supported, sorry...\n"); return OMAPCONF_ERR_INTERNAL; } /* Retrieve temperature sensor list count */ count = temp_sensor_count_get(); if (count <= 0) { fprintf(stderr, "omapconf: could not retrieve sensor count!\n"); return OMAPCONF_ERR_INTERNAL; } dprintf("found %d temperature sensors\n", count); /* Fill table header */ row = 0; autoadjust_table_init(table); autoadjust_table_strncpy(table, row, 0, "Sensor"); autoadjust_table_strncpy(table, row, 1, "Temperature (C)"); autoadjust_table_strncpy(table, row++, 2, "Temperature (F)"); /* Fill table with temperatures */ for (i = 0; i < count; i++) { genlist_get((genlist *) list, i, (char *) &sensor2); if (sensor2 == NULL) { fprintf(stderr, "omapconf: could not retrieve sensor!\n"); return OMAPCONF_ERR_INTERNAL; } autoadjust_table_strncpy(table, row, 0, (char *) sensor2); dprintf("%s(): sensor is %s\n", __func__, sensor2); if (hw) temp = hwtemp_sensor_get(sensor2); else temp = temp_sensor_get(sensor2); if (temp != TEMP_ABSOLUTE_ZERO) { if ((strcasecmp(sensor2, TEMP_SENSOR_MEM1) == 0) || (strcasecmp(sensor2, TEMP_SENSOR_MEM2) == 0)) { sprintf(temp_s, "%s", emif_mr4_convert((emif_mr4_code) temp, TEMP_CELCIUS_DEGREES)); autoadjust_table_strncpy(table, row, 1, temp_s); sprintf(temp_s, "%s", emif_mr4_convert((emif_mr4_code) temp, TEMP_FAHRENHEIT_DEGREES)); autoadjust_table_strncpy(table, row++, 2, temp_s); } else { sprintf(temp_s, "%d", temp); autoadjust_table_strncpy(table, row, 1, temp_s); temp_f = celcius2fahrenheit(temp); sprintf(temp_s, "%d", temp_f); autoadjust_table_strncpy(table, row++, 2, temp_s); } } else { autoadjust_table_strncpy(table, row, 1, "NA"); autoadjust_table_strncpy(table, row++, 2, "NA"); } } /* Display table */ return autoadjust_table_fprint(stream, table, row, 3); }
/* ------------------------------------------------------------------------*//** * @FUNCTION audit_performances * @BRIEF audit performances (CPU Load, C-States, OPP, * memory bandwidth, timers, interrrupts, ...). * @RETURNS 0 in case of success * OMAPCONF_ERR_CPU * OMAPCONF_ERR_ARG * OMAPCONF_ERR_NOT_AVAILABLE * @param[in] stream: output file (NULL: no output (silent)) * @param[in] duration: audit duration, in seconds (>= 1). * @param[in] delay: initial wait delay before starting audit (in sec) * @DESCRIPTION audit performance (CPU Load, C-States, OPP, * memory bandwidth, timers, interrrupts, ...). *//*------------------------------------------------------------------------ */ int audit_performances(FILE *stream, unsigned int duration, unsigned int delay) { int ret; unsigned short skip_proc_stats_audit; unsigned int cpu_cores_cnt, cpu_online_cores_cnt; unsigned short *cpu_online; unsigned int *idle_t0, *iowait_t0, *sum_t0; unsigned int *idle_t1, *iowait_t1, *sum_t1; unsigned int *idle_cnt, *iowait_cnt, *sum_cnt; double *load, load_total; unsigned int cstates_nbr; uint64_t cstates_usage[MAX_CSTATE][3]; uint64_t cstates_time[MAX_CSTATE][3]; unsigned short emif; unsigned int emif_busy_cycles[2]; unsigned int emif_cycles[2]; unsigned int emif_delta_cycles, emif_delta_busy_cycles; double emif_load; uint64_t *time_in_opp_t0 = NULL; uint64_t *time_in_opp_t1 = NULL; uint64_t *time_in_opp_cnt = NULL; uint64_t total_trans_t0, total_trans_t1, total_trans_cnt; unsigned int i; uint64_t sec, msec, usec, active_c0_time; double pct; char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row = 0; char name[16]; FILE *fp = NULL; char perf_summary_file[64]; FILE *fp_irq_1, *fp_irq_2, *fp_timerstats; unsigned int irq_total_count, occurred_irq_count, timer_count; genlist occurred_irq_list, timerstats_list; irq_info irq_inf; timerstat_info timer_inf; char irq_snap_file1[32]; char irq_snap_file2[32]; char timerstats_file[32]; char timerstats_summary[256]; unsigned int skip_irq_audit, skip_cstate_audit; int skip_timerstats_audit; char *workdir; unsigned short skip_cpufreq_audit; unsigned int opp_cnt; if (duration == 0) { fprintf(stream, "Duration should be at least 1 second ...\n\n"); ret = OMAPCONF_ERR_ARG; goto audit_performances_exit; } if (!cpu_is_omap44xx() && !cpu_is_omap54xx()) { fprintf(stream, "Unsupported platform, sorry...\n\n"); ret = OMAPCONF_ERR_CPU; goto audit_performances_exit; } /* Retrieve a writable directory */ workdir = workdir_get(); if (workdir != NULL) { strcpy(irq_snap_file1, workdir); strcpy(irq_snap_file2, workdir); strcpy(timerstats_file, workdir); strcpy(perf_summary_file, workdir); strcat(irq_snap_file1, "proc_interrupts_1"); strcat(irq_snap_file2, "proc_interrupts_2"); strcat(timerstats_file, "proc_timerstats"); strcat(perf_summary_file, "performance_audit_report.txt"); skip_irq_audit = 0; skip_timerstats_audit = 0; } else { skip_irq_audit = 1; skip_timerstats_audit = 1; } /* Open trace output file */ fp = fopen(perf_summary_file, "w"); if (fp == NULL) { fprintf(stderr, "%s(): could not create %s!\n", __func__, perf_summary_file); } else { fprintf(fp, "OMAP Performance Audit Summary\n\n"); omapconf_revision_show(fp); chips_info_show(fp, 1); release_info_show(fp); } /* Retrieve number of CPU cores and allocate buffers */ cpu_cores_cnt = cpu_cores_count_get(); if (cpu_cores_cnt < 1) { skip_proc_stats_audit = 1; } else { dprintf("%s(): found %u cores\n", __func__, cpu_cores_cnt); cpu_online = malloc(cpu_cores_cnt * sizeof(unsigned int)); idle_t0 = malloc(cpu_cores_cnt * sizeof(unsigned int)); iowait_t0 = malloc(cpu_cores_cnt * sizeof(unsigned int)); sum_t0 = malloc(cpu_cores_cnt * sizeof(unsigned int)); idle_t1 = malloc(cpu_cores_cnt * sizeof(unsigned int)); iowait_t1 = malloc(cpu_cores_cnt * sizeof(unsigned int)); sum_t1 = malloc(cpu_cores_cnt * sizeof(unsigned int)); idle_cnt = malloc(cpu_cores_cnt * sizeof(unsigned int)); iowait_cnt = malloc(cpu_cores_cnt * sizeof(unsigned int)); sum_cnt = malloc(cpu_cores_cnt * sizeof(unsigned int)); load = malloc(cpu_cores_cnt * sizeof(double)); if ((cpu_online == NULL) || (idle_t0 == NULL) || (iowait_t0 == NULL) || (sum_t0 == NULL) || (idle_t1 == NULL) || (iowait_t1 == NULL) || (sum_t1 == NULL) || (iowait_cnt == NULL) || (iowait_cnt == NULL) || (sum_cnt == NULL) || (load == NULL)) { fprintf(stderr, "%s(): could not allocate buffers for " "CPU stats!\n", __func__); skip_proc_stats_audit = 1; } dprintf("%s(): CPU stats buffers allocated.\n", __func__); skip_proc_stats_audit = 0; } /* Retrieve number of MPU OPPs and allocate buffers */ opp_cnt = cpufreq_opp_nbr_get(); if (opp_cnt == 0) { skip_cpufreq_audit = 1; } else { dprintf("%s(): found %u MPU OPPs\n", __func__, opp_cnt); time_in_opp_t0 = malloc(opp_cnt * sizeof(uint64_t)); time_in_opp_t1 = malloc(opp_cnt * sizeof(uint64_t)); time_in_opp_cnt = malloc(opp_cnt * sizeof(uint64_t)); if ((time_in_opp_t0 == NULL) || (time_in_opp_t1 == NULL) || (time_in_opp_cnt == NULL)) { fprintf(stderr, "%s(): could not allocate buffers for " "CPUFREQ stats!\n", __func__); skip_cpufreq_audit = 1; } dprintf("%s(): CPUFREQ stats buffers allocated.\n", __func__); skip_cpufreq_audit = 0; } /* Configure EMIF counters to count data bus busy cycles (OMAP4) */ if (cpu_is_omap44xx()) { ret = emif44xx_perf_cnt_configure(EMIF44XX_0, EMIF44XX_PERF_CNT_1, EMIF44XX_PERF_CNT_FILTER_DATA_TRANSFER_CYCLES, -1, EMIF44XX_MEMADDRSPACE_DISABLED); ret |= emif44xx_perf_cnt_configure(EMIF44XX_1, EMIF44XX_PERF_CNT_1, EMIF44XX_PERF_CNT_FILTER_DATA_TRANSFER_CYCLES, -1, EMIF44XX_MEMADDRSPACE_DISABLED); if (ret != 0) { strncpy(timerstats_summary, "Unexpected error occurred while configuring " "EMIF performance counters!!!\n\n", 256); if (stream != NULL) fputs(timerstats_summary, stream); if (fp != NULL) fputs(timerstats_summary, fp); ret = OMAPCONF_ERR_NOT_AVAILABLE; goto audit_performances_exit; } dprintf("%s(): EMIF counters configured.\n", __func__); } /* Retrieve number of active C-State(s) */ cstates_nbr = cstate_get_number(); if (cstates_nbr == 0) { cstates_nbr = 0; skip_cstate_audit = 1; } else { skip_cstate_audit = 0; dprintf("%s(): found %u C-State(s)\n", __func__, cstates_nbr); } if (fp != NULL) { fprintf(fp, "Audit duration: %us\n", duration); fprintf(fp, "Audit initial delay: %us\n\n", delay); } /* Initial delay before starting capture */ if (delay >= 1) { if (stream != NULL) fprintf(stream, "Wait for initial delay (%u sec), then" " sample various Key Performance Indicators " "over %u second(s) ...\n\n", delay, duration); sleep(delay); } else { if (stream != NULL) fprintf(stream, "Sampling various Key Performance Indicators " "over %u second(s) ...\n\n", duration); } /* Save current C-State usage & time counters */ if (skip_cstate_audit == 0) { for (i = 0; i < cstates_nbr; i++) { cstates_usage[i][0] = cstate_get_usage(i); cstates_time[i][0] = cstate_get_time(i); } } /* Save current cpufreq stats */ if (skip_cpufreq_audit == 0) { for (i = 0; i < opp_cnt; i++) { time_in_opp_t0[i] = cpufreq_time_in_state_get(i); dprintf("%s(): time_in_opp_t0[%u] = %llu\n", __func__, i, time_in_opp_t0[i]); } total_trans_t0 = cpufreq_total_transitions_get(); } /* Save current cpu usage stats */ if (skip_proc_stats_audit == 0) { for (i = 0; i < cpu_cores_cnt; i++) { ret = cpu_proc_stats_get(i, &idle_t0[i], &iowait_t0[i], &sum_t0[i]); if (ret != 0) { cpu_online[i] = 0; dprintf("%s(): CPU%u offline\n", __func__, i); } else { cpu_online[i] = 1; } } } /* Get current EMIFs total & data transfer cycles */ if (cpu_is_omap44xx()) { emif_busy_cycles[0] = 0; for (emif = 0; emif < EMIF44XX_MAX; emif++) { emif_busy_cycles[0] += emif44xx_perf_cnt_get_count( (emif44xx_ids) emif, EMIF44XX_PERF_CNT_1); } emif_cycles[0] = emif44xx_perf_cnt_get_time(EMIF44XX_0); } /* Save current interrupt stats */ if (skip_irq_audit != 1) { ret = irq_snapshot_save(irq_snap_file1); if (ret != 0) skip_irq_audit = 1; } /* Save current timer stats */ /* Stop timer statistic collector, if enabled */ skip_timerstats_audit = timerstats_stop(); if (skip_timerstats_audit == 0) skip_timerstats_audit = timerstats_start(); /* Sleep for some time before sampling again usage counters */ sleep(duration); /* Get new EMIFs total & data transfer cycles */ if (cpu_is_omap44xx()) { emif_busy_cycles[1] = 0; for (emif = 0; emif < EMIF44XX_MAX; emif++) { emif_busy_cycles[1] += emif44xx_perf_cnt_get_count( (emif44xx_ids) emif, EMIF44XX_PERF_CNT_1); } emif_cycles[1] = emif44xx_perf_cnt_get_time(EMIF44XX_0); } if (skip_timerstats_audit == 0) skip_timerstats_audit = timerstats_stop(); /* Get new interrupts stats */ if (skip_irq_audit == 0) { ret = irq_snapshot_save(irq_snap_file2); if (ret != 0) { skip_irq_audit = 1; remove(irq_snap_file1); } } if (skip_timerstats_audit == 0) timerstats_save(timerstats_file); /* Get new cpu usage stats*/ if (skip_proc_stats_audit == 0) { for (i = 0; i < cpu_cores_cnt; i++) { ret = cpu_proc_stats_get(i, &idle_t1[i], &iowait_t1[i], &sum_t1[i]); if (ret != 0) { cpu_online[i] = 0; dprintf("%s(): CPU%u offline\n", __func__, i); } else { cpu_online[i] = 1; } } } /* Get new cpufreq stats */ if (skip_cpufreq_audit == 0) { for (i = 0; i < opp_cnt; i++) { time_in_opp_t1[i] = cpufreq_time_in_state_get(i); dprintf("%s(): time_in_opp_t1[%u] = %llu\n", __func__, i, time_in_opp_t1[i]); } total_trans_t1 = cpufreq_total_transitions_get(); } /* Get new C-State usage counters */ if (skip_cstate_audit == 0) { for (i = 0; i < cstates_nbr; i++) { cstates_usage[i][1] = cstate_get_usage(i); cstates_time[i][1] = cstate_get_time(i); dprintf("%s(): cstates_usage[%u][0] = " "%llu\n", __func__, i, cstates_usage[i][0]); dprintf("%s(): cstates_usage[%u][1] = " "%llu\n", __func__, i, cstates_usage[i][1]); dprintf("%s(): cstates_time[%u][0] = " "%llu\n", __func__, i, cstates_time[i][0]); dprintf("%s(): cstates_time[%u][1] = " "%llu\n", __func__, i, cstates_time[i][1]); } } /* Process data */ if (cpu_is_omap44xx()) { emif_delta_busy_cycles = count32_delta( emif_busy_cycles[0], emif_busy_cycles[1]); emif_delta_cycles = 2 * count32_delta( emif_cycles[0], emif_cycles[1]); dprintf("%s(): EMIF delta_busy_cycles=%u, delta_cycles=%u\n", __func__, emif_delta_busy_cycles, emif_delta_cycles); emif_load = 100.0 * ( (double) emif_delta_busy_cycles / emif_delta_cycles); dprintf("%s(): EMIF load = %lf%%\n", __func__, emif_load); } if (skip_cpufreq_audit == 0) { total_trans_cnt = count64_delta(total_trans_t0, total_trans_t1); dprintf("CPUFREQ:\n"); dprintf(" total transitions = %llu\n", total_trans_cnt); for (i = 0; i < opp_cnt; i++) { time_in_opp_cnt[i] = count64_delta(time_in_opp_t0[i], time_in_opp_t1[i]); #ifdef AUDIT_DEBUG /* FIXME: retrieve cpufreq sampling rate (variable) */ if (cpu_is_omap44xx()) printf(" time in OPP %s = %llums\n", opp44xx_name_get(i + 1, OMAP4_VDD_MPU), time_in_opp_cnt[i] * 10); else printf(" time in OPP %s = %llums\n", opp54xx_name_get(i + 1), time_in_opp_cnt[i] * 10); #endif } } if (skip_cstate_audit == 0) { for (i = 0; i < cstates_nbr; i++) { cstates_usage[i][2] = count64_delta( cstates_usage[i][0], cstates_usage[i][1]); cstates_time[i][2] = count64_delta( cstates_time[i][0], cstates_time[i][1]); } } /* Compute & Show C-State Statistics */ if (skip_cstate_audit == 1) { strncpy(timerstats_summary, "WARNING: could not retrieve C-State number. " "Skipping C-States audit.\n\n", 256); if (stream != NULL) fputs(timerstats_summary, stream); if (fp != NULL) fputs(timerstats_summary, fp); } else { autoadjust_table_init(table); row = 0; strncpy(table[row][0], "C-State", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Entered?", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Hit Number", TABLE_MAX_ELT_LEN); strncpy(table[row][3], "Time Spent (s)", TABLE_MAX_ELT_LEN); strncpy(table[row][4], "Time Spent (%)", TABLE_MAX_ELT_LEN); row++; strncpy(table[row][0], "Active + \"C0\"", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Yes", TABLE_MAX_ELT_LEN); active_c0_time = duration * 1000000; for (i = 0; i < cstates_nbr; i++) { if (active_c0_time > cstates_time[i][2]) active_c0_time -= cstates_time[i][2]; else /* * It may be possible that * active_c0_time is < cstates_time[i][2] * (duration may fluctuate a little depending on * system load). Make sure it doesn't cross 0 as * it's an unsigned interger. */ active_c0_time = 0; } sec = active_c0_time / 1000000; msec = (active_c0_time % 1000000) / 1000; usec = active_c0_time % 1000; snprintf(table[row][3], TABLE_MAX_ELT_LEN, "%llus %llums %lluus", sec, msec, usec); pct = ((double) active_c0_time / (double) (duration * 1000000)) * 100.0; snprintf(table[row][4], TABLE_MAX_ELT_LEN, "%3.1f%%", pct); row++; for (i = 0; i < cstates_nbr; i++) { snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s", cstate_get_name(i, name)); if (cstates_usage[i][2] != 0) { dprintf("%s(): C%u entered\n", __func__, i + 1); strncpy(table[row][1], "Yes", TABLE_MAX_ELT_LEN); snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%llu", cstates_usage[i][2]); sec = cstates_time[i][2] / 1000000; msec = (cstates_time[i][2] % 1000000) / 1000; usec = cstates_time[i][2] % 1000; snprintf(table[row][3], TABLE_MAX_ELT_LEN, "%llus %llums %lluus", sec, msec, usec); pct = ((double) cstates_time[i][2] / (double) (duration * 1000000)) * 100.0; snprintf(table[row][4], TABLE_MAX_ELT_LEN, "%3.1f%%", pct); } else { dprintf("%s(): C%u not entered\n", __func__, i + 1); strncpy(table[row][1], "No", TABLE_MAX_ELT_LEN); } row++; } /* Print results */ strncpy(timerstats_summary, "NB: this table shows statistics about " "the ATTEMPTED C-States, not the effectively " "entered C-States (not supported by kernel " "idle framework yet).\nAs a consequence, these " "C-States MAY or MAY NOT have been entered, " "depending on HW conditions.\n\n\n", 256); if (stream != NULL) { autoadjust_table_fprint(stream, table, row, 5); fputs(timerstats_summary, stream); } if (fp != NULL) { autoadjust_table_fprint(fp, table, row, 5); fputs(timerstats_summary, fp); } } /* Show CPUFreq stats */ if (skip_cpufreq_audit == 1) { strncpy(timerstats_summary, "WARNING: could not retrieve MPU " "OPP number. CPUFreq audit skipped.\n\n", 256); if (stream != NULL) fputs(timerstats_summary, stream); if (fp != NULL) fputs(timerstats_summary, fp); } else { autoadjust_table_init(table); row = 0; strncpy(table[row][0], "MPU OPP", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Time Spent in OPP", TABLE_MAX_ELT_LEN); row++; for (i = 0; i < opp_cnt; i++) { if (cpu_is_omap44xx()) snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s", opp44xx_name_get(i + 1, OMAP4_VDD_MPU)); else snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s", opp54xx_name_get(i + 1)); snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%llus%llums", time_in_opp_cnt[i] / 100, (time_in_opp_cnt[i] % 100) * 10); row++; } cpufreq_scaling_governor_get(name); if (name != NULL) sprintf(timerstats_summary, "CPUFreq Governor: %s\n", name); else sprintf(timerstats_summary, "CPUFreq Governor: not found!\n"); if (stream != NULL) fputs(timerstats_summary, stream); if (fp != NULL) fputs(timerstats_summary, fp); sprintf(timerstats_summary, "Total number of OPP transitions: %llu\n\n", total_trans_cnt); if (stream != NULL) { fputs(timerstats_summary, stream); autoadjust_table_fprint(stream, table, row, 2); fprintf(stream, "\n"); } if (fp != NULL) { fputs(timerstats_summary, fp); autoadjust_table_fprint(fp, table, row, 2); fprintf(fp, "\n"); } } /* Show CPU Load stats */ if (skip_proc_stats_audit == 1) { strncpy(timerstats_summary, "WARNING: could not retrieve CPU " "cores number. CPU Load audit skipped.\n\n", 256); if (stream != NULL) fputs(timerstats_summary, stream); if (fp != NULL) fputs(timerstats_summary, fp); } else { autoadjust_table_init(table); row = 0; strncpy(table[row][0], "CPU", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Average Load (*)", TABLE_MAX_ELT_LEN); row++; cpu_online_cores_cnt = 0; load_total = 0.0; for (i = 0; i < cpu_cores_cnt; i++) { snprintf(table[row][0], TABLE_MAX_ELT_LEN, "CPU%u", i); if ((i >= 1) && (cpu_online[i] == 0)) { snprintf(table[row][1], TABLE_MAX_ELT_LEN, "Offline"); row++; continue; } idle_cnt[i] = count32_delta(idle_t0[i], idle_t1[i]); iowait_cnt[i] = count32_delta(iowait_t0[i], iowait_t1[i]); sum_cnt[i] = count32_delta(sum_t0[i], sum_t1[i]); dprintf("%s(): idle_cnt[%u] = %u, iowait_cnt[%u] = %u, " "sum_cnt[%u] = %u\n", __func__, i, idle_cnt[i], i, iowait_cnt[i], i, sum_cnt[i]); if (sum_cnt[i] != 0) { load[i] = cpu_load_get(idle_cnt[i], iowait_cnt[i], sum_cnt[i]); cpu_online_cores_cnt++; } else { /* * Due to tickless feature, it is possible that * that no tick occured during this sampling * window and so /proc/stat counters were not * incremented. => cpu load = 0. */ load[i] = 0.0; } load_total += load[i]; dprintf("%s(): CPU%u load=%.2lf%%\n", __func__, i, load[i]); snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%.2lf%%", load[i]); row++; } dprintf("%s(): cpu_online_cores_cnt=%u\n", __func__, cpu_online_cores_cnt); load_total = load_total / cpu_online_cores_cnt; snprintf(table[row][0], TABLE_MAX_ELT_LEN, "Total"); snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%.2lf%%", load_total); row++; strncpy(timerstats_summary, "(*) CANNOT be converted to Mhz. " "OPP may have changed during the audit.\n\n\n", 256); if (stream != NULL) { autoadjust_table_fprint(stream, table, row, 2); fputs(timerstats_summary, stream); } if (fp != NULL) { autoadjust_table_fprint(fp, table, row, 2); fputs(timerstats_summary, fp); } } /* Show EMIF stats */ if (cpu_is_omap44xx()) { autoadjust_table_init(table); row = 0; strncpy(table[row][0], "EMIF", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Average Load (*)", TABLE_MAX_ELT_LEN); row++; strncpy(table[row][0], "Total EMIF Data Bus Load", TABLE_MAX_ELT_LEN); snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%.2lf%%", (double) emif_load); row++; strncpy(timerstats_summary, "(*) CANNOT be converted to memory " "bandwidth (MB/s).\n DDR data busy cycles may be " "commands (not data) and data size is unknown.\n\n\n", 256); if (stream != NULL) { autoadjust_table_fprint(stream, table, row, 2); fputs(timerstats_summary, stream); } if (fp != NULL) { autoadjust_table_fprint(fp, table, row, 2); fputs(timerstats_summary, fp); } } /* Show interrupts stats */ if (skip_irq_audit == 1) { strncpy(timerstats_summary, "WARNING: could not save a snapshot of " "/proc/interrupts file. " "IRQ audit skipped.\n\n", 256); if (stream != NULL) fputs(timerstats_summary, stream); if (fp != NULL) fputs(timerstats_summary, fp); } else { fp_irq_1 = fopen(irq_snap_file1, "r"); fp_irq_2 = fopen(irq_snap_file2, "r"); if ((fp_irq_1 == NULL) || (fp_irq_2 == NULL)) { fprintf(stderr, "%s(): could not open interrupts " "snapshot files!\n\n", __func__); ret = OMAPCONF_ERR_NOT_AVAILABLE; goto audit_performances_exit; } autoadjust_table_init(table); row = 0; strncpy(table[row][0], "IRQ #", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Device Name", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Occurrence", TABLE_MAX_ELT_LEN); strncpy(table[row][3], "Proportion", TABLE_MAX_ELT_LEN); strncpy(table[row][4], "Rate", TABLE_MAX_ELT_LEN); row++; irq_total_count = irq_total_count_get(fp_irq_2) - irq_total_count_get(fp_irq_1); dprintf("%s(): irq_total_count=%d\n", __func__, irq_total_count); occurred_irq_count = irq_occurred_list_get(fp_irq_1, fp_irq_2, &occurred_irq_list); dprintf("%s(): # of irq lines that occurred = %d\n", __func__, occurred_irq_count); irq_occurred_list_sort(&occurred_irq_list); for (i = 0; i < occurred_irq_count; i++) { genlist_get(&occurred_irq_list, i, &irq_inf); snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%d", irq_inf.nbr); strncpy(table[row][1], irq_inf.dev_name, TABLE_MAX_ELT_LEN); pct = (double) irq_inf.count / (double) irq_total_count; pct *= 100.0; snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%u", irq_inf.count); snprintf(table[row][3], TABLE_MAX_ELT_LEN, "%.1lf%%", pct); pct = (double) irq_inf.count / (double) duration; snprintf(table[row][4], TABLE_MAX_ELT_LEN, "%.1lf/sec", pct); row++; } genlist_free(&occurred_irq_list); fclose(fp_irq_1); remove(irq_snap_file1); fclose(fp_irq_2); remove(irq_snap_file2); sprintf(timerstats_summary, "CPU was interrupted %d times by the following %d " "sources:\n", irq_total_count, occurred_irq_count); if (stream != NULL) { fputs(timerstats_summary, stream); autoadjust_table_fprint(stream, table, row, 5); } if (fp != NULL) { fputs(timerstats_summary, fp); autoadjust_table_fprint(fp, table, row, 5); } } /* Show timer stats */ if (skip_timerstats_audit != 0) { strncpy(timerstats_summary, "Timer Statistics: unable to capture kernel timer " "statistics.\nMake sure that CONFIG_TIMER_STATS " "are enabled in the kernel configuration.\n\n", 256); if (stream != NULL) fputs(timerstats_summary, stream); if (fp != NULL) fputs(timerstats_summary, fp); } else { fp_timerstats = fopen(timerstats_file, "r"); if (fp_timerstats == NULL) { fprintf(stderr, "%s(): could not open timer stats " "snapshot file!\n\n", __func__); ret = OMAPCONF_ERR_NOT_AVAILABLE; goto audit_performances_exit; } autoadjust_table_init(table); row = 0; strncpy(table[row][0], "# Timer Events", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Deferrable", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Process ID", TABLE_MAX_ELT_LEN); strncpy(table[row][3], "Process Name", TABLE_MAX_ELT_LEN); strncpy(table[row][4], "Init Function", TABLE_MAX_ELT_LEN); strncpy(table[row][5], "Callback Function", TABLE_MAX_ELT_LEN); row++; timer_count = timerstats_list_get(fp_timerstats, &timerstats_list); dprintf("%s(): # of timers that occurred = %d\n", __func__, timer_count); timerstats_list_sort(&timerstats_list); for (i = 0; i < timer_count; i++) { genlist_get(&timerstats_list, i, &timer_inf); snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%d", timer_inf.count); strncpy(table[row][1], timer_inf.deferrable, TABLE_MAX_ELT_LEN); snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%d", timer_inf.pid); strncpy(table[row][3], timer_inf.name, TABLE_MAX_ELT_LEN); strncpy(table[row][4], timer_inf.init_fxn, TABLE_MAX_ELT_LEN); strncpy(table[row][5], timer_inf.callback, TABLE_MAX_ELT_LEN); row++; } timerstats_get_summary(fp_timerstats, &timerstats_summary[0]); genlist_free(&timerstats_list); fclose(fp_timerstats); remove(timerstats_file); if (stream != NULL) { fputs(timerstats_summary, stream); autoadjust_table_fprint(stream, table, row, 6); } if (fp != NULL) { fputs(timerstats_summary, fp); autoadjust_table_fprint(fp, table, row, 6); } } if ((fp != NULL) && (stream != NULL)) fprintf(stream, "Performance Audit data saved into " "\"%s\" file.\n\n", perf_summary_file); ret = 0; audit_performances_exit: if (cpu_online != NULL) free(cpu_online); if (idle_t0 != NULL) free(idle_t0); if (iowait_t0 != NULL) free(iowait_t0); if (sum_t0 != NULL) free(sum_t0); if (idle_t1 != NULL) free(idle_t1); if (iowait_t1 != NULL) free(iowait_t1); if (sum_t1 != NULL) free(sum_t1); if (idle_cnt != NULL) free(idle_cnt); if (iowait_cnt != NULL) free(iowait_cnt); if (sum_cnt != NULL) free(sum_cnt); if (load != NULL) free(load); if (time_in_opp_t0 != NULL) free(time_in_opp_t0); if (time_in_opp_t1 != NULL) free(time_in_opp_t1); if (time_in_opp_cnt != NULL) free(time_in_opp_cnt); if (fp != NULL) fclose(fp); return ret; }
/* ------------------------------------------------------------------------*//** * @FUNCTION opp54xx_init * @BRIEF initialize internal data * @DESCRIPTION initialize internal data (architecture dependent) *//*------------------------------------------------------------------------ */ void opp54xx_init(void) { opp_t opp; /* ES1.0 */ static const opp_t mpu_opp_low_es1 = {OPP_LOW, 950000, 400000}; static const opp_t mpu_opp_nom_es1 = {OPP_NOM, 1040000, 800000}; static const opp_t mpu_opp_high_es1 = {OPP_HIGH, 1220000, 1100000}; static const opp_t mm_opp_low_es1 = {OPP_LOW, 950000, 177333}; static const opp_t mm_opp_nom_es1 = {OPP_NOM, 1040000, 354667}; static const opp_t mm_opp_high_es1 = {OPP_HIGH, 1220000, 532000}; static const opp_t core_opp_low_es1 = {OPP_LOW, 950000, 133000}; static const opp_t core_opp_nom_es1 = {OPP_NOM, 1040000, 2660000}; /* ES2.0 */ static const opp_t mpu_opp_low = {OPP_LOW, 880000, 500000}; static const opp_t mpu_opp_nom = {OPP_NOM, 1060000, 1000000}; static const opp_t mpu_opp_high = {OPP_HIGH, 1250000, 1500000}; static const opp_t mpu_opp_sb = {OPP_SB, 1290000, 1700000}; static const opp_t mm_opp_low = {OPP_LOW, 880000, 195000}; static const opp_t mm_opp_nom = {OPP_NOM, 1030000, 389000}; static const opp_t mm_opp_high = {OPP_HIGH, 1120000, 532000}; static const opp_t core_opp_low = {OPP_LOW, 880000, 133000}; static const opp_t core_opp_nom = {OPP_NOM, 1040000, 2660000}; #ifdef OPP54XX_DEBUG int i, count; voltdm54xx_id vdd; #endif if (!opp54xx_init_done) { genlist_init(&vdd54xx_wkup_opp_list); opp.name = OPP_NOM; opp.voltage = 1.0; opp.rate = clk54xx_sysclk_rate_get(); genlist_addtail(&vdd54xx_wkup_opp_list, (void *) &opp, sizeof(opp_t)); genlist_init(&vdd54xx_mpu_opp_list); if (cpu_revision_get() == REV_ES1_0) { genlist_addtail(&vdd54xx_mpu_opp_list, (void *) &mpu_opp_low_es1, sizeof(opp_t)); genlist_addtail(&vdd54xx_mpu_opp_list, (void *) &mpu_opp_nom_es1, sizeof(opp_t)); genlist_addtail(&vdd54xx_mpu_opp_list, (void *) &mpu_opp_high_es1, sizeof(opp_t)); genlist_init(&vdd54xx_mm_opp_list); genlist_addtail(&vdd54xx_mm_opp_list, (void *) &mm_opp_low_es1, sizeof(opp_t)); genlist_addtail(&vdd54xx_mm_opp_list, (void *) &mm_opp_nom_es1, sizeof(opp_t)); genlist_addtail(&vdd54xx_mm_opp_list, (void *) &mm_opp_high_es1, sizeof(opp_t)); genlist_init(&vdd54xx_core_opp_list); genlist_addtail(&vdd54xx_core_opp_list, (void *) &core_opp_low_es1, sizeof(opp_t)); genlist_addtail(&vdd54xx_core_opp_list, (void *) &core_opp_nom_es1, sizeof(opp_t)); } else { genlist_addtail(&vdd54xx_mpu_opp_list, (void *) &mpu_opp_low, sizeof(opp_t)); genlist_addtail(&vdd54xx_mpu_opp_list, (void *) &mpu_opp_nom, sizeof(opp_t)); genlist_addtail(&vdd54xx_mpu_opp_list, (void *) &mpu_opp_high, sizeof(opp_t)); genlist_addtail(&vdd54xx_mpu_opp_list, (void *) &mpu_opp_sb, sizeof(opp_t)); genlist_init(&vdd54xx_mm_opp_list); genlist_addtail(&vdd54xx_mm_opp_list, (void *) &mm_opp_low, sizeof(opp_t)); genlist_addtail(&vdd54xx_mm_opp_list, (void *) &mm_opp_nom, sizeof(opp_t)); genlist_addtail(&vdd54xx_mm_opp_list, (void *) &mm_opp_high, sizeof(opp_t)); genlist_init(&vdd54xx_core_opp_list); genlist_addtail(&vdd54xx_core_opp_list, (void *) &core_opp_low, sizeof(opp_t)); genlist_addtail(&vdd54xx_core_opp_list, (void *) &core_opp_nom, sizeof(opp_t)); } opp54xx_init_done = 1; #ifdef OPP54XX_DEBUG printf("%s(): init done.\n", __func__); printf("OPP List:\n"); for (vdd = VDD54XX_WKUP; vdd <= VDD54XX_CORE; vdd++) { count = genlist_getcount( (genlist *) opp54xx_list_table_es1[vdd]); printf(" %s (%d): ", voltdm54xx_name_get(vdd), count); for (i = 0; i < count; i++) { genlist_get( (genlist *) opp54xx_list_table_es1[vdd], i, (void *) &opp); printf("%s (%.1lfMHz, %.3lfV)", opp.name, khz2mhz(opp.rate), uv2v(opp.voltage)); if (i != count - 1) printf(", "); } printf(".\n"); } #endif } }
/* ------------------------------------------------------------------------*//** * @FUNCTION opp54xx_by_rate_get * @BRIEF return the current voltage domain OPP name, * searched by clock rates. * @RETURNS current voltage domain OPP name (as defined in opp.h) * NULL pointer in case of error or not found * @param[in] vdd_id: voltage domain ID * @DESCRIPTION return the current voltage domain OPP name, * searched by clock rates. *//*------------------------------------------------------------------------ */ const char *opp54xx_by_rate_get(voltdm54xx_id vdd_id) { const char *opp_name = NULL; int opp_id; const char *module_name; double rate = 0.0, rate_por = 0.0; double rate_dsp = 0.0, rate_dsp_por = 0.0; double rate_gpu = 0.0, rate_gpu_por = 0.0; opp_t opp; const genlist *opp_list; int i, ret, opp_count; CHECK_CPU(54xx, NULL); CHECK_ARG_LESS_THAN(vdd_id, VDD54XX_ID_MAX, NULL); /* * Determine current OPPs by getting MPU / IVA / L3 / SARRAM rate * and comparing it to POR rate. */ switch (vdd_id) { case VDD54XX_WKUP: module_name = MOD_L4_WKUP_INTERCONNECT; break; case VDD54XX_MPU: module_name = MOD_MPU; break; case VDD54XX_MM: module_name = MOD_IVA; break; case VDD54XX_CORE: module_name = MOD_L3_MAIN1_INTERCONNECT; break; default: return NULL; } /* * If the DPLL clocking the selected module is stopped, * reported speed will be 0 and OPP cannot be detected. * Hence, ignore DPLL status. */ rate = (double) module_clk_rate_get(module_name, 1) / 1000.0; if (rate < 0.0) { dprintf("%s(): could not retrieve clock speed!\n", __func__); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): %s rate is %lfMHz\n", __func__, voltdm54xx_name_get(vdd_id), clk54xx_name_get(module_clk_get(module_name)), rate); if (vdd_id == VDD54XX_MM) { rate_dsp = (double) module_clk_rate_get(MOD_DSP, 1) / 1000.0; if (rate_dsp < 0.0) { dprintf("%s(): could not retrieve clock speed!\n", __func__); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): DSP rate is %lfMHz\n", __func__, voltdm54xx_name_get(vdd_id), rate_dsp); rate_gpu = (double) module_clk_rate_get(MOD_GPU, 1) / 1000.0; if (rate_gpu < 0.0) { dprintf("%s(): could not retrieve clock speed!\n", __func__); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): GPU rate is %lfMHz\n", __func__, voltdm54xx_name_get(vdd_id), rate_gpu); } opp_list = opp54xx_list_get(vdd_id); if (opp_list == NULL) { dprintf("%s(): could not retrieve OPP list!\n", __func__); goto opp54xx_by_rate_get_end; } opp_count = opp54xx_count_get(vdd_id); if (opp_count <= 0) { dprintf("%s(): could not retrieve OPP count!\n", __func__); goto opp54xx_by_rate_get_end; } for (i = 0; i < opp_count; i++) { ret = genlist_get((genlist *) opp_list, i, (opp_t *) &opp); if (ret != 0) { dprintf("%s(): could not retrieve OPP from list!\n", __func__); goto opp54xx_by_rate_get_end; } opp_id = opp54xx_id_get(opp.name); if (opp_id < 0) { dprintf( "%s(): could not retrieve OPP ID from OPP name!\n", __func__); goto opp54xx_by_rate_get_end; } rate_por = (double) module_por_clk_rate_get(module_name, opp.name) / 1000.0; if (rate_por < 0) { dprintf( "%s(): could not get %s %s POR speed! (%d)\n", __func__, module_name, opp.name, ret); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): %s POR rate for %s is %lf\n", __func__, voltdm54xx_name_get(vdd_id), module_name, opp.name, rate_por); if (vdd_id == VDD54XX_MM) { rate_dsp_por = (double) module_por_clk_rate_get(MOD_DSP, opp.name) / 1000.0; if (rate_dsp_por < 0) { dprintf( "%s(): could not get DSP %s POR speed! (%d)\n", __func__, opp.name, ret); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): DSP POR rate for %s is %lf\n", __func__, voltdm54xx_name_get(vdd_id), opp.name, rate_dsp_por); rate_gpu_por = (double) module_por_clk_rate_get(MOD_GPU, opp.name) / 1000.0; if (rate_gpu_por < 0) { dprintf( "%s(): could not get GPU %s POR speed! (%d)\n", __func__, opp.name, ret); goto opp54xx_by_rate_get_end; } dprintf("%s(%s): GPU POR rate for %s is %lf\n", __func__, voltdm54xx_name_get(vdd_id), opp.name, rate_gpu_por); if (((int) rate <= (int) rate_por) && ((int) rate_dsp <= (int) rate_dsp_por) && ((int) rate_gpu <= (int) rate_gpu_por)) { opp_name = opp.name; goto opp54xx_by_rate_get_end; } } else { if ((int) rate <= (int) rate_por) { opp_name = opp.name; goto opp54xx_by_rate_get_end; } } } dprintf("%s(%s): OPP not found!\n", __func__, voltdm54xx_name_get(vdd_id)); opp54xx_by_rate_get_end: #ifdef OPP54XX_DEBUG if (opp_name == NULL) printf("%s(%s): OPP not found!\n", __func__, voltdm54xx_name_get(vdd_id)); else printf("%s(%s): OPP found: %s\n", __func__, voltdm54xx_name_get(vdd_id), opp_name); #endif return opp_name; }
/* ------------------------------------------------------------------------*//** * @FUNCTION opp_show * @BRIEF show current operating voltages and key clock rates. * @RETURNS 0 in case of success * OMAPCONF_ERR_REG_ACCESS * OMAPCONF_ERR_CPU * OMAPCONF_ERR_INTERNAL * @param[in,out] stream: output file stream (opened, != NULL) * @DESCRIPTION show current operating voltages and key clock rates. *//*------------------------------------------------------------------------ */ int opp_show(FILE *stream) { int volt, volt2; const char *opp_s, *opp_s2; int temp; int rate_mpu, rate_mpu_por; int rate_dsp, rate_iva, rate_gpu; int rate_dsp_por, rate_iva_por, rate_gpu_por, rate_aess_por; int rate_l3, rate_l3_por; int rate_l4, rate_emif, rate_lpddr2, rate_aess, rate_iss, rate_fdif, rate_dss, rate_bb2d, rate_hsi; mod_module_mode mmode; int rate_cal, rate_ipu, rate_c2c; char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row = 0; unsigned int retry_cnt = 0; unsigned int found = 0; const genlist *voltdm_list; int i, vdd_count; const char voltdm[VOLTDM_MAX_NAME_LENGTH]; char prev_gov[CPUFREQ_GOV_MAX_NAME_LENGTH], prev_gov2[CPUFREQ_GOV_MAX_NAME_LENGTH]; const char *temp_sensor; /* Switch to userspace governor temporarily, * so that OPP cannot change during audit and does not false it. */ cpufreq_scaling_governor_set("userspace", prev_gov); autoadjust_table_init(table); row = 0; strncpy(table[row][1], "Temperature", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Voltage", TABLE_MAX_ELT_LEN); strncpy(table[row][3], "Frequency", TABLE_MAX_ELT_LEN); strncpy(table[row][4], "OPerating Point", TABLE_MAX_ELT_LEN); row++; /* * In order to make sure all details (OPP, voltage, clock rates) are * coherent (due to potential OPP change in between), must use a loop, * checking that OPP and voltage did not change and that at least ONE * clock rate is aligned to expected rate for the detected OPP. */ dprintf("%s():\n", __func__); voltdm_list = voltdm_list_get(); if (voltdm_list == NULL) return OMAPCONF_ERR_INTERNAL; vdd_count = voltdm_count_get(); if (vdd_count < 0) return OMAPCONF_ERR_INTERNAL; dprintf("found %d voltage domains\n", vdd_count); for (i = 1; i < vdd_count; i++) { genlist_get((genlist *) voltdm_list, i, (char *) &voltdm); snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s / VDD_CORE%u", voltdm, i); dprintf(" %s:\n", voltdm); /* Retrieve OPP and clock rates */ retry_cnt = 0; found = 0; do { dprintf(" TRY #%u:\n", retry_cnt); if (retry_cnt == 0) /* Print warning on first try */ opp_s = opp_get(voltdm, 0); else opp_s = opp_get(voltdm, 1); if (opp_s == NULL) { dprintf(" OPP NOT detected!\n"); opp_s = OPP_UNKNOWN; } else { dprintf(" OPP detected: %s\n", opp_s); } volt = voltdm_voltage_get(voltdm); dprintf(" Voltage: %duV\n", volt); if (strcmp(voltdm, "VDD_MPU") == 0) { rate_mpu = mod_clk_rate_get("MPU"); if (strcmp(opp_s, OPP_UNKNOWN) != 0) rate_mpu_por = mod_por_clk_rate_get( "MPU", opp_s); else rate_mpu_por = -1; dprintf( " MPU Rate: %dKHz, POR Rate: %dKHz\n", rate_mpu, rate_mpu_por); } else if ((strcmp(voltdm, "VDD_IVA") == 0) || (strcmp(voltdm, "VDD_MM") == 0)) { rate_dsp_por = -1; rate_iva_por = -1; rate_aess_por = -1; rate_gpu_por = -1; rate_dsp = mod_clk_rate_get("DSP"); rate_iva = mod_clk_rate_get("IVA"); if (cpu_is_omap44xx()) rate_aess = mod_clk_rate_get("AESS"); else if (cpu_is_omap54xx()) rate_gpu = mod_clk_rate_get("GPU"); if (strcmp(opp_s, OPP_UNKNOWN) != 0) { rate_dsp_por = mod_por_clk_rate_get( "DSP", opp_s); rate_iva_por = mod_por_clk_rate_get( "IVA", opp_s); if (cpu_is_omap44xx()) rate_aess_por = mod_por_clk_rate_get( "AESS", opp_s); else if (cpu_is_omap54xx()) rate_gpu_por = mod_por_clk_rate_get( "GPU", opp_s); } dprintf( " DSP Rate: %dMHz, POR Rate: %dMHz\n", rate_dsp, rate_dsp_por); dprintf( " IVA Rate: %dMHz, POR Rate: %dMHz\n", rate_iva, rate_iva_por); if (cpu_is_omap44xx()) { dprintf( " AESS Rate: %dMHz, POR Rate: %dMHz\n", rate_aess, rate_aess_por); } else if (cpu_is_omap54xx()) { dprintf( " GPU Rate: %dMHz, POR Rate: %dMHz\n", rate_gpu, rate_gpu_por); } } else if (strcmp(voltdm, "VDD_CORE") == 0) { rate_l3 = mod_clk_rate_get("L3"); if (strcmp(opp_s, OPP_UNKNOWN) != 0) rate_l3_por = mod_por_clk_rate_get( "L3", opp_s); else rate_l3_por = -1; dprintf( " L3_1 Rate: %dMHz, POR Rate: %dMHz\n", rate_l3, rate_l3_por); rate_emif = mod_clk_rate_get("EMIF"); rate_lpddr2 = mod_clk_rate_get("MEM"); rate_l4 = mod_clk_rate_get("L4"); if (cpu_is_omap44xx()) rate_gpu = mod_clk_rate_get("GPU"); else if (cpu_is_omap54xx()) rate_aess = mod_clk_rate_get("AESS"); rate_iss = mod_clk_rate_get("ISS"); rate_fdif = mod_clk_rate_get("FDIF"); if (!cpu_is_omap44xx()) rate_cal = mod_clk_rate_get("CAL"); else rate_cal = -1; rate_ipu = mod_clk_rate_get("IPU"); rate_dss = mod_clk_rate_get("DSS"); rate_hsi = mod_clk_rate_get("HSI"); if (cpu_is_omap4470() || cpu_is_omap54xx()) rate_bb2d = mod_clk_rate_get("BB2D"); else rate_bb2d = -1; rate_c2c = mod_clk_rate_get("C2C"); } if (strcmp(opp_s, OPP_UNKNOWN) == 0) { dprintf( " Could not detect OPP, aborting for this domain.\n"); break; } opp_s2 = opp_get(voltdm, 1); if (opp_s2 == NULL) { dprintf(" OPP NOT detected! (2)\n"); opp_s2 = OPP_UNKNOWN; } else { dprintf(" OPP detected: %s (2)\n", opp_s2); } volt2 = voltdm_voltage_get(voltdm); dprintf(" Voltage (2): %dV\n", volt2); if (strcmp(voltdm, "VDD_MPU") == 0) { found = ((rate_mpu == rate_mpu_por) && (strcmp(opp_s, opp_s2) == 0) && (volt == volt2)); } else if (strcmp(voltdm, "VDD_IVA") == 0) { found = ((strcmp(opp_s, opp_s2) == 0) && (volt == volt2) && (((unsigned int) rate_dsp == (unsigned int) rate_dsp_por) || ((unsigned int) rate_iva == (unsigned int) rate_iva_por) || ((unsigned int) rate_aess == (unsigned int) rate_aess_por))); } else if (strcmp(voltdm, "VDD_MM") == 0) { found = ((strcmp(opp_s, opp_s2) == 0) && (volt == volt2) && ((rate_dsp == rate_dsp_por) || (rate_iva == rate_iva_por) || (rate_gpu == rate_gpu_por))); } else if (strcmp(voltdm, "VDD_CORE") == 0) { found = ((strcmp(opp_s, opp_s2) == 0) && (volt == volt2) && (rate_l3 == rate_l3_por)); } dprintf(" found=%u\n", found); retry_cnt++; } while ((retry_cnt < OPP_MAX_RETRY) && (found == 0)); /* Print temperature */ temp_sensor = temp_sensor_voltdm2sensor(voltdm); if (temp_sensor == NULL) { snprintf(table[row][1], TABLE_MAX_ELT_LEN, "NA"); } else { temp = temp_sensor_get(temp_sensor); if (temp != TEMP_ABSOLUTE_ZERO) snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%dC / %dF", temp, celcius2fahrenheit(temp)); else snprintf(table[row][1], TABLE_MAX_ELT_LEN, "NA"); } /* Print voltage */ if (volt < 0) snprintf(table[row][2], TABLE_MAX_ELT_LEN, "NA"); else if (!cpu_is_omap44xx()) snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%.3lf V", uv2v(volt)); else snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%.6lf V", uv2v(volt)); /* Print OPP */ if (retry_cnt < OPP_MAX_RETRY) { strncpy(table[row][4], opp_s, TABLE_MAX_ELT_LEN); } else { fprintf(stderr, "omapconf: too many %s OPP changes, could not retrieve it!!!\n", voltdm); strncpy(table[row][4], "ERROR", TABLE_MAX_ELT_LEN); } row++; /* Print clock rates */ if (strcmp(voltdm, "VDD_MPU") == 0) { if (cpu_is_online(1) == 1) strncpy(table[row][0], " MPU (CPU1 ON)", TABLE_MAX_ELT_LEN); else strncpy(table[row][0], " MPU (CPU1 OFF)", TABLE_MAX_ELT_LEN); snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_mpu / 1000); row += 2; } else if ((strcmp(voltdm, "VDD_IVA") == 0) || (strcmp(voltdm, "VDD_MM") == 0)) { strncpy(table[row][0], " IVA", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("IVA"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_iva / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_iva / 1000); row++; if (cpu_is_omap44xx()) { strncpy(table[row][0], " AESS", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("AESS"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_aess / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_aess / 1000); row++; } else if (cpu_is_omap54xx()) { strncpy(table[row][0], " GPU", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("GPU"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_gpu / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_gpu / 1000); row++; } strncpy(table[row][0], " DSP", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("DSP"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_dsp / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_dsp / 1000); row += 2; } else if (strcmp(voltdm, "VDD_CORE") == 0) { strncpy(table[row][0], " L3", TABLE_MAX_ELT_LEN); snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_l3 / 1000); row++; strncpy(table[row][0], " DMM/EMIF", TABLE_MAX_ELT_LEN); snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_emif / 1000); row++; strncpy(table[row][0], " LP-DDR2", TABLE_MAX_ELT_LEN); snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_lpddr2 / 1000); row++; strncpy(table[row][0], " L4", TABLE_MAX_ELT_LEN); snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_l4 / 1000); row++; if (cpu_is_omap44xx()) { strncpy(table[row][0], " GPU", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("GPU"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_gpu / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_gpu / 1000); row++; } else if (cpu_is_omap54xx()) { strncpy(table[row][0], " AESS", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("AESS"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_aess / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_aess / 1000); row++; } strncpy(table[row][0], " FDIF", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("FDIF"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_fdif / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_fdif / 1000); row++; if (cpu_is_omap54xx()) { strncpy(table[row][0], " CAL", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("CAL"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_cal / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_cal / 1000); row++; } strncpy(table[row][0], " IPU", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("IPU"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_ipu / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_ipu / 1000); row++; if (cpu_is_omap44xx()) { strncpy(table[row][0], " Cortex-M3 Cores", TABLE_MAX_ELT_LEN); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_ipu / 2000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_ipu / 2000); row++; } else if (cpu_is_omap54xx()) { strncpy(table[row][0], " Cortex-M4 Cores", TABLE_MAX_ELT_LEN); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_ipu / 2000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_ipu / 2000); row++; } strncpy(table[row][0], " ISS", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("ISS"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_iss / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_iss / 1000); row++; strncpy(table[row][0], " DSS", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("DSS"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_dss / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_dss / 1000); row++; if (cpu_is_omap4470() || cpu_is_omap54xx()) { strncpy(table[row][0], " BB2D", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("BB2D"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_bb2d / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_bb2d / 1000); row++; } strncpy(table[row][0], " HSI", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("HSI"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_hsi / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_hsi / 1000); row++; strncpy(table[row][0], " C2C", TABLE_MAX_ELT_LEN); mmode = mod_mode_get("C2C"); if (mmode == MOD_DISABLED_MODE) snprintf(table[row][3], TABLE_MAX_ELT_LEN, "(%-4d MHz) (1)", rate_c2c / 1000); else snprintf(table[row][3], TABLE_MAX_ELT_LEN, " %-4d MHz", rate_c2c / 1000); row++; } } /* Display table */ autoadjust_table_fprint(stream, table, row, 5); fprintf(stream, "Notes:\n"); fprintf(stream, " (1) Module is disabled, rate may not be relevant.\n\n"); /* Restore CPUFreq governor */ cpufreq_scaling_governor_set(prev_gov, prev_gov2); return 0; }
const char *opp_by_voltage_get(const char *voltdm, unsigned short quiet) { int volt; opp_t opp; const genlist *opp_list; int i, opp_count; const char *opp_name = NULL; const char *opp_name2 = NULL; CHECK_NULL_ARG(voltdm, NULL); opp_init(); volt = voltdm_nominal_voltage_get(voltdm); if (volt < 0) { dprintf("%s(%s): could not get voltage!\n", __func__, voltdm); return NULL; } dprintf("%s(%s): nominal voltage is %duV\n", __func__, voltdm, volt); opp_list = opp_list_get(voltdm); if (opp_list == NULL) { dprintf("%s(%s): could not get OPP list!\n", __func__, voltdm); return NULL; } opp_count = opp_count_get(voltdm); if (opp_count <= 0) { dprintf("%s(%s): could not get OPP count!\n", __func__, voltdm); return NULL; } dprintf("%s(%s): found %d possible OPP\n", __func__, voltdm, opp_count); for (i = 0; i < opp_count; i++) { genlist_get((genlist *) opp_list, i, (opp_t *) &opp); dprintf("%s(%s): POR nominal voltage for %s is %duV\n", __func__, voltdm, opp.name, opp.voltage); if (volt == opp.voltage) { /* * OPP DPLL_CASC and OPP[50-NOM] shares the same * voltage. * This is also the case for OPP_NITRO and OPP_NITRO_SB. * Must double-check with frequencies. */ if ((strcmp(opp.name, OPP_DPLL_CASC) != 0) && (strcmp(opp.name, OPP_NITRO) != 0)) { opp_name = opp.name; dprintf("%s(%s): OPP found: %s\n", __func__, voltdm, opp_name); break; } dprintf( "%s(%s): %s found, double-checking using rates (same voltage apply to more than 1 OPP.\n", __func__, voltdm, opp.name); opp_name2 = opp_by_rate_get(voltdm, 1); if (strcmp(opp_name2, opp.name) == 0) { opp_name = opp.name; dprintf("%s(%s): OPP found: %s\n", __func__, voltdm, opp_name); break; } dprintf( "%s(%s): this was not %s, but probably the next one.\n", __func__, voltdm, opp.name); } } if ((quiet == 0) && (opp_name == NULL)) fprintf(stdout, "omapconf: warning: no matching %s OPP for %lfV nominal voltage. Please check voltage against Data Manual recommendations.\n", voltdm, uv2v(volt)); return opp_name; }
/************************************************************************** Called when a key is pressed. **************************************************************************/ static gboolean inputline_handler(GtkWidget *w, GdkEventKey *ev) { if ((ev->state & GDK_CONTROL_MASK)) { /* Chatline featured text support. */ switch (ev->keyval) { case GDK_b: inputline_make_tag(GTK_ENTRY(w), TTT_BOLD); return TRUE; case GDK_c: inputline_make_tag(GTK_ENTRY(w), TTT_COLOR); return TRUE; case GDK_i: inputline_make_tag(GTK_ENTRY(w), TTT_ITALIC); return TRUE; case GDK_s: inputline_make_tag(GTK_ENTRY(w), TTT_STRIKE); return TRUE; case GDK_u: inputline_make_tag(GTK_ENTRY(w), TTT_UNDERLINE); return TRUE; default: break; } } else { /* Chatline history controls. */ switch (ev->keyval) { case GDK_Up: if (history_pos < genlist_size(history_list) - 1) { gtk_entry_set_text(GTK_ENTRY(w), genlist_get(history_list, ++history_pos)); gtk_editable_set_position(GTK_EDITABLE(w), -1); } return TRUE; case GDK_Down: if (history_pos >= 0) { history_pos--; } if (history_pos >= 0) { gtk_entry_set_text(GTK_ENTRY(w), genlist_get(history_list, history_pos)); } else { gtk_entry_set_text(GTK_ENTRY(w), ""); } gtk_editable_set_position(GTK_EDITABLE(w), -1); return TRUE; case GDK_Tab: if (gui_gtk2_chatline_autocompletion) { return chatline_autocomplete(GTK_EDITABLE(w)); } default: break; } } return FALSE; }
/* ------------------------------------------------------------------------*//** * @FUNCTION opp_dra7xx_init * @BRIEF initialize internal data * @DESCRIPTION initialize internal data (architecture dependent) *//*------------------------------------------------------------------------ */ void opp_dra7xx_init(void) { static const opp_t core_opp_nom = {OPP_NOM, 1030000, 266000}; static const opp_t mpu_opp_nom = {OPP_NOM, 1060000, 1000000}; static const opp_t mpu_opp_od = {OPP_OD, 1160000, 1176000}; static const opp_t mpu_opp_high = {OPP_HIGH, 1250000, 1500000}; /* * opp_dra7xx_list is just a reference of how many opp that a * voltage manager has, so only need to add either dsp or eve, * to indicating there are opp_nom, and opp_od for VDD_DSPEVE. */ static const opp_t dsp_opp_nom = {OPP_NOM, 1060000, 600000}; static const opp_t dsp_opp_od = {OPP_OD, 1150000, 700000}; static const opp_t iva_opp_nom = {OPP_NOM, 1060000, 388300}; static const opp_t iva_opp_od = {OPP_OD, 1160000, 430000}; static const opp_t iva_opp_high = {OPP_HIGH, 1250000, 532000}; static const opp_t gpu_opp_nom = {OPP_NOM, 1060000, 425600}; static const opp_t gpu_opp_od = {OPP_OD, 1160000, 500000}; static const opp_t gpu_opp_high = {OPP_HIGH, 1250000, 532000}; static const opp_t rtc_opp_nom = {OPP_NOM, 1030000, 34000}; #ifdef OPP_DRA7XX_DEBUG int i, count; voltdm_dra7xx_id vdd; #endif if (!opp_dra7xx_init_done) { genlist_init(&vdd_dra7xx_core_opp_list); genlist_addtail(&vdd_dra7xx_core_opp_list, (void *) &core_opp_nom, sizeof(opp_t)); genlist_init(&vdd_dra7xx_mpu_opp_list); genlist_addtail(&vdd_dra7xx_mpu_opp_list, (void *) &mpu_opp_nom, sizeof(opp_t)); genlist_addtail(&vdd_dra7xx_mpu_opp_list, (void *) &mpu_opp_od, sizeof(opp_t)); genlist_addtail(&vdd_dra7xx_mpu_opp_list, (void *) &mpu_opp_high, sizeof(opp_t)); genlist_init(&vdd_dra7xx_dspeve_opp_list); genlist_addtail(&vdd_dra7xx_dspeve_opp_list, (void *) &dsp_opp_nom, sizeof(opp_t)); genlist_addtail(&vdd_dra7xx_dspeve_opp_list, (void *) &dsp_opp_od, sizeof(opp_t)); genlist_init(&vdd_dra7xx_iva_opp_list); genlist_addtail(&vdd_dra7xx_iva_opp_list, (void *) &iva_opp_nom, sizeof(opp_t)); genlist_addtail(&vdd_dra7xx_iva_opp_list, (void *) &iva_opp_od, sizeof(opp_t)); genlist_addtail(&vdd_dra7xx_iva_opp_list, (void *) &iva_opp_high, sizeof(opp_t)); genlist_init(&vdd_dra7xx_gpu_opp_list); genlist_addtail(&vdd_dra7xx_gpu_opp_list, (void *) &gpu_opp_nom, sizeof(opp_t)); genlist_addtail(&vdd_dra7xx_gpu_opp_list, (void *) &gpu_opp_od, sizeof(opp_t)); genlist_addtail(&vdd_dra7xx_gpu_opp_list, (void *) &gpu_opp_high, sizeof(opp_t)); genlist_init(&vdd_dra7xx_rtc_opp_list); genlist_addtail(&vdd_dra7xx_rtc_opp_list, (void *) &rtc_opp_nom, sizeof(opp_t)); opp_dra7xx_init_done = 1; #ifdef OPP_DRA7XX_DEBUG printf("%s(): init done.\n", __func__); printf("OPP List:\n"); for (vdd = VDD_DRA7XX_WKUP; vdd < VDD_DRA7XX_ID_MAX; vdd++) { count = genlist_getcount( (genlist *) opp_dra7xx_list_table[vdd]); printf(" %s (%d): ", voltdm_dra7xx_name_get(vdd), count); for (i = 0; i < count; i++) { genlist_get( (genlist *) opp_dra7xx_list_table[vdd], i, (void *) &opp); printf("%s (%.1lfMHz, %.3lfV)", opp.name, khz2mhz(opp.rate), uv2v(opp.voltage)); if (i != count - 1) printf(", "); } printf(".\n"); } #endif } }
/* ------------------------------------------------------------------------*//** * @FUNCTION opp_dra7xx_by_rate_get * @BRIEF return the current voltage domain OPP name, * searched by clock rates. * @RETURNS current voltage domain OPP name (as defined in opp.h) * NULL pointer in case of error or not found * @param[in] vdd_id: voltage domain ID * @DESCRIPTION return the current voltage domain OPP name, * searched by clock rates. *//*------------------------------------------------------------------------ */ const char *opp_dra7xx_by_rate_get(voltdm_dra7xx_id vdd_id) { const char *opp_name = NULL; int opp_id; const char *module_name; double rate = 0.0, rate_por = 0.0; double rate_eve = 0.0, rate_eve_por = 0.0; opp_t opp; const genlist *opp_list; int i, ret, opp_count; CHECK_ARG_LESS_THAN(vdd_id, VDD_DRA7XX_ID_MAX, NULL); /* * Determine current OPPs by getting MPU / IVA / L3 / DSPEVE / GPU rate * and comparing it to POR rate. */ switch (vdd_id) { case VDD_DRA7XX_CORE: module_name = MOD_L3_MAIN1_INTERCONNECT; break; case VDD_DRA7XX_MPU: module_name = MOD_MPU; break; case VDD_DRA7XX_IVA: module_name = MOD_IVAHD; break; case VDD_DRA7XX_DSPEVE: module_name = MOD_DSP1; /* special case, need to check both DSP and EVE */ break; case VDD_DRA7XX_GPU: module_name = MOD_GPU; break; case VDD_DRA7XX_RTC: return OPP_NOM; /* module_name = TBD; */ break; default: return NULL; } /* * If the DPLL clocking the selected module is stopped, * reported speed will be 0 and OPP cannot be detected. * Hence, ignore DPLL status. */ rate = (double) module_clk_rate_get(module_name, 1) / 1000.0; if (rate < 0.0) { dprintf("%s(): could not retrieve clock speed!\n", __func__); goto opp_dra7xx_by_rate_get_end; } dprintf("%s(%s): %s rate is %lfMHz\n", __func__, voltdm_dra7xx_name_get(vdd_id), clk_dra7xx_name_get(module_clk_get(module_name)), rate); if (vdd_id == VDD_DRA7XX_DSPEVE) { rate_eve = (double) module_clk_rate_get(MOD_EVE1, 1) / 1000.0; if (rate_eve < 0.0) { dprintf("%s(): could not retrieve clock speed!\n", __func__); goto opp_dra7xx_by_rate_get_end; } dprintf("%s(%s): EVE rate is %lfMHz\n", __func__, voltdm_dra7xx_name_get(vdd_id), rate_eve); } opp_list = opp_dra7xx_list_get(vdd_id); if (opp_list == NULL) { dprintf("%s(): could not retrieve OPP list!\n", __func__); goto opp_dra7xx_by_rate_get_end; } opp_count = opp_dra7xx_count_get(vdd_id); if (opp_count <= 0) { dprintf("%s(): could not retrieve OPP count!\n", __func__); goto opp_dra7xx_by_rate_get_end; } for (i = 0; i < opp_count; i++) { ret = genlist_get((genlist *) opp_list, i, (opp_t *) &opp); if (ret != 0) { dprintf("%s(): could not retrieve OPP from list!\n", __func__); goto opp_dra7xx_by_rate_get_end; } opp_id = opp_dra7xx_id_get(opp.name); if (opp_id < 0) { dprintf( "%s(): could not retrieve OPP ID from OPP name!\n", __func__); goto opp_dra7xx_by_rate_get_end; } rate_por = (double) module_por_clk_rate_get(module_name, opp.name) / 1000.0; if (rate_por < 0) { dprintf( "%s(): could not get %s %s POR speed! (%d)\n", __func__, module_name, opp.name, ret); goto opp_dra7xx_by_rate_get_end; } dprintf("%s(%s): %s POR rate for %s is %lf\n", __func__, voltdm_dra7xx_name_get(vdd_id), module_name, opp.name, rate_por); if (vdd_id == VDD_DRA7XX_DSPEVE) { rate_eve_por = (double) module_por_clk_rate_get(MOD_EVE1, opp.name) / 1000.0; if (rate_eve_por < 0) { dprintf( "%s(): could not get GPU %s POR speed! (%d)\n", __func__, opp.name, ret); goto opp_dra7xx_by_rate_get_end; } dprintf("%s(%s): EVE POR rate for %s is %lf\n", __func__, voltdm_dra7xx_name_get(vdd_id), opp.name, rate_eve_por); if (((int) rate == (int) rate_por) && ((int) rate_eve == (int) rate_eve_por)) { opp_name = opp.name; goto opp_dra7xx_by_rate_get_end; } } else { if ((int) rate == (int) rate_por) { opp_name = opp.name; goto opp_dra7xx_by_rate_get_end; } } } dprintf("%s(%s): OPP not found!\n", __func__, voltdm_dra7xx_name_get(vdd_id)); opp_dra7xx_by_rate_get_end: #ifdef OPP_DRA7XX_DEBUG if (opp_name == NULL) printf("%s(%s): OPP not found!\n", __func__, voltdm_dra7xx_name_get(vdd_id)); else printf("%s(%s): OPP found: %s\n", __func__, voltdm_dra7xx_name_get(vdd_id), opp_name); #endif return opp_name; }