Beispiel #1
0
void chromeos_acpi_gpio_generate(const struct cros_gpio *gpios, size_t num)
{
	size_t i;
	int gpio_num;

	acpigen_write_scope("\\");
	acpigen_write_name("OIPG");

	acpigen_write_package(num);
	for (i = 0; i < num; i++) {
		acpigen_write_package(4);
		acpigen_write_integer(gpios[i].type);
		acpigen_write_integer(gpios[i].polarity);
		gpio_num = gpios[i].gpio_num;
#if CONFIG(GENERIC_GPIO_LIB)
		/* Get ACPI pin from GPIO library if available */
		if (gpios[i].gpio_num != CROS_GPIO_VIRTUAL)
			gpio_num = gpio_acpi_pin(gpio_num);
#endif
		acpigen_write_integer(gpio_num);
		acpigen_write_string(gpios[i].device);
		acpigen_pop_len();
	}
	acpigen_pop_len();

	acpigen_pop_len();
}
Beispiel #2
0
static int generate_P_state_entries(int core, int cores_per_package)
{
	int len, len_pss;
	int ratio_min, ratio_max, ratio_turbo, ratio_step, ratio_range_2;
	int coord_type, power_max, power_unit, num_entries;
	int ratio, power, clock, clock_max;
	int vid, vid_turbo, vid_min, vid_max, vid_range_2;
	u32 control_status;
	const struct pattrs *pattrs = pattrs_get();
	msr_t msr;

	/* Inputs from CPU attributes */
	ratio_max = pattrs->iacore_ratios[IACORE_MAX];
	ratio_min = pattrs->iacore_ratios[IACORE_LFM];
	vid_max = pattrs->iacore_vids[IACORE_MAX];
	vid_min = pattrs->iacore_vids[IACORE_LFM];

	/* Hardware coordination of P-states */
	coord_type = HW_ALL;

	/* Max Non-Turbo Frequency */
	clock_max = (ratio_max * pattrs->bclk_khz) / 1000;

	/* Calculate CPU TDP in mW */
	msr = rdmsr(MSR_PKG_POWER_SKU_UNIT);
	power_unit = 1 << (msr.lo & 0xf);
	msr = rdmsr(MSR_PKG_POWER_LIMIT);
	power_max = ((msr.lo & 0x7fff) / power_unit) * 1000;

	/* Write _PCT indicating use of FFixedHW */
	len = acpigen_write_empty_PCT();

	/* Write _PPC with NVS specified limit on supported P-state */
	len += acpigen_write_PPC_NVS();

	/* Write PSD indicating configured coordination type */
	len += acpigen_write_PSD_package(core, 1, coord_type);

	/* Add P-state entries in _PSS table */
	len += acpigen_write_name("_PSS");

	/* Determine ratio points */
	ratio_step = 1;
	num_entries = (ratio_max - ratio_min) / ratio_step;
	while (num_entries > 15) { /* ACPI max is 15 ratios */
		ratio_step <<= 1;
		num_entries >>= 1;
	}

	/* P[T] is Turbo state if enabled */
	if (get_turbo_state() == TURBO_ENABLED) {
		/* _PSS package count including Turbo */
		len_pss = acpigen_write_package(num_entries + 2);

		ratio_turbo = pattrs->iacore_ratios[IACORE_TURBO];
		vid_turbo = pattrs->iacore_vids[IACORE_TURBO];
		control_status = (ratio_turbo << 8) | vid_turbo;

		/* Add entry for Turbo ratio */
		len_pss += acpigen_write_PSS_package(
			clock_max + 1,		/*MHz*/
			power_max,		/*mW*/
			10,			/*lat1*/
			10,			/*lat2*/
			control_status,		/*control*/
			control_status);	/*status*/
	} else {
		/* _PSS package count without Turbo */
		len_pss = acpigen_write_package(num_entries + 1);
		ratio_turbo = ratio_max;
		vid_turbo = vid_max;
	}

	/* First regular entry is max non-turbo ratio */
	control_status = (ratio_max << 8) | vid_max;
	len_pss += acpigen_write_PSS_package(
		clock_max,		/*MHz*/
		power_max,		/*mW*/
		10,			/*lat1*/
		10,			/*lat2*/
		control_status,		/*control */
		control_status);	/*status*/

	/* Set up ratio and vid ranges for VID calculation */
	ratio_range_2 = (ratio_turbo - ratio_min) * 2;
	vid_range_2 = (vid_turbo - vid_min) * 2;

	/* Generate the remaining entries */
	for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
	     ratio >= ratio_min; ratio -= ratio_step) {

		/* Calculate VID for this ratio */
		vid = ((ratio - ratio_min) * vid_range_2) /
			ratio_range_2 + vid_min;
		/* Round up if remainder */
		if (((ratio - ratio_min) * vid_range_2) % ratio_range_2)
			vid++;

		/* Calculate power at this ratio */
		power = calculate_power(power_max, ratio_max, ratio);
		clock = (ratio * pattrs->bclk_khz) / 1000;
		control_status = (ratio << 8) | (vid & 0xff);

		len_pss += acpigen_write_PSS_package(
			clock,			/*MHz*/
			power,			/*mW*/
			10,			/*lat1*/
			10,			/*lat2*/
			control_status,		/*control*/
			control_status);	/*status*/
	}

	/* Fix package length */
	len_pss--;
	acpigen_patch_len(len_pss);

	return len + len_pss;
}