예제 #1
0
static int
pn_probe(device_t dev)
{
	struct pn_softc *sc;
	uint64_t status;
	uint64_t rate;
	struct pcpu *pc;
	u_int sfid, mfid, cfid;

	sc = device_get_softc(dev);
	sc->errata = 0;
	status = rdmsr(MSR_AMDK7_FIDVID_STATUS);

	pc = cpu_get_pcpu(dev);
	if (pc == NULL)
		return (ENODEV);

	cpu_est_clockrate(pc->pc_cpuid, &rate);

	switch (cpu_id & 0xf00) {
	case 0x600:
		sfid = PN7_STA_SFID(status);
		mfid = PN7_STA_MFID(status);
		cfid = PN7_STA_CFID(status);
		sc->pn_type = PN7_TYPE;
		sc->fsb = rate / 100000 / pn7_fid_to_mult[cfid];

		/*
		 * If start FID is different to max FID, then it is a
		 * mobile processor.  If not, it is a low powered desktop
		 * processor.
		 */
		if (PN7_STA_SFID(status) != PN7_STA_MFID(status)) {
			sc->vid_to_volts = pn7_mobile_vid_to_volts;
			device_set_desc(dev, "PowerNow! K7");
		} else {
			sc->vid_to_volts = pn7_desktop_vid_to_volts;
			device_set_desc(dev, "Cool`n'Quiet K7");
		}
		break;

	case 0xf00:
		sfid = PN8_STA_SFID(status);
		mfid = PN8_STA_MFID(status);
		cfid = PN8_STA_CFID(status);
		sc->pn_type = PN8_TYPE;
		sc->vid_to_volts = pn8_vid_to_volts;
		sc->fsb = rate / 100000 / pn8_fid_to_mult[cfid];

		if (PN8_STA_SFID(status) != PN8_STA_MFID(status))
			device_set_desc(dev, "PowerNow! K8");
		else
			device_set_desc(dev, "Cool`n'Quiet K8");
		break;
	default:
		return (ENODEV);
	}

	return (0);
}
예제 #2
0
static int
acpi_px_get(device_t dev, struct cf_setting *set)
{
	struct acpi_perf_softc *sc;
	uint64_t rate;
	int i;
	struct pcpu *pc;

	if (set == NULL)
		return (EINVAL);
	sc = device_get_softc(dev);

	/* If we can't get new states, return immediately. */
	if (sc->info_only)
		return (ENXIO);

	/* If we've set the rate before, use the cached value. */
	if (sc->px_curr_state != CPUFREQ_VAL_UNKNOWN) {
		acpi_px_to_set(dev, &sc->px_states[sc->px_curr_state], set);
		return (0);
	}

	/* Otherwise, estimate and try to match against our settings. */
	pc = cpu_get_pcpu(dev);
	if (pc == NULL)
		return (ENXIO);
	cpu_est_clockrate(pc->pc_cpuid, &rate);
	rate /= 1000000;
	for (i = 0; i < sc->px_count; i++) {
		if (CPUFREQ_CMP(sc->px_states[i].core_freq, rate)) {
			sc->px_curr_state = i;
			acpi_px_to_set(dev, &sc->px_states[i], set);
			break;
		}
	}

	/* No match, give up. */
	if (i == sc->px_count) {
		sc->px_curr_state = CPUFREQ_VAL_UNKNOWN;
		set->freq = CPUFREQ_VAL_UNKNOWN;
	}

	return (0);
}