Exemplo n.º 1
0
static int
ichss_probe(device_t dev)
{
	device_t est_dev, perf_dev;
	int error, type;

	/*
	 * If the ACPI perf driver has attached and is not just offering
	 * info, let it manage things.  Also, if Enhanced SpeedStep is
	 * available, don't attach.
	 */
	perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
	if (perf_dev && device_is_attached(perf_dev)) {
		error = CPUFREQ_DRV_TYPE(perf_dev, &type);
		if (error == 0 && (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
			return (ENXIO);
	}
	est_dev = device_find_child(device_get_parent(dev), "est", -1);
	if (est_dev && device_is_attached(est_dev))
		return (ENXIO);

	device_set_desc(dev, "SpeedStep ICH");
	return (-1000);
}
Exemplo n.º 2
0
static int
hwpstate_probe(device_t dev)
{
	struct hwpstate_softc *sc;
	device_t perf_dev;
	uint64_t msr;
	int error, type;

	/*
	 * Only hwpstate0.
	 * It goes well with acpi_throttle.
	 */
	if (device_get_unit(dev) != 0)
		return (ENXIO);

	sc = device_get_softc(dev);
	sc->dev = dev;

	/*
	 * Check if acpi_perf has INFO only flag.
	 */
	perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
	error = TRUE;
	if (perf_dev && device_is_attached(perf_dev)) {
		error = CPUFREQ_DRV_TYPE(perf_dev, &type);
		if (error == 0) {
			if ((type & CPUFREQ_FLAG_INFO_ONLY) == 0) {
				/*
				 * If acpi_perf doesn't have INFO_ONLY flag,
				 * it will take care of pstate transitions.
				 */
				HWPSTATE_DEBUG(dev, "acpi_perf will take care of pstate transitions.\n");
				return (ENXIO);
			} else {
				/*
				 * If acpi_perf has INFO_ONLY flag, (_PCT has FFixedHW)
				 * we can get _PSS info from acpi_perf
				 * without going into ACPI.
				 */
				HWPSTATE_DEBUG(dev, "going to fetch info from acpi_perf\n");
				error = hwpstate_get_info_from_acpi_perf(dev, perf_dev);
			}
		}
	}

	if (error == 0) {
		/*
		 * Now we get _PSS info from acpi_perf without error.
		 * Let's check it.
		 */
		msr = rdmsr(MSR_AMD_10H_11H_LIMIT);
		if (sc->cfnum != 1 + AMD_10H_11H_GET_PSTATE_MAX_VAL(msr)) {
			HWPSTATE_DEBUG(dev, "msr and acpi _PSS count mismatch.\n");
			error = TRUE;
		}
	}

	/*
	 * If we cannot get info from acpi_perf,
	 * Let's get info from MSRs.
	 */
	if (error)
		error = hwpstate_get_info_from_msr(dev);
	if (error)
		return (error);

	device_set_desc(dev, "Cool`n'Quiet 2.0");
	return (0);
}
Exemplo n.º 3
0
static int
pn_decode_acpi(device_t dev, device_t perf_dev)
{
	int i, j, n;
	uint64_t status;
	uint32_t ctrl;
	u_int cpuid;
	u_int regs[4];
	struct pn_softc *sc;
	struct powernow_state state;
	struct cf_setting sets[POWERNOW_MAX_STATES];
	int count = POWERNOW_MAX_STATES;
	int type;
	int rv;

	if (perf_dev == NULL)
		return (ENXIO);

	rv = CPUFREQ_DRV_SETTINGS(perf_dev, sets, &count);
	if (rv)
		return (ENXIO);
	rv = CPUFREQ_DRV_TYPE(perf_dev, &type);
	if (rv || (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
		return (ENXIO);

	sc = device_get_softc(dev);

	do_cpuid(0x80000001, regs);
	cpuid = regs[0];
	if ((cpuid & 0xfff) == 0x760)
		sc->errata |= A0_ERRATA;

	ctrl = 0;
	sc->sgtc = 0;
	for (n = 0, i = 0; i < count; ++i) {
		ctrl = sets[i].spec[PX_SPEC_CONTROL];
		switch (sc->pn_type) {
		case PN7_TYPE:
			state.fid = ACPI_PN7_CTRL_TO_FID(ctrl);
			state.vid = ACPI_PN7_CTRL_TO_VID(ctrl);
			if ((sc->errata & A0_ERRATA) &&
			    (pn7_fid_to_mult[state.fid] % 10) == 5)
				continue;
			state.freq = 100 * pn7_fid_to_mult[state.fid] * sc->fsb;
			break;
		case PN8_TYPE:
			state.fid = ACPI_PN8_CTRL_TO_FID(ctrl);
			state.vid = ACPI_PN8_CTRL_TO_VID(ctrl);
			state.freq = 100 * pn8_fid_to_mult[state.fid] * sc->fsb;
			break;
		}

		state.power = sets[i].power;

		j = n;
		while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) {
			memcpy(&sc->powernow_states[j],
			    &sc->powernow_states[j - 1],
			    sizeof(struct powernow_state));
			--j;
		}
		memcpy(&sc->powernow_states[j], &state,
		    sizeof(struct powernow_state));
		++n;
	}

	sc->powernow_max_states = n;
	state = sc->powernow_states[0];
	status = rdmsr(MSR_AMDK7_FIDVID_STATUS);

	switch (sc->pn_type) {
	case PN7_TYPE:
		sc->sgtc = ACPI_PN7_CTRL_TO_SGTC(ctrl);
		/*
		 * XXX Some bios forget the max frequency!
		 * This maybe indicates we have the wrong tables.  Therefore,
		 * don't implement a quirk, but fallback to BIOS legacy
		 * tables instead.
		 */
		if (PN7_STA_MFID(status) != state.fid) {
			device_printf(dev, "ACPI MAX frequency not found\n");
			return (EINVAL);
		}
		break;
	case PN8_TYPE:
		sc->vst = ACPI_PN8_CTRL_TO_VST(ctrl),
		sc->mvs = ACPI_PN8_CTRL_TO_MVS(ctrl),
		sc->pll = ACPI_PN8_CTRL_TO_PLL(ctrl),
		sc->rvo = ACPI_PN8_CTRL_TO_RVO(ctrl),
		sc->irt = ACPI_PN8_CTRL_TO_IRT(ctrl);
		sc->low = 0; /* XXX */

		/*
		 * powernow k8 supports only one low frequency.
		 */
		if (sc->powernow_max_states >= 2 &&
		    (sc->powernow_states[sc->powernow_max_states - 2].fid < 8))
			return (EINVAL);
		break;
	}

	return (0);
}