xref: /netbsd/sys/dev/acpi/acpi_cpu_pstate.c (revision a5ba2377)
1 /* $NetBSD: acpi_cpu_pstate.c,v 1.39 2011/02/25 09:16:00 jruoho Exp $ */
2 
3 /*-
4  * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen@iki.fi>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.39 2011/02/25 09:16:00 jruoho Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/evcnt.h>
34 #include <sys/kmem.h>
35 #include <sys/once.h>
36 
37 #include <dev/acpi/acpireg.h>
38 #include <dev/acpi/acpivar.h>
39 #include <dev/acpi/acpi_cpu.h>
40 
41 #define _COMPONENT	 ACPI_BUS_COMPONENT
42 ACPI_MODULE_NAME	 ("acpi_cpu_pstate")
43 
44 static void		 acpicpu_pstate_attach_print(struct acpicpu_softc *);
45 static void		 acpicpu_pstate_attach_evcnt(struct acpicpu_softc *);
46 static void		 acpicpu_pstate_detach_evcnt(struct acpicpu_softc *);
47 static ACPI_STATUS	 acpicpu_pstate_pss(struct acpicpu_softc *);
48 static ACPI_STATUS	 acpicpu_pstate_pss_add(struct acpicpu_pstate *,
49 						ACPI_OBJECT *);
50 static ACPI_STATUS	 acpicpu_pstate_xpss(struct acpicpu_softc *);
51 static ACPI_STATUS	 acpicpu_pstate_xpss_add(struct acpicpu_pstate *,
52 						 ACPI_OBJECT *);
53 static ACPI_STATUS	 acpicpu_pstate_pct(struct acpicpu_softc *);
54 static int		 acpicpu_pstate_max(struct acpicpu_softc *);
55 static int		 acpicpu_pstate_min(struct acpicpu_softc *);
56 static void		 acpicpu_pstate_change(struct acpicpu_softc *);
57 static void		 acpicpu_pstate_reset(struct acpicpu_softc *);
58 static void		 acpicpu_pstate_bios(void);
59 
60 static uint32_t		 acpicpu_pstate_saved = 0;
61 
62 void
63 acpicpu_pstate_attach(device_t self)
64 {
65 	struct acpicpu_softc *sc = device_private(self);
66 	const char *str;
67 	ACPI_HANDLE tmp;
68 	ACPI_STATUS rv;
69 
70 	rv = acpicpu_pstate_pss(sc);
71 
72 	if (ACPI_FAILURE(rv)) {
73 		str = "_PSS";
74 		goto fail;
75 	}
76 
77 	/*
78 	 * Append additional information from the extended _PSS,
79 	 * if available. Note that XPSS can not be used on Intel
80 	 * systems that use either _PDC or _OSC. From the XPSS
81 	 * method specification:
82 	 *
83 	 *   "The platform must not require the use of the
84 	 *    optional _PDC or _OSC methods to coordinate
85 	 *    between the operating system and firmware for
86 	 *    the purposes of enabling specific processor
87 	 *    power management features or implementations."
88 	 */
89 	if (sc->sc_cap == 0) {
90 
91 		rv = acpicpu_pstate_xpss(sc);
92 
93 		if (ACPI_SUCCESS(rv))
94 			sc->sc_flags |= ACPICPU_FLAG_P_XPSS;
95 	}
96 
97 	rv = acpicpu_pstate_pct(sc);
98 
99 	if (ACPI_FAILURE(rv)) {
100 		str = "_PCT";
101 		goto fail;
102 	}
103 
104 	/*
105 	 * The ACPI 3.0 and 4.0 specifications mandate three
106 	 * objects for P-states: _PSS, _PCT, and _PPC. A less
107 	 * strict wording is however used in the earlier 2.0
108 	 * standard, and some systems conforming to ACPI 2.0
109 	 * do not have _PPC, the method for dynamic maximum.
110 	 */
111 	rv = AcpiGetHandle(sc->sc_node->ad_handle, "_PPC", &tmp);
112 
113 	if (ACPI_FAILURE(rv))
114 		aprint_debug_dev(self, "_PPC missing\n");
115 
116 	/*
117 	 * Employ the XPSS structure by filling
118 	 * it with MD information required for FFH.
119 	 */
120 	rv = acpicpu_md_pstate_pss(sc);
121 
122 	if (rv != 0) {
123 		rv = AE_SUPPORT;
124 		goto fail;
125 	}
126 
127 	sc->sc_flags |= ACPICPU_FLAG_P;
128 
129 	acpicpu_pstate_bios();
130 	acpicpu_pstate_reset(sc);
131 	acpicpu_pstate_attach_evcnt(sc);
132 	acpicpu_pstate_attach_print(sc);
133 
134 	return;
135 
136 fail:
137 	switch (rv) {
138 
139 	case AE_NOT_FOUND:
140 		return;
141 
142 	case AE_SUPPORT:
143 		aprint_verbose_dev(self, "P-states not supported\n");
144 		return;
145 
146 	default:
147 		aprint_error_dev(self, "failed to evaluate "
148 		    "%s: %s\n", str, AcpiFormatException(rv));
149 	}
150 }
151 
152 static void
153 acpicpu_pstate_attach_print(struct acpicpu_softc *sc)
154 {
155 	const uint8_t method = sc->sc_pstate_control.reg_spaceid;
156 	struct acpicpu_pstate *ps;
157 	static bool once = false;
158 	const char *str;
159 	uint32_t i;
160 
161 	if (once != false)
162 		return;
163 
164 	str = (method != ACPI_ADR_SPACE_SYSTEM_IO) ? "FFH" : "I/O";
165 
166 	for (i = 0; i < sc->sc_pstate_count; i++) {
167 
168 		ps = &sc->sc_pstate[i];
169 
170 		if (ps->ps_freq == 0)
171 			continue;
172 
173 		aprint_verbose_dev(sc->sc_dev, "P%d: %3s, "
174 		    "lat %3u us, pow %5u mW, %4u MHz\n", i, str,
175 		    ps->ps_latency, ps->ps_power, ps->ps_freq);
176 	}
177 
178 	once = true;
179 }
180 
181 static void
182 acpicpu_pstate_attach_evcnt(struct acpicpu_softc *sc)
183 {
184 	struct acpicpu_pstate *ps;
185 	uint32_t i;
186 
187 	for (i = 0; i < sc->sc_pstate_count; i++) {
188 
189 		ps = &sc->sc_pstate[i];
190 
191 		if (ps->ps_freq == 0)
192 			continue;
193 
194 		(void)snprintf(ps->ps_name, sizeof(ps->ps_name),
195 		    "P%u (%u MHz)", i, ps->ps_freq);
196 
197 		evcnt_attach_dynamic(&ps->ps_evcnt, EVCNT_TYPE_MISC,
198 		    NULL, device_xname(sc->sc_dev), ps->ps_name);
199 	}
200 }
201 
202 int
203 acpicpu_pstate_detach(device_t self)
204 {
205 	struct acpicpu_softc *sc = device_private(self);
206 	static ONCE_DECL(once_detach);
207 	size_t size;
208 	int rv;
209 
210 	if ((sc->sc_flags & ACPICPU_FLAG_P) == 0)
211 		return 0;
212 
213 	rv = RUN_ONCE(&once_detach, acpicpu_md_pstate_stop);
214 
215 	if (rv != 0)
216 		return rv;
217 
218 	size = sc->sc_pstate_count * sizeof(*sc->sc_pstate);
219 
220 	if (sc->sc_pstate != NULL)
221 		kmem_free(sc->sc_pstate, size);
222 
223 	sc->sc_flags &= ~ACPICPU_FLAG_P;
224 	acpicpu_pstate_detach_evcnt(sc);
225 
226 	return 0;
227 }
228 
229 static void
230 acpicpu_pstate_detach_evcnt(struct acpicpu_softc *sc)
231 {
232 	struct acpicpu_pstate *ps;
233 	uint32_t i;
234 
235 	for (i = 0; i < sc->sc_pstate_count; i++) {
236 
237 		ps = &sc->sc_pstate[i];
238 
239 		if (ps->ps_freq != 0)
240 			evcnt_detach(&ps->ps_evcnt);
241 	}
242 }
243 
244 void
245 acpicpu_pstate_start(device_t self)
246 {
247 	struct acpicpu_softc *sc = device_private(self);
248 	struct acpicpu_pstate *ps;
249 	uint32_t i;
250 	int rv;
251 
252 	rv = acpicpu_md_pstate_start(sc);
253 
254 	if (rv != 0)
255 		goto fail;
256 
257 	/*
258 	 * Initialize the state to P0.
259 	 */
260 	for (i = 0, rv = ENXIO; i < sc->sc_pstate_count; i++) {
261 
262 		ps = &sc->sc_pstate[i];
263 
264 		if (ps->ps_freq != 0) {
265 			sc->sc_cold = false;
266 			rv = acpicpu_pstate_set(sc, ps->ps_freq);
267 			break;
268 		}
269 	}
270 
271 	if (rv != 0)
272 		goto fail;
273 
274 	return;
275 
276 fail:
277 	sc->sc_flags &= ~ACPICPU_FLAG_P;
278 
279 	if (rv == EEXIST) {
280 		aprint_error_dev(self, "driver conflicts with existing one\n");
281 		return;
282 	}
283 
284 	aprint_error_dev(self, "failed to start P-states (err %d)\n", rv);
285 }
286 
287 bool
288 acpicpu_pstate_suspend(device_t self)
289 {
290 	struct acpicpu_softc *sc = device_private(self);
291 	struct acpicpu_pstate *ps = NULL;
292 	int32_t i;
293 
294 	mutex_enter(&sc->sc_mtx);
295 	acpicpu_pstate_reset(sc);
296 	mutex_exit(&sc->sc_mtx);
297 
298 	if (acpicpu_pstate_saved != 0)
299 		return true;
300 
301 	/*
302 	 * Following design notes for Windows, we set the highest
303 	 * P-state when entering any of the system sleep states.
304 	 * When resuming, the saved P-state will be restored.
305 	 *
306 	 *	Microsoft Corporation: Windows Native Processor
307 	 *	Performance Control. Version 1.1a, November, 2002.
308 	 */
309 	for (i = sc->sc_pstate_count - 1; i >= 0; i--) {
310 
311 		if (sc->sc_pstate[i].ps_freq != 0) {
312 			ps = &sc->sc_pstate[i];
313 			break;
314 		}
315 	}
316 
317 	if (__predict_false(ps == NULL))
318 		return true;
319 
320 	mutex_enter(&sc->sc_mtx);
321 	acpicpu_pstate_saved = sc->sc_pstate_current;
322 	mutex_exit(&sc->sc_mtx);
323 
324 	if (acpicpu_pstate_saved == ps->ps_freq)
325 		return true;
326 
327 	(void)acpicpu_pstate_set(sc, ps->ps_freq);
328 
329 	return true;
330 }
331 
332 bool
333 acpicpu_pstate_resume(device_t self)
334 {
335 	struct acpicpu_softc *sc = device_private(self);
336 
337 	if (acpicpu_pstate_saved != 0) {
338 		(void)acpicpu_pstate_set(sc, acpicpu_pstate_saved);
339 		acpicpu_pstate_saved = 0;
340 	}
341 
342 	return true;
343 }
344 
345 void
346 acpicpu_pstate_callback(void *aux)
347 {
348 	struct acpicpu_softc *sc;
349 	device_t self = aux;
350 	uint32_t old, new;
351 
352 	sc = device_private(self);
353 
354 	mutex_enter(&sc->sc_mtx);
355 
356 	old = sc->sc_pstate_max;
357 	acpicpu_pstate_change(sc);
358 	new = sc->sc_pstate_max;
359 
360 	if (old == new) {
361 		mutex_exit(&sc->sc_mtx);
362 		return;
363 	}
364 
365 	mutex_exit(&sc->sc_mtx);
366 
367 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "maximum frequency "
368 		"changed from P%u (%u MHz) to P%u (%u MHz)\n",
369 		old, sc->sc_pstate[old].ps_freq, new,
370 		sc->sc_pstate[sc->sc_pstate_max].ps_freq));
371 
372 	(void)acpicpu_pstate_set(sc, sc->sc_pstate[new].ps_freq);
373 }
374 
375 ACPI_STATUS
376 acpicpu_pstate_pss(struct acpicpu_softc *sc)
377 {
378 	struct acpicpu_pstate *ps;
379 	ACPI_OBJECT *obj;
380 	ACPI_BUFFER buf;
381 	ACPI_STATUS rv;
382 	uint32_t count;
383 	uint32_t i, j;
384 
385 	rv = acpi_eval_struct(sc->sc_node->ad_handle, "_PSS", &buf);
386 
387 	if (ACPI_FAILURE(rv))
388 		return rv;
389 
390 	obj = buf.Pointer;
391 
392 	if (obj->Type != ACPI_TYPE_PACKAGE) {
393 		rv = AE_TYPE;
394 		goto out;
395 	}
396 
397 	sc->sc_pstate_count = obj->Package.Count;
398 
399 	if (sc->sc_pstate_count == 0) {
400 		rv = AE_NOT_EXIST;
401 		goto out;
402 	}
403 
404 	if (sc->sc_pstate_count > ACPICPU_P_STATE_MAX) {
405 		rv = AE_LIMIT;
406 		goto out;
407 	}
408 
409 	sc->sc_pstate = kmem_zalloc(sc->sc_pstate_count *
410 	    sizeof(struct acpicpu_pstate), KM_SLEEP);
411 
412 	if (sc->sc_pstate == NULL) {
413 		rv = AE_NO_MEMORY;
414 		goto out;
415 	}
416 
417 	for (count = i = 0; i < sc->sc_pstate_count; i++) {
418 
419 		ps = &sc->sc_pstate[i];
420 		rv = acpicpu_pstate_pss_add(ps, &obj->Package.Elements[i]);
421 
422 		if (ACPI_FAILURE(rv)) {
423 			aprint_error_dev(sc->sc_dev, "failed to add "
424 			    "P-state: %s\n", AcpiFormatException(rv));
425 			ps->ps_freq = 0;
426 			continue;
427 		}
428 
429 		for (j = 0; j < i; j++) {
430 
431 			if (ps->ps_freq >= sc->sc_pstate[j].ps_freq) {
432 				ps->ps_freq = 0;
433 				break;
434 			}
435 		}
436 
437 		if (ps->ps_freq != 0)
438 			count++;
439 	}
440 
441 	rv = (count != 0) ? AE_OK : AE_NOT_EXIST;
442 
443 out:
444 	if (buf.Pointer != NULL)
445 		ACPI_FREE(buf.Pointer);
446 
447 	return rv;
448 }
449 
450 static ACPI_STATUS
451 acpicpu_pstate_pss_add(struct acpicpu_pstate *ps, ACPI_OBJECT *obj)
452 {
453 	ACPI_OBJECT *elm;
454 	int i;
455 
456 	if (obj->Type != ACPI_TYPE_PACKAGE)
457 		return AE_TYPE;
458 
459 	if (obj->Package.Count != 6)
460 		return AE_BAD_DATA;
461 
462 	elm = obj->Package.Elements;
463 
464 	for (i = 0; i < 6; i++) {
465 
466 		if (elm[i].Type != ACPI_TYPE_INTEGER)
467 			return AE_TYPE;
468 
469 		if (elm[i].Integer.Value > UINT32_MAX)
470 			return AE_AML_NUMERIC_OVERFLOW;
471 	}
472 
473 	ps->ps_freq       = elm[0].Integer.Value;
474 	ps->ps_power      = elm[1].Integer.Value;
475 	ps->ps_latency    = elm[2].Integer.Value;
476 	ps->ps_latency_bm = elm[3].Integer.Value;
477 	ps->ps_control    = elm[4].Integer.Value;
478 	ps->ps_status     = elm[5].Integer.Value;
479 
480 	if (ps->ps_freq == 0 || ps->ps_freq > 9999)
481 		return AE_BAD_DECIMAL_CONSTANT;
482 
483 	if (ps->ps_latency == 0 || ps->ps_latency > 1000)
484 		ps->ps_latency = 1;
485 
486 	return AE_OK;
487 }
488 
489 static ACPI_STATUS
490 acpicpu_pstate_xpss(struct acpicpu_softc *sc)
491 {
492 	struct acpicpu_pstate *ps;
493 	ACPI_OBJECT *obj;
494 	ACPI_BUFFER buf;
495 	ACPI_STATUS rv;
496 	uint32_t i = 0;
497 
498 	rv = acpi_eval_struct(sc->sc_node->ad_handle, "XPSS", &buf);
499 
500 	if (ACPI_FAILURE(rv))
501 		goto out;
502 
503 	obj = buf.Pointer;
504 
505 	if (obj->Type != ACPI_TYPE_PACKAGE) {
506 		rv = AE_TYPE;
507 		goto out;
508 	}
509 
510 	if (obj->Package.Count != sc->sc_pstate_count) {
511 		rv = AE_LIMIT;
512 		goto out;
513 	}
514 
515 	while (i < sc->sc_pstate_count) {
516 
517 		ps = &sc->sc_pstate[i];
518 		acpicpu_pstate_xpss_add(ps, &obj->Package.Elements[i]);
519 
520 		i++;
521 	}
522 
523 out:
524 	if (ACPI_FAILURE(rv) && rv != AE_NOT_FOUND)
525 		aprint_error_dev(sc->sc_dev, "failed to evaluate "
526 		    "XPSS: %s\n", AcpiFormatException(rv));
527 
528 	if (buf.Pointer != NULL)
529 		ACPI_FREE(buf.Pointer);
530 
531 	return rv;
532 }
533 
534 static ACPI_STATUS
535 acpicpu_pstate_xpss_add(struct acpicpu_pstate *ps, ACPI_OBJECT *obj)
536 {
537 	ACPI_OBJECT *elm;
538 	int i;
539 
540 	if (obj->Type != ACPI_TYPE_PACKAGE)
541 		return AE_TYPE;
542 
543 	if (obj->Package.Count != 8)
544 		return AE_BAD_DATA;
545 
546 	elm = obj->Package.Elements;
547 
548 	for (i = 0; i < 4; i++) {
549 
550 		if (elm[i].Type != ACPI_TYPE_INTEGER)
551 			return AE_TYPE;
552 
553 		if (elm[i].Integer.Value > UINT32_MAX)
554 			return AE_AML_NUMERIC_OVERFLOW;
555 	}
556 
557 	for (; i < 8; i++) {
558 
559 		if (elm[i].Type != ACPI_TYPE_BUFFER)
560 			return AE_TYPE;
561 
562 		if (elm[i].Buffer.Length != 8)
563 			return AE_LIMIT;
564 	}
565 
566 	/*
567 	 * Only overwrite the elements that were
568 	 * not available from the conventional _PSS.
569 	 */
570 	if (ps->ps_freq == 0)
571 		ps->ps_freq = elm[0].Integer.Value;
572 
573 	if (ps->ps_power == 0)
574 		ps->ps_power = elm[1].Integer.Value;
575 
576 	if (ps->ps_latency == 0)
577 		ps->ps_latency = elm[2].Integer.Value;
578 
579 	if (ps->ps_latency_bm == 0)
580 		ps->ps_latency_bm = elm[3].Integer.Value;
581 
582 	if (ps->ps_control == 0)
583 		ps->ps_control = ACPI_GET64(elm[4].Buffer.Pointer);
584 
585 	if (ps->ps_status == 0)
586 		ps->ps_status = ACPI_GET64(elm[5].Buffer.Pointer);
587 
588 	if (ps->ps_control_mask == 0)
589 		ps->ps_control_mask = ACPI_GET64(elm[6].Buffer.Pointer);
590 
591 	if (ps->ps_status_mask == 0)
592 		ps->ps_status_mask = ACPI_GET64(elm[7].Buffer.Pointer);
593 
594 	ps->ps_flags |= ACPICPU_FLAG_P_XPSS;
595 
596 	if (ps->ps_freq == 0 || ps->ps_freq > 9999)
597 		return AE_BAD_DECIMAL_CONSTANT;
598 
599 	if (ps->ps_latency == 0 || ps->ps_latency > 1000)
600 		ps->ps_latency = 1;
601 
602 	return AE_OK;
603 }
604 
605 ACPI_STATUS
606 acpicpu_pstate_pct(struct acpicpu_softc *sc)
607 {
608 	static const size_t size = sizeof(struct acpicpu_reg);
609 	struct acpicpu_reg *reg[2];
610 	struct acpicpu_pstate *ps;
611 	ACPI_OBJECT *elm, *obj;
612 	ACPI_BUFFER buf;
613 	ACPI_STATUS rv;
614 	uint8_t width;
615 	uint32_t i;
616 
617 	rv = acpi_eval_struct(sc->sc_node->ad_handle, "_PCT", &buf);
618 
619 	if (ACPI_FAILURE(rv))
620 		return rv;
621 
622 	obj = buf.Pointer;
623 
624 	if (obj->Type != ACPI_TYPE_PACKAGE) {
625 		rv = AE_TYPE;
626 		goto out;
627 	}
628 
629 	if (obj->Package.Count != 2) {
630 		rv = AE_LIMIT;
631 		goto out;
632 	}
633 
634 	for (i = 0; i < 2; i++) {
635 
636 		elm = &obj->Package.Elements[i];
637 
638 		if (elm->Type != ACPI_TYPE_BUFFER) {
639 			rv = AE_TYPE;
640 			goto out;
641 		}
642 
643 		if (size > elm->Buffer.Length) {
644 			rv = AE_AML_BAD_RESOURCE_LENGTH;
645 			goto out;
646 		}
647 
648 		reg[i] = (struct acpicpu_reg *)elm->Buffer.Pointer;
649 
650 		switch (reg[i]->reg_spaceid) {
651 
652 		case ACPI_ADR_SPACE_SYSTEM_IO:
653 
654 			if (reg[i]->reg_addr == 0) {
655 				rv = AE_AML_ILLEGAL_ADDRESS;
656 				goto out;
657 			}
658 
659 			width = reg[i]->reg_bitwidth;
660 
661 			if (width + reg[i]->reg_bitoffset > 32) {
662 				rv = AE_AML_BAD_RESOURCE_VALUE;
663 				goto out;
664 			}
665 
666 			if (width != 8 && width != 16 && width != 32) {
667 				rv = AE_AML_BAD_RESOURCE_VALUE;
668 				goto out;
669 			}
670 
671 			break;
672 
673 		case ACPI_ADR_SPACE_FIXED_HARDWARE:
674 
675 			if ((sc->sc_flags & ACPICPU_FLAG_P_XPSS) != 0) {
676 
677 				if (reg[i]->reg_bitwidth != 64) {
678 					rv = AE_AML_BAD_RESOURCE_VALUE;
679 					goto out;
680 				}
681 
682 				if (reg[i]->reg_bitoffset != 0) {
683 					rv = AE_AML_BAD_RESOURCE_VALUE;
684 					goto out;
685 				}
686 
687 				break;
688 			}
689 
690 			if ((sc->sc_flags & ACPICPU_FLAG_P_FFH) == 0) {
691 				rv = AE_SUPPORT;
692 				goto out;
693 			}
694 
695 			break;
696 
697 		default:
698 			rv = AE_AML_INVALID_SPACE_ID;
699 			goto out;
700 		}
701 	}
702 
703 	if (reg[0]->reg_spaceid != reg[1]->reg_spaceid) {
704 		rv = AE_AML_INVALID_SPACE_ID;
705 		goto out;
706 	}
707 
708 	(void)memcpy(&sc->sc_pstate_control, reg[0], size);
709 	(void)memcpy(&sc->sc_pstate_status,  reg[1], size);
710 
711 	if ((sc->sc_flags & ACPICPU_FLAG_P_XPSS) == 0)
712 		goto out;
713 
714 	/*
715 	 * In XPSS the control address can not be zero,
716 	 * but the status address may be. In this case,
717 	 * comparable to T-states, we can ignore the status
718 	 * check during the P-state (FFH) transition.
719 	 */
720 	if (sc->sc_pstate_control.reg_addr == 0) {
721 		rv = AE_AML_BAD_RESOURCE_LENGTH;
722 		goto out;
723 	}
724 
725 	/*
726 	 * If XPSS is present, copy the MSR addresses
727 	 * to the P-state structures for convenience.
728 	 */
729 	for (i = 0; i < sc->sc_pstate_count; i++) {
730 
731 		ps = &sc->sc_pstate[i];
732 
733 		if (ps->ps_freq == 0)
734 			continue;
735 
736 		ps->ps_status_addr  = sc->sc_pstate_status.reg_addr;
737 		ps->ps_control_addr = sc->sc_pstate_control.reg_addr;
738 	}
739 
740 out:
741 	if (buf.Pointer != NULL)
742 		ACPI_FREE(buf.Pointer);
743 
744 	return rv;
745 }
746 
747 static int
748 acpicpu_pstate_max(struct acpicpu_softc *sc)
749 {
750 	ACPI_INTEGER val;
751 	ACPI_STATUS rv;
752 
753 	/*
754 	 * Evaluate the currently highest P-state that can be used.
755 	 * If available, we can use either this state or any lower
756 	 * power (i.e. higher numbered) state from the _PSS object.
757 	 * Note that the return value must match the _OST parameter.
758 	 */
759 	rv = acpi_eval_integer(sc->sc_node->ad_handle, "_PPC", &val);
760 
761 	if (ACPI_SUCCESS(rv) && val < sc->sc_pstate_count) {
762 
763 		if (sc->sc_pstate[val].ps_freq != 0) {
764 			sc->sc_pstate_max = val;
765 			return 0;
766 		}
767 	}
768 
769 	return 1;
770 }
771 
772 static int
773 acpicpu_pstate_min(struct acpicpu_softc *sc)
774 {
775 	ACPI_INTEGER val;
776 	ACPI_STATUS rv;
777 
778 	/*
779 	 * The _PDL object defines the minimum when passive cooling
780 	 * is being performed. If available, we can use the returned
781 	 * state or any higher power (i.e. lower numbered) state.
782 	 */
783 	rv = acpi_eval_integer(sc->sc_node->ad_handle, "_PDL", &val);
784 
785 	if (ACPI_SUCCESS(rv) && val < sc->sc_pstate_count) {
786 
787 		if (sc->sc_pstate[val].ps_freq == 0)
788 			return 1;
789 
790 		if (val >= sc->sc_pstate_max) {
791 			sc->sc_pstate_min = val;
792 			return 0;
793 		}
794 	}
795 
796 	return 1;
797 }
798 
799 static void
800 acpicpu_pstate_change(struct acpicpu_softc *sc)
801 {
802 	static ACPI_STATUS rv = AE_OK;
803 	ACPI_OBJECT_LIST arg;
804 	ACPI_OBJECT obj[2];
805 	static int val = 0;
806 
807 	acpicpu_pstate_reset(sc);
808 
809 	/*
810 	 * Cache the checks as the optional
811 	 * _PDL and _OST are rarely present.
812 	 */
813 	if (val == 0)
814 		val = acpicpu_pstate_min(sc);
815 
816 	arg.Count = 2;
817 	arg.Pointer = obj;
818 
819 	obj[0].Type = ACPI_TYPE_INTEGER;
820 	obj[1].Type = ACPI_TYPE_INTEGER;
821 
822 	obj[0].Integer.Value = ACPICPU_P_NOTIFY;
823 	obj[1].Integer.Value = acpicpu_pstate_max(sc);
824 
825 	if (ACPI_FAILURE(rv))
826 		return;
827 
828 	rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "_OST", &arg, NULL);
829 }
830 
831 static void
832 acpicpu_pstate_reset(struct acpicpu_softc *sc)
833 {
834 
835 	sc->sc_pstate_max = 0;
836 	sc->sc_pstate_min = sc->sc_pstate_count - 1;
837 
838 }
839 
840 static void
841 acpicpu_pstate_bios(void)
842 {
843 	const uint8_t val = AcpiGbl_FADT.PstateControl;
844 	const uint32_t addr = AcpiGbl_FADT.SmiCommand;
845 
846 	if (addr == 0 || val == 0)
847 		return;
848 
849 	(void)AcpiOsWritePort(addr, val, 8);
850 }
851 
852 int
853 acpicpu_pstate_get(struct acpicpu_softc *sc, uint32_t *freq)
854 {
855 	const uint8_t method = sc->sc_pstate_control.reg_spaceid;
856 	struct acpicpu_pstate *ps = NULL;
857 	uint32_t i, val = 0;
858 	uint64_t addr;
859 	uint8_t width;
860 	int rv;
861 
862 	if (__predict_false(sc->sc_cold != false)) {
863 		rv = EBUSY;
864 		goto fail;
865 	}
866 
867 	if (__predict_false((sc->sc_flags & ACPICPU_FLAG_P) == 0)) {
868 		rv = ENODEV;
869 		goto fail;
870 	}
871 
872 	mutex_enter(&sc->sc_mtx);
873 
874 	/*
875 	 * Use the cached value, if available.
876 	 */
877 	if (sc->sc_pstate_current != ACPICPU_P_STATE_UNKNOWN) {
878 		*freq = sc->sc_pstate_current;
879 		mutex_exit(&sc->sc_mtx);
880 		return 0;
881 	}
882 
883 	mutex_exit(&sc->sc_mtx);
884 
885 	switch (method) {
886 
887 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
888 
889 		rv = acpicpu_md_pstate_get(sc, freq);
890 
891 		if (__predict_false(rv != 0))
892 			goto fail;
893 
894 		break;
895 
896 	case ACPI_ADR_SPACE_SYSTEM_IO:
897 
898 		addr  = sc->sc_pstate_status.reg_addr;
899 		width = sc->sc_pstate_status.reg_bitwidth;
900 
901 		(void)AcpiOsReadPort(addr, &val, width);
902 
903 		if (val == 0) {
904 			rv = EIO;
905 			goto fail;
906 		}
907 
908 		for (i = 0; i < sc->sc_pstate_count; i++) {
909 
910 			if (sc->sc_pstate[i].ps_freq == 0)
911 				continue;
912 
913 			if (val == sc->sc_pstate[i].ps_status) {
914 				ps = &sc->sc_pstate[i];
915 				break;
916 			}
917 		}
918 
919 		if (ps == NULL) {
920 			rv = EIO;
921 			goto fail;
922 		}
923 
924 		*freq = ps->ps_freq;
925 		break;
926 
927 	default:
928 		rv = ENOTTY;
929 		goto fail;
930 	}
931 
932 	mutex_enter(&sc->sc_mtx);
933 	sc->sc_pstate_current = *freq;
934 	mutex_exit(&sc->sc_mtx);
935 
936 	return 0;
937 
938 fail:
939 	aprint_error_dev(sc->sc_dev, "failed "
940 	    "to get frequency (err %d)\n", rv);
941 
942 	mutex_enter(&sc->sc_mtx);
943 	*freq = sc->sc_pstate_current = ACPICPU_P_STATE_UNKNOWN;
944 	mutex_exit(&sc->sc_mtx);
945 
946 	return rv;
947 }
948 
949 int
950 acpicpu_pstate_set(struct acpicpu_softc *sc, uint32_t freq)
951 {
952 	const uint8_t method = sc->sc_pstate_control.reg_spaceid;
953 	struct acpicpu_pstate *ps = NULL;
954 	uint32_t i, val;
955 	uint64_t addr;
956 	uint8_t width;
957 	int rv;
958 
959 	if (__predict_false(sc->sc_cold != false)) {
960 		rv = EBUSY;
961 		goto fail;
962 	}
963 
964 	if (__predict_false((sc->sc_flags & ACPICPU_FLAG_P) == 0)) {
965 		rv = ENODEV;
966 		goto fail;
967 	}
968 
969 	mutex_enter(&sc->sc_mtx);
970 
971 	if (sc->sc_pstate_current == freq) {
972 		mutex_exit(&sc->sc_mtx);
973 		return 0;
974 	}
975 
976 	/*
977 	 * Verify that the requested frequency is available.
978 	 *
979 	 * The access needs to be protected since the currently
980 	 * available maximum and minimum may change dynamically.
981 	 */
982 	for (i = sc->sc_pstate_max; i <= sc->sc_pstate_min; i++) {
983 
984 		if (__predict_false(sc->sc_pstate[i].ps_freq == 0))
985 			continue;
986 
987 		if (sc->sc_pstate[i].ps_freq == freq) {
988 			ps = &sc->sc_pstate[i];
989 			break;
990 		}
991 	}
992 
993 	mutex_exit(&sc->sc_mtx);
994 
995 	if (__predict_false(ps == NULL)) {
996 		rv = EINVAL;
997 		goto fail;
998 	}
999 
1000 	switch (method) {
1001 
1002 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
1003 
1004 		rv = acpicpu_md_pstate_set(ps);
1005 
1006 		if (__predict_false(rv != 0))
1007 			goto fail;
1008 
1009 		break;
1010 
1011 	case ACPI_ADR_SPACE_SYSTEM_IO:
1012 
1013 		addr  = sc->sc_pstate_control.reg_addr;
1014 		width = sc->sc_pstate_control.reg_bitwidth;
1015 
1016 		(void)AcpiOsWritePort(addr, ps->ps_control, width);
1017 
1018 		addr  = sc->sc_pstate_status.reg_addr;
1019 		width = sc->sc_pstate_status.reg_bitwidth;
1020 
1021 		/*
1022 		 * Some systems take longer to respond
1023 		 * than the reported worst-case latency.
1024 		 */
1025 		for (i = val = 0; i < ACPICPU_P_STATE_RETRY; i++) {
1026 
1027 			(void)AcpiOsReadPort(addr, &val, width);
1028 
1029 			if (val == ps->ps_status)
1030 				break;
1031 
1032 			DELAY(ps->ps_latency);
1033 		}
1034 
1035 		if (i == ACPICPU_P_STATE_RETRY) {
1036 			rv = EAGAIN;
1037 			goto fail;
1038 		}
1039 
1040 		break;
1041 
1042 	default:
1043 		rv = ENOTTY;
1044 		goto fail;
1045 	}
1046 
1047 	mutex_enter(&sc->sc_mtx);
1048 	ps->ps_evcnt.ev_count++;
1049 	sc->sc_pstate_current = freq;
1050 	mutex_exit(&sc->sc_mtx);
1051 
1052 	return 0;
1053 
1054 fail:
1055 	aprint_error_dev(sc->sc_dev, "failed to set "
1056 	    "frequency to %u (err %d)\n", freq, rv);
1057 
1058 	mutex_enter(&sc->sc_mtx);
1059 	sc->sc_pstate_current = ACPICPU_P_STATE_UNKNOWN;
1060 	mutex_exit(&sc->sc_mtx);
1061 
1062 	return rv;
1063 }
1064