Пример #1
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		cpufreq_set
 * @BRIEF		change MPU OPP using cpufreq userspace governor.
 * @RETURNS		0 in case of success
 *			CPUFREQ_ERR_NOT_AVAILABLE
 *			CPUFREQ_ERR_UNEXPECTED
 * @param[in]		freq_mpu: MPU frequency to be set (KHz)
 * @DESCRIPTION		change MPU OPP using cpufreq userspace governor.
 *//*------------------------------------------------------------------------ */
int cpufreq_set(unsigned int freq_mpu)
{
	int ret;
	char prev_gov[CPUFREQ_GOV_MAX_NAME_LENGTH];
	char freq_mpu_s[8];
	FILE *fp;

	/* Switch to userspace governor to get MPU OPP control */
	ret = cpufreq_scaling_governor_set("userspace", prev_gov);
	if (ret != 0)
		return ret;

	fp = fopen(cpufreq_scaling_setspeed_file, "r+");
	if (fp == NULL) {
		fprintf(stderr, "%s not found, no CPUFREQ?\n\n",
			cpufreq_scaling_setspeed_file);
		return CPUFREQ_ERR_NOT_AVAILABLE;
	}

	sprintf(freq_mpu_s, "%u", freq_mpu);
	if (fwrite(freq_mpu_s, sizeof(char), strlen(freq_mpu_s), fp)
		!= strlen(freq_mpu_s)) {
		fprintf(stderr, "%s(): could not update CPU frequency!\n",
			__func__);
		ret = CPUFREQ_ERR_UNEXPECTED;
	} else {
		ret = 0;
	}

	if (fp != NULL)
		fclose(fp);

	return ret;
}
Пример #2
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		lib54xx_voltage_set
 * @BRIEF		change voltage of a given voltage domain, switching
 *			CPUFreq governor to "userspace" & disabling smart-reflex
 * @RETURNS		0 on success
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_NOT_AVAILABLE
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_INTERNAL
 * @param[in]		vdd_id: voltage domain ID
 * @param[in]		volt: new supply voltage (in volt)
 * @DESCRIPTION		change voltage of a given voltage domain, switching
 *			CPUFreq governor to "userspace" & disabling smart-reflex
 *//*------------------------------------------------------------------------ */
int lib54xx_voltage_set(voltdm54xx_id vdd_id, double volt)
{
	int ret, ret_cpufreq;
	char prev_gov[CPUFREQ_GOV_MAX_NAME_LENGTH];
	sr54xx_mod_id sr_id;

	CHECK_CPU(54xx, OMAPCONF_ERR_CPU);
	CHECK_ARG_LESS_THAN(vdd_id, VDD54XX_ID_MAX, OMAPCONF_ERR_ARG);

	/*
	 * Switch governor to 'userspace' otherwise voltage change will be
	 * overriden in case of OPP change.
	 */
	printf("Warning: switching CPUFreq governor to 'userspace', otherwise "
		"voltage change will be overriden...\n");
	ret_cpufreq = cpufreq_scaling_governor_set("userspace", prev_gov);
	if (ret_cpufreq < 0)
		printf("Warning: failed to switch governor. Voltage will be "
			"overriden in case of OPP change.\n");
	else
		printf("CPUFreq governor switched to 'userspace'.\n");
	/*
	 * Disable Smart-Reflex (if running) otherwise voltage change will be
	 * overriden.
	 */
	sr_id = sr54xx_vddid2srid(vdd_id);
	if (sr54xx_avs_is_enabled(sr_id)) {
		printf("Warning: %s Smart-Reflex AVS is enabled. "
			"Disabling it...\n", voltdm54xx_name_get(vdd_id));
		ret = sr54xx_avs_enable(sr_id, 0);
		if (ret == 0)
			printf("Smartreflex disabled.\n\n");
		else
			printf("Warning: Could not disable Smart-Reflex AVS. "
				"Voltage may be overriden.\n\n");
	} else {
		printf("Smartreflex disabled.\n\n");
	}

	ret = voltdm54xx_voltage_set(vdd_id,
		(unsigned long) (volt * 1000000));
	if (ret != 0) {
		fprintf(stderr, "Oups, could not change %s voltage to "
			"%.3lfV ... (%d)\n\n",
			voltdm54xx_name_get(vdd_id), volt, ret);
	} else {
		printf("%s supply voltage set to %1.3lfV (vsel = 0x%02X).\n\n",
			voltdm54xx_name_get(vdd_id), volt,
			smps_uvolt2vsel(vdd_id2smps_id(vdd_id),
				(unsigned long) (volt * 1000000)));
		printf("Warning:\n"
			"  - Do not re-enable %s smartreflex or new voltage "
			"will be overriden.\n"
			"  - Do not change OPP (or use CPUFREQ) or new voltage"
			" will be overriden.\n\n", voltdm54xx_name_get(vdd_id));
	}

	return ret;
}
Пример #3
0
/* ------------------------------------------------------------------------*//**
 * @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;
}
Пример #4
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		lib54xx_vminsearch
 * @BRIEF		search minimum supply voltage by decreasing voltage
 *			step by step  until it breaks.
 * @RETURNS		0 on success
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_NOT_AVAILABLE
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_INTERNAL
 * @param[in]		argc: shell input argument number (must be == 3)
 * @param[in]		argv: shell input argument(s)
 *				argv[0]="voltage domain" ("mpu", "mm", "core")
 *				argv[1]="initial voltage" (in volts)
 *				argv[2]="delay" between steps (in milliseconds)
 * @DESCRIPTION		search minimum supply voltage by decreasing voltage
 *			step by step  until it breaks.
 *			NB: switch CPUFreq governor to "userspace" &
 *			disable smart-reflex
 *//*------------------------------------------------------------------------ */
