void parse_print_rails(void) { char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; int row; struct pm_bus *bus; struct ina226_rail *rail; bus = root_pm_bus; while (bus) { autoadjust_table_init(table); row = 0; snprintf(table[row][0], TABLE_MAX_ELT_LEN, "BUS_NAME = %s I2C_BUS=%s", bus->name, bus->i2c_bus); row++; strncpy(table[row][0], "Rail Name", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Group Name", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Input Name", TABLE_MAX_ELT_LEN); strncpy(table[row][3], "Output Name", TABLE_MAX_ELT_LEN); strncpy(table[row][4], "I2C Address(hex)", TABLE_MAX_ELT_LEN); strncpy(table[row][5], "Shunt Resistor Value(Ohm)", TABLE_MAX_ELT_LEN); strncpy(table[row][6], "Shunt Resistor Accuracy(%)", TABLE_MAX_ELT_LEN); row++; rail = bus->rail; while (rail) { snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s", rail->name); snprintf(table[row][1], TABLE_MAX_ELT_LEN, "%s", rail->board_group_name); snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%s", rail->in_board_name); snprintf(table[row][3], TABLE_MAX_ELT_LEN, "%s", rail->out_board_name); snprintf(table[row][4], TABLE_MAX_ELT_LEN, "0x%02x", rail->i2c_slave_addr); snprintf(table[row][5], TABLE_MAX_ELT_LEN, "%4.3f", rail->shunt_resistor_value); snprintf(table[row][6], TABLE_MAX_ELT_LEN, "%3.1f", rail->shunt_resistor_accuracy); row++; rail = rail->next; } bus = bus->next; autoadjust_table_generic_fprint(stdout, table, row, 7, TABLE_HAS_SUBTITLE | TABLE_HAS_TITLE); } }
/* ------------------------------------------------------------------------*//** * @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 vc44xx_config_show * @BRIEF decode and show VC current configuration * @RETURNS 0 in case of success * OMAPCONF_ERR_CPU * OMAPCONF_ERR_REG_ACCESS * @param[in,out] stream: output file (NULL: no output (silent)) * @param[in,out] vc_regs: Voltage Controller registers content * @DESCRIPTION decode and show VC current configuration *//*------------------------------------------------------------------------ */ int vc44xx_config_show(FILE *stream, vc44xx_registers *vc_regs) { voltdm44xx_id id; unsigned char raw_cmd_on, raw_cmd_onlp, raw_cmd_ret, raw_cmd_off; unsigned char cmd_on, cmd_onlp, cmd_ret, cmd_off; char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row = 0; CHECK_CPU(44xx, OMAPCONF_ERR_CPU); row = 0; autoadjust_table_init(table); autoadjust_table_strncpy(table, row, 0, "PRM VC Configuration"); autoadjust_table_strncpy(table, row, 1, "VC_MPU"); autoadjust_table_strncpy(table, row, 2, "VC_IVA"); autoadjust_table_strncpy(table, row, 3, "VC_CORE"); row++; for (id = OMAP4_VDD_MPU; id <= OMAP4_VDD_CORE; id++) { row = 1; autoadjust_table_strncpy(table, row, 0, "Power IC Slave Address (SA)"); snprintf(table[row][id], TABLE_MAX_ELT_LEN, "0x%02X", vc44xx_sa_get(id, vc_regs->prm_vc_smps_sa, vc_regs->prm_vc_cfg_channel)); row++; autoadjust_table_strncpy(table, row, 0, "Voltage Reg. Addr (VOLRA)"); snprintf(table[row][id], TABLE_MAX_ELT_LEN, "0x%02X", vc44xx_volra_get(id, vc_regs->prm_vc_cfg_channel, vc_regs->prm_vc_smps_ra_vol)); row++; autoadjust_table_strncpy(table, row, 0, "Command Reg. Addr (CMDRA)"); snprintf(table[row][id], TABLE_MAX_ELT_LEN, "0x%02X", vc44xx_cmdra_get(id, vc_regs->prm_vc_cfg_channel, vc_regs->prm_vc_val_smps_ra_cmd)); row++; autoadjust_table_strncpy(table, row++, 0, "Command Values:"); vc44xx_raw_cmd_values_get(id, vc_regs, &raw_cmd_on, &raw_cmd_onlp, &raw_cmd_ret, &raw_cmd_off); vc44xx_cmd_values_get(id, vc_regs, &cmd_on, &cmd_onlp, &cmd_ret, &cmd_off); strncpy(table[row][0], " ON", TABLE_MAX_ELT_LEN); snprintf(table[row][id], TABLE_MAX_ELT_LEN, "0x%02X (%.6lfV)", raw_cmd_on, smps_vsel2volt(vdd_id2smps_id(id), cmd_on)); row++; autoadjust_table_strncpy(table, row, 0, " ON-Low-Power (ONLP)"); snprintf(table[row][id], TABLE_MAX_ELT_LEN, "0x%02X (%.6lfV)", raw_cmd_onlp, smps_vsel2volt(vdd_id2smps_id(id), cmd_onlp)); row++; autoadjust_table_strncpy(table, row, 0, " RET"); snprintf(table[row][id], TABLE_MAX_ELT_LEN, "0x%02X (%.6lfV)", raw_cmd_ret, smps_vsel2volt(vdd_id2smps_id(id), cmd_ret)); row++; autoadjust_table_strncpy(table, row, 0, " OFF"); snprintf(table[row][id], TABLE_MAX_ELT_LEN, "0x%02X (%.6lfV)", raw_cmd_off, smps_vsel2volt(vdd_id2smps_id(id), cmd_off)); row++; } if (stream != NULL) autoadjust_table_fprint(stream, table, row, 4); return 0; }
/** * Function: counters44xx_perf * Role: trace OMAP performance (CPU Load, OPP & memory bandwidth usage). * Parameters: * capture_time: capture (trace) duration * Return: * 0 in case of success * OMAPCONF_ERR_ARG * OMAPCONF_ERR_NOT_AVAILABLE * OMAPCONF_ERR_UNEXPECTED */ int counters44xx_count(unsigned int capture_time) { unsigned int i; unsigned int sample_cnt; int ret; unsigned int addr, data, l2_disabled_prior = 0; unsigned int *trace_buf[TRACE_CFG_ENABLED_OPTIONS_MAX]; unsigned short emif; unsigned int sample; FILE *fp = NULL; char s[16]; char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row = 0; char name[64]; char tmp_name[64]; char option[64]; unsigned int temp, avg, min, max; /* Configure EMIF counters */ ret = 0; if (trace_state[TRACE_CFG_EMIF0_CNT0_FILTER] >= 0) ret = emif44xx_perf_cnt_configure(EMIF44XX_0, 0, trace_state[TRACE_CFG_EMIF0_CNT0_FILTER], trace_state[TRACE_CFG_EMIF0_CNT0_ID], trace_state[TRACE_CFG_EMIF0_CNT0_ADDRSPACE]); if (trace_state[TRACE_CFG_EMIF1_CNT0_FILTER] >= 0) ret |= emif44xx_perf_cnt_configure(EMIF44XX_1, 0, trace_state[TRACE_CFG_EMIF1_CNT0_FILTER], trace_state[TRACE_CFG_EMIF1_CNT0_ID], trace_state[TRACE_CFG_EMIF1_CNT0_ADDRSPACE]); if (trace_state[TRACE_CFG_EMIF0_CNT1_FILTER] >= 0) ret |= emif44xx_perf_cnt_configure(EMIF44XX_0, 1, trace_state[TRACE_CFG_EMIF0_CNT1_FILTER], trace_state[TRACE_CFG_EMIF0_CNT1_ID], trace_state[TRACE_CFG_EMIF0_CNT1_ADDRSPACE]); if (trace_state[TRACE_CFG_EMIF1_CNT1_FILTER] >= 0) ret |= emif44xx_perf_cnt_configure(EMIF44XX_1, 1, trace_state[TRACE_CFG_EMIF1_CNT1_FILTER], trace_state[TRACE_CFG_EMIF1_CNT1_ID], trace_state[TRACE_CFG_EMIF1_CNT1_ADDRSPACE]); if (ret != 0) { fprintf(stderr, "%s(): error while configuring EMIF perf. " "counters!\n", __func__); ret = OMAPCONF_ERR_NOT_AVAILABLE; goto counters44xx_count_err; } /* Configure L2CC counters */ /* Do this regardless whether enabled or disabled (at this point.) */ if (trace_state[TRACE_CFG_L2CC_CNT0_FILTER] >= 0) ret = l2cc44xx_perf_cnt_configure(0, trace_state[TRACE_CFG_L2CC_CNT0_FILTER], 1); /* for last entry, should use boolean 'true' */ if (trace_state[TRACE_CFG_L2CC_CNT1_FILTER] >= 0) ret = l2cc44xx_perf_cnt_configure(1, trace_state[TRACE_CFG_L2CC_CNT1_FILTER], 1); /* for last entry, should use boolean 'true' */ /* // if (ret != 0) { // fprintf(stderr, "%s(): error while configuring L2CC perf. " // "counters!\n", __func__); // ret = OMAPCONF_ERR_NOT_AVAILABLE; // goto counters44xx_count_err; // } */ /* Allocate buffer to store sampled data, unless continuous capture is enabled */ if (capture_time > 0) { if (sampling_rate > 0) { sample_cnt = 1 + ((capture_time * 1000) / sampling_rate); } else { /* If smaple rate of 0, trace as fast as possible for the capture time. */ sample_cnt = 1 + ((capture_time * 1000)); } } else { /* Hack. If capture_time == 0, capture continuous. Need room for at least 2 samples. */ sample_cnt = 2; if (trace_state[TRACE_CFG_LONG_HEADER] == 1) { printf("#\n"); printf("# ----------------- OMAP4430 Performance Trace+ ----------" "--------------------------------------------------------------" "-----\n"); printf("#\n"); /* printf("# NB:\n"); */ printf("# * This is an intrusive trace (counters polling).\n"); printf("# Idle C-States usage was altered.\n"); printf("# Limted additional CPU & EMIFs loads generated.\n"); printf("#\n"); /* printf("# * If CPU1 Load = -5.0, it means CPU1 is OFFLINE.\n"); */ /* printf("#\n"); */ /* printf("# * CPU LOADS CANNOT be directly converted to Mhz.\n"); */ /* printf("# OPP may have changed during the audit.\n"); */ /* printf("#\n"); */ printf("# ----------------------- Trace FORMAT -------------------" "--------------------------------------------------------------" "-----\n"); printf("#\n"); printf("# Trace Length: %us\n", capture_time); printf("#\n"); printf("# Trace Sampling Rate: %ums\n", sampling_rate); printf("#\n"); printf("# Number of samples: %u\n", sample_cnt - 1); printf("#\n"); printf("# %10.10s ", "Timestamp(s)"); }; for (i = 0; i < TRACE_CFG_ENABLED_OPTIONS_MAX; i++) { if (trace_state[i] >= 0) {/* Traces state is enabled if non-zero state value. */ ret = value2name(i, name, trace_config_options_table); printf("\t%10.10s", name); switch (i) { case TRACE_CFG_EMIF0_CNT0_FILTER: case TRACE_CFG_EMIF1_CNT0_FILTER: case TRACE_CFG_EMIF0_CNT1_FILTER: case TRACE_CFG_EMIF1_CNT1_FILTER: ret = value2name(trace_state[i], name, emif_event_counters); ret = snprintf(tmp_name, 64, "%s%s", ".", name); ret = snprintf(name, 64, "%s", tmp_name); break; case TRACE_CFG_L2CC_CNT0_FILTER: case TRACE_CFG_L2CC_CNT1_FILTER: ret = value2name(trace_state[i], name, l2cc_event_counters_table); ret = snprintf(tmp_name, 64, "%s%s", ".", name); ret = snprintf(name, 64, "%s", tmp_name); break; default: strcpy(name, " "); break; } /* end switch */ printf("%s ", name); } } printf("\n"); if (trace_state[TRACE_CFG_LONG_HEADER] == 1) { printf("#\n"); printf("# ----------------------- Trace START --------------------" "--------------------------------------------------------------" "-----\n"); } } dprintf("%s(): capture_time=%us, sample_cnt=%u\n", __func__, capture_time, sample_cnt); for (i = 0; i < TRACE_CFG_ENABLED_OPTIONS_MAX; i++) { if (trace_state[i] >= 0) {/* Traces state is enabled if non-zero state value. */ /* Add three sample entries to hold min, avg, max */ trace_buf[i] = malloc((sample_cnt+3) * sizeof(unsigned int)); if (trace_buf[i] == NULL) { ret = value2name(i, name, trace_config_options_table); fprintf(stderr, "%s(): could not allocate %s!\n", __func__, name); ret = OMAPCONF_ERR_NOT_AVAILABLE; goto counters44xx_count_err; } } } /* end for i < TRACE_CFG_ENABLED_OPTIONS_MAX */ /* Enable L2CC counters */ ret = l2cc44xx_perf_cnt_enable(); /* Sample performance indicators periodically */ printf("\n"); printf("Sampling OMAP Counters for %us, please wait...\n", capture_time); for (sample = 0; sample < sample_cnt; sample++) { /* // This could be a big for loop and 'switch' statemenet... // Get CPU runtime execution stats // Get EMIF cnt0, cnt1 & total mclk cycle counts as enabled // skorson // Being lazy and doing these two one after the other. I suppose code could be written // to convert a for 0 to 1 loop but with only two, this is OK. */ emif = 0; if (trace_state[TRACE_CFG_EMIF0_CNT0_FILTER] >= 0) { trace_buf[TRACE_CFG_EMIF0_CNT0_FILTER][sample] = emif44xx_perf_cnt_get_count( emif, EMIF44XX_PERF_CNT_0); dprintf("%s(): EMIF0 counter 0 value=%u\n", __func__, trace_buf[TRACE_CFG_EMIF0_CNT0_FILTER][sample]); } if (trace_state[TRACE_CFG_EMIF0_CNT1_FILTER] >= 0) { trace_buf[TRACE_CFG_EMIF0_CNT1_FILTER][sample] = emif44xx_perf_cnt_get_count( emif, EMIF44XX_PERF_CNT_1); dprintf("%s(): EMIF0 counter 1 value=%u\n", __func__, trace_buf[TRACE_CFG_EMIF0_CNT1_FILTER][sample]); } if (trace_state[TRACE_CFG_EMIF0_MCLK_CYCLES] >= 0) { trace_buf[TRACE_CFG_EMIF0_MCLK_CYCLES][sample] = emif44xx_perf_cnt_get_time(emif); } emif = 1; if (trace_state[TRACE_CFG_EMIF1_CNT0_FILTER] >= 0) { trace_buf[TRACE_CFG_EMIF1_CNT0_FILTER][sample] = emif44xx_perf_cnt_get_count( emif, EMIF44XX_PERF_CNT_0); dprintf("%s(): EMIF1 counter 0 value=%u\n", __func__, trace_buf[TRACE_CFG_EMIF1_CNT0_FILTER][sample]); } if (trace_state[TRACE_CFG_EMIF1_CNT1_FILTER] >= 0) { trace_buf[TRACE_CFG_EMIF1_CNT1_FILTER][sample] = emif44xx_perf_cnt_get_count( emif, EMIF44XX_PERF_CNT_1); dprintf("%s(): EMIF1 counter 1 value=%u\n", __func__, trace_buf[TRACE_CFG_EMIF1_CNT1_FILTER][sample]); } if (trace_state[TRACE_CFG_EMIF1_MCLK_CYCLES] >= 0) { trace_buf[TRACE_CFG_EMIF1_MCLK_CYCLES][sample] = emif44xx_perf_cnt_get_time(emif); dprintf("%s(): EMIF1 MCLK cycles=%u\n", __func__, trace_buf[TRACE_CFG_EMIF1_MCLK_CYCLES][sample]); } /* // FIXME: There is a bug where the L2 Counters are being disabled. Until this is known, enable the following // block to determine if the counter has been disabled during a run. Print appropriate ERROR to screen... */ if ((trace_state[TRACE_CFG_L2CC_CNT0_FILTER] >= 0) || (trace_state[TRACE_CFG_L2CC_CNT1_FILTER] >= 0)) { /* check if counter is still enabled.... */ ret = name2addr("EVENT_COUNTER_CONTROL", &addr, (reg_table *) omap4_mpuss_pl310_reg_table); ret = mem_read(addr, &data); dprintf("EVENT COUNTER VALUE: 0x%x 0x%x\n", addr, data); if (ret != 0) { fprintf(stderr, "%s(): error reading L2CC (PL310) EVENT_COUNTER_CONTROL reg!\n", __func__); return OMAPCONF_ERR_REG_ACCESS; } if (data == 0 && l2_disabled_prior == 0) { l2_disabled_prior = 1; fprintf(stderr, "%s(): WARNING:L2CC (PL310) EVENT_COUNTER_CONTROL was DISABLED during a run!!!\n", __func__); fprintf(stderr, "%s(): WARNING: Counter values will be invalid (zero) after this point.\n", __func__); } } /* END FIXME */ if (trace_state[TRACE_CFG_L2CC_CNT0_FILTER] >= 0) { trace_buf[TRACE_CFG_L2CC_CNT0_FILTER][sample] = (unsigned int) l2cc44xx_get_perf_cnt(0); dprintf("%s(): l2_event_cnt[0] sample %d = 0x%x %d\n", __func__, sample, trace_buf[TRACE_CFG_L2CC_CNT0_FILTER][sample], trace_buf[TRACE_CFG_L2CC_CNT0_FILTER][sample]); } if (trace_state[TRACE_CFG_L2CC_CNT1_FILTER] >= 0) { trace_buf[TRACE_CFG_L2CC_CNT1_FILTER][sample] = (unsigned int) l2cc44xx_get_perf_cnt(1); dprintf("%s(): l2_event_cnt[1] sample %d = 0x%x %d\n", __func__, sample, trace_buf[TRACE_CFG_L2CC_CNT1_FILTER][sample], trace_buf[TRACE_CFG_L2CC_CNT1_FILTER][sample]); } if (trace_state[TRACE_CFG_TIMER_32K_SYNC] >= 0) { addr = T32KSYNCNT_CR; ret = mem_read(addr, &data); trace_buf[TRACE_CFG_TIMER_32K_SYNC][sample] = data; dprintf("%s(): 32K CLK cycles=%u\n", __func__, trace_buf[TRACE_CFG_TIMER_32K_SYNC][sample]); } dprintf("\n"); /* Sleep for some [minimum] time before sampling again */ if ((capture_time == 0) && (sample > 0)) { /* Save timestamp */ printf("[unix time stamp here]"); for (i = 0; i < TRACE_CFG_ENABLED_OPTIONS_MAX; i++) { if (trace_state[i] >= 0) { sprintf(s, "%u", count32_delta(trace_buf[i][0], trace_buf[i][1])); printf("\t%10.10s", s); } /* if state >= 0 */ } /* for i to TRACE_CFG_ENABLED_OPTIONS_MAX */ printf("\n"); /* Now move sample[1] to sample[0] */ for (i = 0; i < TRACE_CFG_ENABLED_OPTIONS_MAX; i++) { if (trace_state[i] >= 0) { trace_buf[i][0] = trace_buf[i][1]; } /* if state >= 0 */ } /* for i to TRACE_CFG_ENABLED_OPTIONS_MAX */ sample = 0; } /* SLeep onyl if a sampling rate is set. */ /* Sampling rate of 0 is as fast as possible... */ if (sampling_rate > 0) usleep(sampling_rate * 1000); } /* Disable L2CC counters */ /* Do regardless of whether enabled for tracing or not. */ ret = l2cc44xx_perf_cnt_disable(); printf("Sampling done, processing and saving data...\n"); /* Open trace output file */ fp = workdir_fopen(trace_perf_file, "w"); if (fp == NULL) { fprintf(stderr, "%s(): could not create %s!\n", __func__, trace_perf_file); ret = OMAPCONF_ERR_NOT_AVAILABLE; goto counters44xx_count_err; } dprintf("INFO: TRACE_CFG_LONG_HEADER %d\n", trace_state[TRACE_CFG_LONG_HEADER]); if (trace_state[TRACE_CFG_LONG_HEADER] == 1) { fprintf(fp, "#\n"); fprintf(fp, "# ----------------- OMAP4430 Performance Trace+ ----------" "--------------------------------------------------------------" "-----\n"); fprintf(fp, "#\n"); /* fprintf(fp, "# NB:\n"); */ fprintf(fp, "# * This is an intrusive trace (counters polling).\n"); fprintf(fp, "# Idle C-States usage was altered.\n"); fprintf(fp, "# Limted additional CPU & EMIFs loads generated.\n"); fprintf(fp, "#\n"); /* fprintf(fp, "# * If CPU1 Load = -5.0, it means CPU1 is OFFLINE.\n"); */ /* fprintf(fp, "#\n"); */ /* fprintf(fp, "# * CPU LOADS CANNOT be directly converted to Mhz.\n"); */ /* fprintf(fp, "# OPP may have changed during the audit.\n"); */ /* fprintf(fp, "#\n"); */ fprintf(fp, "# ----------------------- Trace FORMAT -------------------" "--------------------------------------------------------------" "-----\n"); fprintf(fp, "#\n"); fprintf(fp, "# Trace Length: %us\n", capture_time); fprintf(fp, "#\n"); fprintf(fp, "# Trace Sampling Rate: %ums\n", sampling_rate); fprintf(fp, "#\n"); fprintf(fp, "# Number of samples: %u\n", sample_cnt - 1); fprintf(fp, "#\n"); fprintf(fp, "# %10.10s ", "Timestamp(s)"); }; for (i = 0; i < TRACE_CFG_ENABLED_OPTIONS_MAX; i++) { if (trace_state[i] >= 0) {/* Traces state is enabled if non-zero state value. */ ret = value2name(i, name, trace_config_options_table); fprintf(fp, "\t%10.10s", name); switch (i) { case TRACE_CFG_EMIF0_CNT0_FILTER: case TRACE_CFG_EMIF1_CNT0_FILTER: case TRACE_CFG_EMIF0_CNT1_FILTER: case TRACE_CFG_EMIF1_CNT1_FILTER: ret = value2name(trace_state[i], name, emif_event_counters); ret = snprintf(tmp_name, 64, "%s%s", ".", name); ret = snprintf(name, 64, "%s", tmp_name); break; case TRACE_CFG_L2CC_CNT0_FILTER: case TRACE_CFG_L2CC_CNT1_FILTER: ret = value2name(trace_state[i], name, l2cc_event_counters_table); ret = snprintf(tmp_name, 64, "%s%s", ".", name); ret = snprintf(name, 64, "%s", tmp_name); break; default: strcpy(name, " "); break; } /* end switch */ fprintf(fp, "%s ", name); } } fprintf(fp, "\n"); if (trace_state[TRACE_CFG_LONG_HEADER] == 1) { fprintf(fp, "#\n"); fprintf(fp, "# ----------------------- Trace START --------------------" "--------------------------------------------------------------" "-----\n"); } dprintf ("I'm here 0\n"); /* Note: dropping first sample (or using it to normalize data to 0) */ for (sample = 1; sample < sample_cnt; sample++) { if (sampling_rate > 0) { /* Save timestamp */ sprintf(s, "%.3lf", (double) (sample * sampling_rate) / 1000.0); fprintf(fp, "%10.10s", s); } else { sprintf(s, "%.3lf", (double) (sample)); fprintf(fp, "%10.10s", s); } dprintf ("I'm here 1.%d\n", sample); for (i = 0; i < TRACE_CFG_ENABLED_OPTIONS_MAX; i++) { if (trace_state[i] >= 0) { /* // For now, treating this timer as a counter - its easier to perform calculations // (std. dev, mean, error etc.) // if ( i == TRACE_CFG_TIMER_32K_SYNC ) { // // These don't need offset adjusted like counters // sprintf(s, "%u", count32_delta(trace_buf[i][0], // trace_buf[i][sample]) ); // fprintf(fp, "\t%10.10s", s); // continue; // } */ dprintf("INFO: Current Sample %d Value %d Previous %d\n", sample, trace_buf[i][sample], trace_buf[i][sample - 1]); sprintf(s, "%u", count32_delta(trace_buf[i][sample - 1], trace_buf[i][sample])); fprintf(fp, "\t%10.10s", s); } /* if state >= 0 */ } /* for i to TRACE_CFG_ENABLED_OPTIONS_MAX */ dprintf ("I'm here 2\n"); fprintf(fp, "\n"); } /* for sample < sample_cnt */ if (trace_state[TRACE_CFG_LONG_HEADER]) { fprintf(fp, "# ------------------------ Trace END ---------------------" "--------------------------------------------------------------" "-----\n"); }; fclose(fp); printf("Performance trace saved into \"%s\" file.\n", trace_perf_file); /* Calculate Averages/Statistics*/ fp = workdir_fopen(trace_perf_stats_file, "w"); if (fp == NULL) { fprintf(stderr, "%s(): could not create %s!\n", __func__, trace_perf_stats_file); ret = OMAPCONF_ERR_NOT_AVAILABLE; goto counters44xx_count_err; } dprintf ("I'm here 2\n"); autoadjust_table_init(table); row = 0; strncpy(table[row][0], "Performance Statistics", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Option", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Min", TABLE_MAX_ELT_LEN); strncpy(table[row][3], "Max", TABLE_MAX_ELT_LEN); strncpy(table[row][4], "Average", TABLE_MAX_ELT_LEN); row++; /* Note: sample_cnt+0 = min, +1=avg, +2 = max */ min = sample_cnt; avg = sample_cnt+1; max = sample_cnt+2; dprintf ("I'm here 3\n"); for (i = 0; i < TRACE_CFG_ENABLED_OPTIONS_MAX; i++) { /* Whats the 'if' below for? Will always be true... */ if (trace_state[i] >= 0) { trace_buf[i][min] = ~0; trace_buf[i][max] = 0; trace_buf[i][avg] = 0; dprintf ("I'm here 3.%d\n", i); ret = value2name(i, name, trace_config_options_table); dprintf ("Name: %s MIN: %d MAX: %d AVG: %d\n", name, trace_buf[i][min], trace_buf[i][max], trace_buf[i][avg]); for (sample = 1; sample < sample_cnt; sample++) { dprintf ("I'm here 3.%d.%d\n", i, sample); temp = count32_delta(trace_buf[i][sample - 1], trace_buf[i][sample]); dprintf ("I'm here 3.%d.%d !FREQ %d\n", i, sample, temp); if (temp > trace_buf[i][max]) trace_buf[i][max] = temp; if (temp < trace_buf[i][min]) trace_buf[i][min] = temp; trace_buf[i][avg] = (unsigned int) avg_recalc((double) trace_buf[i][avg], (double) temp, sample - 1); ret = value2name(i, name, trace_config_options_table); dprintf ("Name: %s MIN: %d MAX: %d AVG: %d\n", name, trace_buf[i][min], trace_buf[i][max], trace_buf[i][avg]); } /* for sample < sample_cnt */ dprintf ("I'm here 4.%d\n", i); /* Save statistics */ ret = value2name(i, name, trace_config_options_table); dprintf ("Name: %s MIN: %d MAX: %d AVG: %d\n", name, trace_buf[i][min], trace_buf[i][max], trace_buf[i][avg]); strncpy(table[row][0], name, TABLE_MAX_ELT_LEN); strcpy (option, ""); switch (i) { case TRACE_CFG_EMIF0_CNT0_FILTER: case TRACE_CFG_EMIF1_CNT0_FILTER: case TRACE_CFG_EMIF0_CNT1_FILTER: case TRACE_CFG_EMIF1_CNT1_FILTER: ret = value2name(trace_state[i], option, emif_event_counters); break; case TRACE_CFG_L2CC_CNT0_FILTER: case TRACE_CFG_L2CC_CNT1_FILTER: ret = value2name(trace_state[i], option, l2cc_event_counters_table); break; default: break; } /* end switch */ strncpy(table[row][1], option, TABLE_MAX_ELT_LEN); snprintf(table[row][2], TABLE_MAX_ELT_LEN, "%.2d", trace_buf[i][min]); snprintf(table[row][3], TABLE_MAX_ELT_LEN, "%.2d", trace_buf[i][max]); snprintf(table[row][4], TABLE_MAX_ELT_LEN, "%.2d", trace_buf[i][avg]); row++; } /* if (trace_state[i] >= 0 */ } /* for i to TRACE_CFG_ENABLED_OPTIONS_MAX */ dprintf ("I'm here 5\n"); autoadjust_table_fprint(fp, table, row, 4); fclose(fp); printf("Performance statistics saved into \"%s\" file.\n\n", trace_perf_stats_file); dprintf ("I'm here 6\n"); autoadjust_table_print(table, row, 4); dprintf ("I'm here 7\n"); return ret; counters44xx_count_err: /* Free allocated buffers */ for (i = 0; i < TRACE_CFG_ENABLED_OPTIONS_MAX; i++) { if (trace_state[i] >= 0) {/* Traces state is enabled if non-neg state value. */ if (trace_buf[i] != NULL) { free(trace_buf[i]); } } } /* end for i < TRACE_CFG_ENABLED_OPTIONS_MAX */ return ret; }
/* ------------------------------------------------------------------------*//** * @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 prm54xx_dump * @BRIEF dump selected registers and pretty-print it in * selected output stream * @RETURNS 0 in case of success * OMAPCONF_ERR_CPU * OMAPCONF_ERR_ARG * @param[in,out] stream: output stream * @param[in] id: PRM module ID - If id == PRM54XX_MODS_COUNT, * dump all PRM registers. * @DESCRIPTION dump selected registers and pretty-print it in * selected output stream *//*------------------------------------------------------------------------ */ int prm54xx_dump(FILE *stream, prm54xx_mod_id id) { unsigned int i = 0, mid; unsigned int val = 0; int err = 0; reg **mod; reg *r; char s[TABLE_MAX_ELT_LEN]; char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row; if (stream == NULL) { fprintf(stderr, "%s(): stream == NULL!!!\n", __func__); err = OMAPCONF_ERR_ARG; goto prm54xx_dump_end; } if (id > PRM54XX_MODS_COUNT) { fprintf(stderr, "%s(): id (%u) > PRM54XX_MODS_COUNT!!! (%u)\n", __func__, id, PRM54XX_MODS_COUNT); err = OMAPCONF_ERR_ARG; goto prm54xx_dump_end; } autoadjust_table_init(table); row = 0; if (id != PRM54XX_MODS_COUNT) snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s Reg. Name", prm54xx_mod_name_get(id)); else strncpy(table[row][0], "PRM Reg. Name", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Reg. Address", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Reg. Value", TABLE_MAX_ELT_LEN); row++; for (mid = PRM54XX_DSS_PRM; mid < PRM54XX_MODS_COUNT; mid++) { if ((id != PRM54XX_MODS_COUNT) && (mid != id)) continue; else { if (cpu_revision_get() == REV_ES1_0) mod = prm54xxes1_mods[mid]; else mod = prm54xx_mods[mid]; for (i = 0; mod[i] != NULL; i++) { r = mod[i]; /* Read register */ val = reg_read(r); /* Show register name, addr & content */ snprintf(s, TABLE_MAX_ELT_LEN, "%s", r->name); autoadjust_table_strncpy(table, row, 0, s); snprintf(s, TABLE_MAX_ELT_LEN, "0x%08X", r->addr); autoadjust_table_strncpy(table, row, 1, s); snprintf(s, TABLE_MAX_ELT_LEN, "0x%08X", val); autoadjust_table_strncpy(table, row++, 2, s); } } } autoadjust_table_print(table, row, 3); prm54xx_dump_end: return err; }
/* ------------------------------------------------------------------------*//** * @FUNCTION emif54xx_dump * @BRIEF dump selected registers * @RETURNS 0 in case of success * OMAPCONF_ERR_CPU * OMAPCONF_ERR_ARG * @param[in,out] stream: output stream * @param[in] id: EMIF module ID * If id == EMIF54XX_MODS_COUNT, dump all EMIF registers. * @DESCRIPTION dump selected registers and pretty-print it in selected * output stream *//*------------------------------------------------------------------------ */ int emif54xx_dump(FILE *stream, emif54xx_mod_id id) { unsigned int i = 0, mid, accessible; unsigned int val = 0; int err = 0; reg **mod; reg *r; char s[TABLE_MAX_ELT_LEN]; char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row; CHECK_CPU(54xx, OMAPCONF_ERR_CPU); CHECK_NULL_ARG(stream, OMAPCONF_ERR_ARG); if (id > EMIF54XX_MODS_COUNT) { fprintf(stderr, "%s(): id (%u) > EMIF54XX_MODS_COUNT!!! (%u)\n", __func__, id, EMIF54XX_MODS_COUNT); err = OMAPCONF_ERR_ARG; goto emif54xx_dump_end; } autoadjust_table_init(table); row = 0; if (id != EMIF54XX_MODS_COUNT) snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s Reg. Name", emif54xx_mod_name_get(id)); else strncpy(table[row][0], "EMIF Reg. Name", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Reg. Address", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Reg. Value", TABLE_MAX_ELT_LEN); row++; for (mid = 0; mid < EMIF54XX_MODS_COUNT; mid++) { if ((id != EMIF54XX_MODS_COUNT) && (mid != id)) continue; else { switch (mid) { case EMIF54XX_EMIF1: accessible = module_is_accessible(MOD_EMIF1); break; case EMIF54XX_EMIF2: accessible = module_is_accessible(MOD_EMIF2); break; default: accessible = 0; } if (!accessible) { printf("%s module is not running, registers not" " accessible.\n", emif54xx_mod_name_get(mid)); return 0; } if (cpu_revision_get() == REV_ES1_0) mod = emif54xxes1_mods[mid]; else mod = emif54xx_mods[mid]; for (i = 0; mod[i] != NULL; i++) { r = mod[i]; /* Read register */ dprintf("%s(): read %s 0x%08X\n", __func__, r->name, r->addr); val = reg_read(r); dprintf("%s(): OK\n", __func__); /* Show register name, addr & content */ snprintf(s, TABLE_MAX_ELT_LEN, "%s", r->name); autoadjust_table_strncpy(table, row, 0, s); snprintf(s, TABLE_MAX_ELT_LEN, "0x%08X", r->addr); autoadjust_table_strncpy(table, row, 1, s); snprintf(s, TABLE_MAX_ELT_LEN, "0x%08X", val); autoadjust_table_strncpy(table, row++, 2, s); } } } autoadjust_table_print(table, row, 3); emif54xx_dump_end: return err; }
/* ------------------------------------------------------------------------*//** * @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; }
/* ------------------------------------------------------------------------*//** * @FUNCTION tlv320aic3x_dumpregs * @BRIEF dump registers from table given as argument * @RETURNS 0 in case of success * OMAPCONF_ERR_REG_ACCESS * @param[in] none * @DESCRIPTION dump registers from table given as argument *//*------------------------------------------------------------------------ */ int tlv320aic3x_dumpregs(int argc, char *argv[]) { unsigned int i = 0; unsigned int val = 0; int ret, err = 0; char autoadjust_table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row; unsigned int i2cbus, chip_address; if (argc == 1) { /* Take defaults: bus 0, address 0x18 */ i2cbus = 0; chip_address = TLV320AIC3X_I2C_VALID_ADDR1; } else if (argc == 3) { if (argv == NULL) { printf("%s(): argv == NULL!!!\n", __func__); return OMAPCONF_ERR_ARG; } ret = sscanf(argv[1], "%u", &i2cbus); if (ret != 1) { tlv320aic3x_dumpregs_usage(); return OMAPCONF_ERR_ARG; } ret = sscanf(argv[2], "0x%x", &chip_address); if (ret != 1) { tlv320aic3x_dumpregs_usage(); return OMAPCONF_ERR_ARG; } } switch (chip_address) { case TLV320AIC3X_I2C_VALID_ADDR1: case TLV320AIC3X_I2C_VALID_ADDR2: case TLV320AIC3X_I2C_VALID_ADDR3: case TLV320AIC3X_I2C_VALID_ADDR4: break; default: printf("Invalid chip address, valid addresses are: 0x%02x - 0x%02x\n", TLV320AIC3X_I2C_VALID_ADDR1, TLV320AIC3X_I2C_VALID_ADDR4); return OMAPCONF_ERR_NOT_AVAILABLE; } /* Read register 0 (Page select) to see if other i2c reads can succeed */ ret = i2cget(i2cbus, chip_address, tlv320aic3x_reg_table[i].addr, &val); if (ret) { printf("I2C chip is not accessible\n"); return OMAPCONF_ERR_REG_ACCESS; } autoadjust_table_init(autoadjust_table); row = 0; printf("I2C bus: %u\n", i2cbus); printf("Chip address: 0x%02x\n\n", chip_address); strncpy(autoadjust_table[row][0], "Reg. Name", TABLE_MAX_ELT_LEN); strncpy(autoadjust_table[row][1], "Reg. Addr", TABLE_MAX_ELT_LEN); strncpy(autoadjust_table[row][2], "Reg. Val.", TABLE_MAX_ELT_LEN); row++; while (strcmp(tlv320aic3x_reg_table[i].name, "END") != 0) { ret = i2cget(i2cbus, chip_address, tlv320aic3x_reg_table[i].addr, &val); if (ret == 0) { /* Show register name, addr & content (hex) */ snprintf(autoadjust_table[row][0], TABLE_MAX_ELT_LEN, "%s", tlv320aic3x_reg_table[i].name); snprintf(autoadjust_table[row][1], TABLE_MAX_ELT_LEN, "%3u", tlv320aic3x_reg_table[i].addr); snprintf(autoadjust_table[row][2], TABLE_MAX_ELT_LEN, "0x%02X", val); row++; } else if (ret == -4) { /* * Some registers maybe unaccessible if * its voltage domain is disabled */ snprintf(autoadjust_table[row][0], TABLE_MAX_ELT_LEN, "%s", tlv320aic3x_reg_table[i].name); snprintf(autoadjust_table[row][1], TABLE_MAX_ELT_LEN, "%3u", tlv320aic3x_reg_table[i].addr); snprintf(autoadjust_table[row][2], TABLE_MAX_ELT_LEN, "INACTIVE"); row++; } else { printf("omapconf_tlv320aic3x_dumpregs(): read error! " "(addr=%u, err=%d)\n", tlv320aic3x_reg_table[i].addr, ret); err = OMAPCONF_ERR_REG_ACCESS; break; } i++; } autoadjust_table_print(autoadjust_table, row, 3); return err; }
/* ------------------------------------------------------------------------*//** * @FUNCTION sr54xx_dump * @BRIEF dump selected registers and pretty-print it in selected * output stream * @RETURNS 0 in case of success * OMAPCONF_ERR_CPU * OMAPCONF_ERR_ARG * @param[in,out] stream: output stream * @param[in] id: SR module ID - If id == SR54XX_MODS_COUNT, * dump all SR registers. * @DESCRIPTION dump selected registers and pretty-print it in selected * output stream *//*------------------------------------------------------------------------ */ int sr54xx_dump(FILE *stream, sr54xx_mod_id id) { unsigned int i = 0, mid; unsigned int val = 0; int err = 0; reg **mod; reg *r; char s[TABLE_MAX_ELT_LEN]; char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row; if (stream == NULL) { fprintf(stderr, "%s(): stream == NULL!!!\n", __func__); err = OMAPCONF_ERR_ARG; goto sr54xx_dump_end; } if (id > SR54XX_MODS_COUNT) { fprintf(stderr, "%s(): id (%u) > SR54XX_MODS_COUNT!!! (%u)\n", __func__, id, SR54XX_MODS_COUNT); err = OMAPCONF_ERR_ARG; goto sr54xx_dump_end; } autoadjust_table_init(table); row = 0; if (id != SR54XX_MODS_COUNT) snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s Reg. Name", sr54xx_mod_name_get(id)); else strncpy(table[row][0], "SR Reg. Name", TABLE_MAX_ELT_LEN); strncpy(table[row][1], "Reg. Address", TABLE_MAX_ELT_LEN); strncpy(table[row][2], "Reg. Value", TABLE_MAX_ELT_LEN); row++; for (mid = SR54XX_SMARTREFLEX_MPU; mid < SR54XX_MODS_COUNT; mid++) { if ((id != SR54XX_MODS_COUNT) && (mid != id)) continue; else { if (!sr54xx_is_enabled(mid)) { if (stream != NULL) fprintf(stream, "%s module not running" ", registers not accessible.\n", sr54xx_mod_name_get(mid)); return 0; } mod = sr54xx_mods[mid]; for (i = 0; mod[i] != NULL; i++) { r = mod[i]; /* Read register */ val = reg_read(r); /* Show register name, addr & content */ snprintf(s, TABLE_MAX_ELT_LEN, "%s", r->name); autoadjust_table_strncpy(table, row, 0, s); snprintf(s, TABLE_MAX_ELT_LEN, "0x%08X", r->addr); autoadjust_table_strncpy(table, row, 1, s); snprintf(s, TABLE_MAX_ELT_LEN, "0x%08X", val); autoadjust_table_strncpy(table, row++, 2, s); } } } autoadjust_table_fprint(stream, table, row, 3); sr54xx_dump_end: return err; }
/* ------------------------------------------------------------------------*//** * @FUNCTION ctrlmod54xx_io_audit * @BRIEF OMAP5 PADCONF/IO audit. * @RETURNS 0 in case of success * OMAPCONF_ERR_ARG * OMAPCONF_ERR_CPU * @param[in,out] stream: output file - NULL: no output (silent) * @param[in,out] err_nbr: pointer to return audit error number * @param[in,out] wng_nbr: pointer to return audit warning number * @DESCRIPTION OMAP5 PADCONF/IO audit. *//*------------------------------------------------------------------------ */ int ctrlmod54xx_io_audit(FILE *stream, unsigned int *err_nbr, unsigned int *wng_nbr) { const char pass[5] = "pass"; const char fail[5] = "FAIL"; const char ignore[5] = "ign."; const char warning[5] = "warn"; char *status; char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN]; unsigned int row, i, j, curr, expected, max; ctrlmod54xx_golden_item *golden_values; reg **ctrlmod_regs; CHECK_CPU(54xx, OMAPCONF_ERR_CPU); CHECK_NULL_ARG(err_nbr, OMAPCONF_ERR_ARG); CHECK_NULL_ARG(wng_nbr, OMAPCONF_ERR_ARG); *err_nbr = 0; *wng_nbr = 0; if (cpu_revision_get() != REV_ES1_0) { fprintf(stream, "No golden settings available for OMAP5430 ES2.x, sorry...\n\n"); status = (char *) warning; (*wng_nbr)++; return OMAPCONF_ERR_CPU; } for (j = 0; j < 4; j++) { autoadjust_table_init(table); row = 0; switch (j) { case 0: snprintf(table[row][0], TABLE_MAX_ELT_LEN, "CONTROL MODULE CORE registers AUDIT"); if (cpu_revision_get() == REV_ES1_0) { golden_values = (ctrlmod54xx_golden_item *) ctrlmod_core54xxes1_golden_values; ctrlmod_regs = omap5430es1_ctrl_module_core_mod; max = OMAP5430ES1_CTRL_MODULE_CORE_MOD_REGCOUNT; } else { /* FIXME WHEN ES2.0 targets available */ golden_values = (ctrlmod54xx_golden_item *) ctrlmod_core54xxes1_golden_values; ctrlmod_regs = omap5430_ctrl_module_core_mod; max = OMAP5430_CTRL_MODULE_CORE_MOD_REGCOUNT; } break; case 1: snprintf(table[row][0], TABLE_MAX_ELT_LEN, "CONTROL MODULE CORE PADCONF Registers AUDIT"); if (cpu_revision_get() == REV_ES1_0) { golden_values = (ctrlmod54xx_golden_item *) ctrlmod_core_pad54xxes1_golden_values; ctrlmod_regs = omap5430es1_ctrl_module_core_pad_mod; max = OMAP5430_CTRL_MODULE_CORE_PAD_MOD_REGCOUNT; } else { golden_values = (ctrlmod54xx_golden_item *) ctrlmod_core_pad54xxes1_golden_values; ctrlmod_regs = omap5430_ctrl_module_core_pad_mod; max = OMAP5430_CTRL_MODULE_CORE_PAD_MOD_REGCOUNT; } break; case 2: snprintf(table[row][0], TABLE_MAX_ELT_LEN, "CONTROL MODULE WKUP Registers AUDIT"); if (cpu_revision_get() == REV_ES1_0) { golden_values = (ctrlmod54xx_golden_item *) ctrlmod_wkup54xxes1_golden_values; ctrlmod_regs = omap5430es1_ctrl_module_wkup_mod; max = OMAP5430ES1_CTRL_MODULE_WKUP_MOD_REGCOUNT; } else { /* FIXME WHEN ES2.0 targets available */ golden_values = (ctrlmod54xx_golden_item *) ctrlmod_wkup54xxes1_golden_values; ctrlmod_regs = omap5430_ctrl_module_wkup_mod; max = OMAP5430ES1_CTRL_MODULE_WKUP_MOD_REGCOUNT; } break; case 3: snprintf(table[row][0], TABLE_MAX_ELT_LEN, "CONTROL MODULE WKUP PADCONF Registers AUDIT"); if (cpu_revision_get() == REV_ES1_0) { golden_values = (ctrlmod54xx_golden_item *) ctrlmod_wkup_pad54xxes1_golden_values; ctrlmod_regs = omap5430_ctrl_module_wkup_pad_mod; max = OMAP5430_CTRL_MODULE_WKUP_PAD_MOD_REGCOUNT; } else { /* FIXME WHEN ES2.0 targets available */ golden_values = (ctrlmod54xx_golden_item *) ctrlmod_wkup_pad54xxes1_golden_values; ctrlmod_regs = omap5430_ctrl_module_wkup_pad_mod; max = OMAP5430_CTRL_MODULE_WKUP_PAD_MOD_REGCOUNT; } break; } snprintf(table[row][1], TABLE_MAX_ELT_LEN, "Current"); snprintf(table[row][2], TABLE_MAX_ELT_LEN, "Expected"); snprintf(table[row++][3], TABLE_MAX_ELT_LEN, "STATUS"); for (i = 0; i < max; i++) { /* Read register */ curr = reg_read(ctrlmod_regs[i]); /* Store name & register read content in table */ snprintf(table[row][0], TABLE_MAX_ELT_LEN, "%s", (ctrlmod_regs[i])->name); snprintf(table[row][1], TABLE_MAX_ELT_LEN, "0x%08X", curr); /* Compare to golden value */ switch (golden_values[i].valid) { case DATA_INVALID: case DATA_TBD: status = (char *) warning; (*wng_nbr)++; snprintf(table[row][2], TABLE_MAX_ELT_LEN, " TBD"); break; case DATA_VALID: expected = golden_values[i].golden_value; snprintf(table[row][2], TABLE_MAX_ELT_LEN, "0x%08X", expected); if (curr != expected) { status = (char *) fail; (*err_nbr)++; } else { status = (char *) pass; } break; case DATA_IGNORE: status = (char *) ignore; break; default: fprintf(stderr, "%s(): something's wrong here?! (j=%u, " "i=%u, golden_values[i].valid=%u)\n", __func__, j, i, golden_values[i].valid); } /* Store status in table */ snprintf(table[row++][3], TABLE_MAX_ELT_LEN, "%s", status); } if (stream != NULL) { autoadjust_table_fprint(stream, table, row, 4); fprintf(stream, " ### WARNING: PRELIMINARY ###\n"); fprintf(stream, " ### GOLDEN VALUES STILL TO BE " "VERIFIED/COMPLETED!!! ###\n\n"); } } /* Print audit results summary */ if (stream != NULL) { if (*err_nbr == 0) fprintf(stream, "\nSUCCESS! Clock Speed audit " "completed with 0 error (%d warning(s))\n\n", *wng_nbr); else fprintf(stream, "\nFAILED! Clock Speed audit " "completed with %d error and %d warning.\n\n", *err_nbr, *wng_nbr); } return 0; }