p4tcc.c revision 181691
167754Smsmith/*-
267754Smsmith * Copyright (c) 2005 Nate Lawson
367754Smsmith * All rights reserved.
467754Smsmith *
567754Smsmith * Redistribution and use in source and binary forms, with or without
667754Smsmith * modification, are permitted provided that the following conditions
767754Smsmith * are met:
867754Smsmith * 1. Redistributions of source code must retain the above copyright
967754Smsmith *    notice, this list of conditions and the following disclaimer.
1067754Smsmith * 2. Redistributions in binary form must reproduce the above copyright
11202771Sjkim *    notice, this list of conditions and the following disclaimer in the
1270243Smsmith *    documentation and/or other materials provided with the distribution.
1367754Smsmith *
1467754Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1567754Smsmith * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1667754Smsmith * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1767754Smsmith * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1867754Smsmith * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1967754Smsmith * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2067754Smsmith * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2167754Smsmith * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2267754Smsmith * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2367754Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2467754Smsmith * SUCH DAMAGE.
2567754Smsmith */
2667754Smsmith
2767754Smsmith/*
2867754Smsmith * Throttle clock frequency by using the thermal control circuit.  This
2967754Smsmith * operates independently of SpeedStep and ACPI throttling and is supported
3067754Smsmith * on Pentium 4 and later models (feature TM).
3167754Smsmith *
3267754Smsmith * Reference:  Intel Developer's manual v.3 #245472-012
3367754Smsmith *
3467754Smsmith * The original version of this driver was written by Ted Unangst for
3567754Smsmith * OpenBSD and imported by Maxim Sobolev.  It was rewritten by Nate Lawson
3667754Smsmith * for use with the cpufreq framework.
3767754Smsmith */
3867754Smsmith
3967754Smsmith#include <sys/cdefs.h>
4067754Smsmith__FBSDID("$FreeBSD: head/sys/i386/cpufreq/p4tcc.c 181691 2008-08-13 16:09:40Z jhb $");
4167754Smsmith
4267754Smsmith#include <sys/param.h>
4367754Smsmith#include <sys/systm.h>
4467754Smsmith#include <sys/bus.h>
4567754Smsmith#include <sys/cpu.h>
4667754Smsmith#include <sys/kernel.h>
4767754Smsmith#include <sys/module.h>
4867754Smsmith
4967754Smsmith#include <machine/md_var.h>
5067754Smsmith#include <machine/specialreg.h>
5167754Smsmith
5267754Smsmith#include "cpufreq_if.h"
5367754Smsmith
5467754Smsmith#include <contrib/dev/acpica/acpi.h>
5567754Smsmith#include <dev/acpica/acpivar.h>
5667754Smsmith#include "acpi_if.h"
5767754Smsmith
5867754Smsmithstruct p4tcc_softc {
5967754Smsmith	device_t	dev;
6067754Smsmith	int		set_count;
6167754Smsmith	int		lowest_val;
6267754Smsmith	int		auto_mode;
6367754Smsmith};
6467754Smsmith
6567754Smsmith#define TCC_NUM_SETTINGS	8
6667754Smsmith
6767754Smsmith#define TCC_ENABLE_ONDEMAND	(1<<4)
6867754Smsmith#define TCC_REG_OFFSET		1
6967754Smsmith#define TCC_SPEED_PERCENT(x)	((10000 * (x)) / TCC_NUM_SETTINGS)
7067754Smsmith
7167754Smsmithstatic int	p4tcc_features(driver_t *driver, u_int *features);
7267754Smsmithstatic void	p4tcc_identify(driver_t *driver, device_t parent);
7367754Smsmithstatic int	p4tcc_probe(device_t dev);
7467754Smsmithstatic int	p4tcc_attach(device_t dev);
7567754Smsmithstatic int	p4tcc_settings(device_t dev, struct cf_setting *sets,
7667754Smsmith		    int *count);
7767754Smsmithstatic int	p4tcc_set(device_t dev, const struct cf_setting *set);
7867754Smsmithstatic int	p4tcc_get(device_t dev, struct cf_setting *set);
7967754Smsmithstatic int	p4tcc_type(device_t dev, int *type);
8067754Smsmith
8167754Smsmithstatic device_method_t p4tcc_methods[] = {
8267754Smsmith	/* Device interface */
8367754Smsmith	DEVMETHOD(device_identify,	p4tcc_identify),
8467754Smsmith	DEVMETHOD(device_probe,		p4tcc_probe),
8567754Smsmith	DEVMETHOD(device_attach,	p4tcc_attach),
8667754Smsmith
8767754Smsmith	/* cpufreq interface */
8867754Smsmith	DEVMETHOD(cpufreq_drv_set,	p4tcc_set),
8967754Smsmith	DEVMETHOD(cpufreq_drv_get,	p4tcc_get),
9067754Smsmith	DEVMETHOD(cpufreq_drv_type,	p4tcc_type),
9167754Smsmith	DEVMETHOD(cpufreq_drv_settings,	p4tcc_settings),
9267754Smsmith
9367754Smsmith	/* ACPI interface */
9467754Smsmith	DEVMETHOD(acpi_get_features,	p4tcc_features),
9567754Smsmith
9667754Smsmith	{0, 0}
9767754Smsmith};
9867754Smsmith
9967754Smsmithstatic driver_t p4tcc_driver = {
10067754Smsmith	"p4tcc",
10167754Smsmith	p4tcc_methods,
10267754Smsmith	sizeof(struct p4tcc_softc),
10367754Smsmith};
10467754Smsmith
10567754Smsmithstatic devclass_t p4tcc_devclass;
10667754SmsmithDRIVER_MODULE(p4tcc, cpu, p4tcc_driver, p4tcc_devclass, 0, 0);
10767754Smsmith
10867754Smsmithstatic int
10967754Smsmithp4tcc_features(driver_t *driver, u_int *features)
11067754Smsmith{
11167754Smsmith
11267754Smsmith	/* Notify the ACPI CPU that we support direct access to MSRs */
11367754Smsmith	*features = ACPI_CAP_THR_MSRS;
11467754Smsmith	return (0);
11567754Smsmith}
11667754Smsmith
11767754Smsmithstatic void
11867754Smsmithp4tcc_identify(driver_t *driver, device_t parent)
119193341Sjkim{
120193341Sjkim
121193341Sjkim	if ((cpu_feature & (CPUID_ACPI | CPUID_TM)) != (CPUID_ACPI | CPUID_TM))
12267754Smsmith		return;
12367754Smsmith
12477424Smsmith	/* Make sure we're not being doubly invoked. */
12591116Smsmith	if (device_find_child(parent, "p4tcc", -1) != NULL)
12667754Smsmith		return;
127151937Sjkim
128123315Snjl	/*
129151937Sjkim	 * We attach a p4tcc child for every CPU since settings need to
130151937Sjkim	 * be performed on every CPU in the SMP case.  See section 13.15.3
131151937Sjkim	 * of the IA32 Intel Architecture Software Developer's Manual,
132151937Sjkim	 * Volume 3, for more info.
133151937Sjkim	 */
134151937Sjkim	if (BUS_ADD_CHILD(parent, 10, "p4tcc", -1) == NULL)
135151937Sjkim		device_printf(parent, "add p4tcc child failed\n");
136151937Sjkim}
137151937Sjkim
138151937Sjkimstatic int
139151937Sjkimp4tcc_probe(device_t dev)
140151937Sjkim{
141151937Sjkim
142151937Sjkim	if (resource_disabled("p4tcc", 0))
143102550Siwasaki		return (ENXIO);
14477424Smsmith
14567754Smsmith	device_set_desc(dev, "CPU Frequency Thermal Control");
14687031Smsmith	return (0);
14787031Smsmith}
148151937Sjkim
14987031Smsmithstatic int
15087031Smsmithp4tcc_attach(device_t dev)
151151937Sjkim{
152151937Sjkim	struct p4tcc_softc *sc;
15387031Smsmith	struct cf_setting set;
15487031Smsmith
15587031Smsmith	sc = device_get_softc(dev);
15687031Smsmith	sc->dev = dev;
15787031Smsmith	sc->set_count = TCC_NUM_SETTINGS;
15887031Smsmith
15987031Smsmith	/*
16087031Smsmith	 * On boot, the TCC is usually in Automatic mode where reading the
16187031Smsmith	 * current performance level is likely to produce bogus results.
162193267Sjkim	 * We record that state here and don't trust the contents of the
163151937Sjkim	 * status MSR until we've set it ourselves.
164151937Sjkim	 */
165167802Sjkim	sc->auto_mode = TRUE;
16687031Smsmith
16787031Smsmith	/*
16887031Smsmith	 * XXX: After a cursory glance at various Intel specification
16987031Smsmith	 * XXX: updates it seems like these tests for errata is bogus.
17087031Smsmith	 * XXX: As far as I can tell, the failure mode is benign, in
17187031Smsmith	 * XXX: that cpus with no errata will have their bottom two
17287031Smsmith	 * XXX: STPCLK# rates disabled, so rather than waste more time
173123315Snjl	 * XXX: hunting down intel docs, just document it and punt. /phk
17487031Smsmith	 */
17587031Smsmith	switch (cpu_id & 0xff) {
17687031Smsmith	case 0x22:
17791116Smsmith	case 0x24:
17887031Smsmith	case 0x25:
179151937Sjkim	case 0x27:
180151937Sjkim	case 0x29:
181151937Sjkim		/*
182151937Sjkim		 * These CPU models hang when set to 12.5%.
183151937Sjkim		 * See Errata O50, P44, and Z21.
184151937Sjkim		 */
185151937Sjkim		sc->set_count -= 1;
18691116Smsmith		break;
18791116Smsmith	case 0x07:	/* errata N44 and P18 */
18891116Smsmith	case 0x0a:
18991116Smsmith	case 0x12:
19091116Smsmith	case 0x13:
19191116Smsmith		/*
19287031Smsmith		 * These CPU models hang when set to 12.5% or 25%.
19387031Smsmith		 * See Errata N44 and P18l.
19487031Smsmith		 */
19587031Smsmith		sc->set_count -= 2;
19687031Smsmith		break;
19787031Smsmith	}
19887031Smsmith	sc->lowest_val = TCC_NUM_SETTINGS - sc->set_count + 1;
19987031Smsmith
20067754Smsmith	/*
20167754Smsmith	 * Before we finish attach, switch to 100%.  It's possible the BIOS
20267754Smsmith	 * set us to a lower rate.  The user can override this after boot.
20367754Smsmith	 */
20467754Smsmith	set.freq = 10000;
20567754Smsmith	p4tcc_set(dev, &set);
20667754Smsmith
207151937Sjkim	cpufreq_register(dev);
208151937Sjkim	return (0);
20967754Smsmith}
21067754Smsmith
21167754Smsmithstatic int
21277424Smsmithp4tcc_settings(device_t dev, struct cf_setting *sets, int *count)
21367754Smsmith{
214114237Snjl	struct p4tcc_softc *sc;
21567754Smsmith	int i, val;
21667754Smsmith
217114237Snjl	sc = device_get_softc(dev);
21867754Smsmith	if (sets == NULL || count == NULL)
21967754Smsmith		return (EINVAL);
22067754Smsmith	if (*count < sc->set_count)
22167754Smsmith		return (E2BIG);
222167802Sjkim
22367754Smsmith	/* Return a list of valid settings for this driver. */
22483174Smsmith	memset(sets, CPUFREQ_VAL_UNKNOWN, sizeof(*sets) * sc->set_count);
22567754Smsmith	val = TCC_NUM_SETTINGS;
22667754Smsmith	for (i = 0; i < sc->set_count; i++, val--) {
22767754Smsmith		sets[i].freq = TCC_SPEED_PERCENT(val);
22867754Smsmith		sets[i].dev = dev;
229114237Snjl	}
23067754Smsmith	*count = sc->set_count;
23167754Smsmith
23267754Smsmith	return (0);
23367754Smsmith}
234114237Snjl
235114237Snjlstatic int
236114237Snjlp4tcc_set(device_t dev, const struct cf_setting *set)
23767754Smsmith{
23867754Smsmith	struct p4tcc_softc *sc;
23967754Smsmith	uint64_t mask, msr;
24077424Smsmith	int val;
24167754Smsmith
24267754Smsmith	if (set == NULL)
24367754Smsmith		return (EINVAL);
244151937Sjkim	sc = device_get_softc(dev);
24567754Smsmith
24667754Smsmith	/*
247151937Sjkim	 * Validate requested state converts to a setting that is an integer
24867754Smsmith	 * from [sc->lowest_val .. TCC_NUM_SETTINGS].
249151937Sjkim	 */
250151937Sjkim	val = set->freq * TCC_NUM_SETTINGS / 10000;
25167754Smsmith	if (val * 10000 != set->freq * TCC_NUM_SETTINGS ||
25267754Smsmith	    val < sc->lowest_val || val > TCC_NUM_SETTINGS)
25367754Smsmith		return (EINVAL);
25477424Smsmith
25567754Smsmith	/*
25667754Smsmith	 * Read the current register and mask off the old setting and
25767754Smsmith	 * On-Demand bit.  If the new val is < 100%, set it and the On-Demand
25867754Smsmith	 * bit, otherwise just return to Automatic mode.
25967754Smsmith	 */
26067754Smsmith	msr = rdmsr(MSR_THERM_CONTROL);
26167754Smsmith	mask = (TCC_NUM_SETTINGS - 1) << TCC_REG_OFFSET;
26267754Smsmith	msr &= ~(mask | TCC_ENABLE_ONDEMAND);
26367754Smsmith	if (val < TCC_NUM_SETTINGS)
26467754Smsmith		msr |= (val << TCC_REG_OFFSET) | TCC_ENABLE_ONDEMAND;
26567754Smsmith	wrmsr(MSR_THERM_CONTROL, msr);
26691116Smsmith
26791116Smsmith	/*
26867754Smsmith	 * Record whether we're now in Automatic or On-Demand mode.  We have
269107325Siwasaki	 * to cache this since there is no reliable way to check if TCC is in
27085756Smsmith	 * Automatic mode (i.e., at 100% or possibly 50%).  Reading bit 4 of
27167754Smsmith	 * the ACPI Thermal Monitor Control Register produces 0 no matter
27267754Smsmith	 * what the current mode.
273167802Sjkim	 */
27482367Smsmith	if (msr & TCC_ENABLE_ONDEMAND)
27582367Smsmith		sc->auto_mode = TRUE;
276107325Siwasaki	else
27767754Smsmith		sc->auto_mode = FALSE;
27867754Smsmith
27967754Smsmith	return (0);
28067754Smsmith}
28167754Smsmith
28267754Smsmithstatic int
28367754Smsmithp4tcc_get(device_t dev, struct cf_setting *set)
28467754Smsmith{
28582367Smsmith	struct p4tcc_softc *sc;
28667754Smsmith	uint64_t msr;
28767754Smsmith	int val;
28867754Smsmith
289200553Sjkim	if (set == NULL)
290193267Sjkim		return (EINVAL);
291193267Sjkim	sc = device_get_softc(dev);
292193267Sjkim
293193267Sjkim	/*
294193267Sjkim	 * Read the current register and extract the current setting.  If
295193267Sjkim	 * in automatic mode, assume we're at TCC_NUM_SETTINGS (100%).
296193267Sjkim	 *
297107325Siwasaki	 * XXX This is not completely reliable since at high temperatures
298107325Siwasaki	 * the CPU may be automatically throttling to 50% but it's the best
29967754Smsmith	 * we can do.
30067754Smsmith	 */
301151937Sjkim	if (!sc->auto_mode) {
30267754Smsmith		msr = rdmsr(MSR_THERM_CONTROL);
30367754Smsmith		val = (msr >> TCC_REG_OFFSET) & (TCC_NUM_SETTINGS - 1);
30467754Smsmith	} else
30567754Smsmith		val = TCC_NUM_SETTINGS;
30667754Smsmith
307151937Sjkim	memset(set, CPUFREQ_VAL_UNKNOWN, sizeof(*set));
308151937Sjkim	set->freq = TCC_SPEED_PERCENT(val);
309151937Sjkim	set->dev = dev;
31067754Smsmith
311151937Sjkim	return (0);
31267754Smsmith}
313151937Sjkim
31467754Smsmithstatic int
315151937Sjkimp4tcc_type(device_t dev, int *type)
316151937Sjkim{
317204773Sjkim
318151937Sjkim	if (type == NULL)
31967754Smsmith		return (EINVAL);
320151937Sjkim
32167754Smsmith	*type = CPUFREQ_TYPE_RELATIVE;
32267754Smsmith	return (0);
323193267Sjkim}
324193267Sjkim