int lib54xx_vminsearch(int argc, char *argv[])
{
	long uv;
	double v, prev_v;
	int ret, temp;
	unsigned long vstep;
	unsigned char vsel;
	voltdm54xx_id vdd_id;
	sr54xx_mod_id sr_id;
	unsigned int ms;
	char prev_gov[CPUFREQ_GOV_MAX_NAME_LENGTH];

	CHECK_CPU(54xx, OMAPCONF_ERR_CPU);

	/* Retrieve arguments */
	if (argc != 3)
		goto lib54xx_vminsearch_arg_err;
	if (strcmp(argv[0], "mpu") == 0)
		vdd_id = VDD54XX_MPU;
	else if (strcmp(argv[0], "mm") == 0)
		vdd_id = VDD54XX_MM;
	else if (strcmp(argv[0], "core") == 0)
		vdd_id = VDD54XX_CORE;
	else
		goto lib54xx_vminsearch_arg_err;
	ret = sscanf(argv[1], "%lf", &v);
	if (ret != 1)
		goto lib54xx_vminsearch_arg_err;
	ret = sscanf(argv[2], "%d", &ms);
	if (ret != 1)
		goto lib54xx_vminsearch_arg_err;
	if (ms <= 0)
		goto lib54xx_vminsearch_arg_err;

	/*
	 * Switch governor to 'userspace' otherwise voltage change will be
	 * overriden in case of OPP change.
	 */
	printf("Warning: switching CPUFreq governor to 'userspace', otherwise "
		"voltage change will be overriden...\n");
	ret = cpufreq_scaling_governor_set("userspace", prev_gov);
	if (ret < 0)
		printf("Warning: failed to switch governor. Voltage will be "
			"overriden in case of OPP change.\n");
	else
		printf("CPUFreq governor switched to 'userspace'.\n");

	/*
	 * Disable Smart-Reflex (if running) otherwise voltage change will be
	 * overriden.
	 */
	sr_id = sr54xx_vddid2srid(vdd_id);
	if (sr54xx_avs_is_enabled(sr_id)) {
		printf("Warning: %s Smart-Reflex AVS is enabled. "
			"Disabling it...\n", voltdm54xx_name_get(vdd_id));
		ret = sr54xx_avs_enable(sr_id, 0);
		if (ret == 0)
			printf("Smartreflex disabled.\n\n");
		else
			printf("Warning: Could not disable Smart-Reflex AVS. "
				"Voltage may be overriden.\n\n");
	} else {
		printf("Smartreflex disabled.\n\n");
	}

	/* Show current OPP for reference */
	printf("Current OPP configuration for reference:\n\n");
	opp_show(stdout);

	/* Retrieving SMPS voltage step */
	vstep = smps_step_get(vdd_id2smps_id(vdd_id));
	dprintf("%s(): vstep=%luuV\n", __func__, vstep);

	printf("Vmin SEARCH on %s domain scaling voltage down from %1.3lfV in "
		"steps of %lumV, waiting %dms between each step.\n",
		voltdm54xx_name_get(vdd_id), v, vstep / 1000, ms);
	printf("LAST voltage displayed with OK status before crash "
		"will be the Vmin for %s domain.\n\n",
		voltdm54xx_name_get(vdd_id));
	printf("NB:\n  - Make sure your load generator application is "
		"running in background during the whole procedure.\n");
	printf("  - PLATFORM MUST BE REBOOTED AFTER USE "
		"(NO POSSIBLE RECOVERY).\n\n");

	/* Rounding requested initial voltage */
	vsel = smps_uvolt2vsel(vdd_id2smps_id(vdd_id),
		(unsigned long) (v * 1000000));
	prev_v = v;
	v = (double) smps_vsel2uvolt(vdd_id2smps_id(vdd_id), vsel);
	v = v / 1000000;
	if (v != prev_v)
		printf("Note: rounded up initial voltage to %.3lfV.\n\n", v);

	/* Decreasing voltage step by step until it breaks */
	printf("Starting Vmin SEARCH...\n");

	for (uv = (unsigned long) (v * 1000000); uv >= 0; uv = uv - vstep) {
		/* Get vsel corresponding to target voltage */
		vsel = smps_uvolt2vsel(vdd_id2smps_id(vdd_id), uv);
		temp = temp54xx_get(voltdm2sensor_id(vdd_id));
		if (temp != TEMP_ABSOLUTE_ZERO)
			printf("Trying %1.3lfV (SMPS code: 0x%02X, temperature: %dC/%dF)...",
				smps_vsel2volt(vdd_id2smps_id(vdd_id), vsel),
				vsel, temp, celcius2fahrenheit(temp));
		else
			printf("Trying %1.3lfV (SMPS code: 0x%02X, temperature: N/A)...",
				smps_vsel2volt(vdd_id2smps_id(vdd_id), vsel),
				vsel);
		fflush(stdout);
		ret = smps_voltage_set(vdd_id2smps_id(vdd_id), uv);
		if (ret != 0) {
			fprintf(stderr, "Error: could not set %s voltage!\n\n",
				voltdm54xx_name_get(vdd_id));
			return ret;
		}
		usleep(1000 * ms);
		printf("OK!\n");
	}
	fprintf(stderr, "Shouldn't have reached this point... "
		"please check voltage is really scaling down.\n\n");
	return 0;

lib54xx_vminsearch_arg_err:
	return err_arg_msg_show(HELP_VOLT);
	return OMAPCONF_ERR_ARG;
}