Lines Matching +full:set +full:- +full:rate +full:- +full:parent
1 /*-
2 * Copyright (c) 2003-2005 Nate Lawson (SDG)
65 /* Offsets in struct cf_setting array for storing driver-specific values. */
74 struct resource *perf_ctrl; /* Set new performance state. */
83 int info_only; /* Can we set new states? */
95 static void acpi_perf_identify(driver_t *driver, device_t parent);
101 struct cf_setting *set);
107 static int acpi_px_set(device_t dev, const struct cf_setting *set);
108 static int acpi_px_get(device_t dev, struct cf_setting *set);
139 acpi_perf_identify(driver_t *driver, device_t parent) in acpi_perf_identify() argument
145 if (device_find_child(parent, "acpi_perf", DEVICE_UNIT_ANY) != NULL) in acpi_perf_identify()
149 handle = acpi_get_handle(parent); in acpi_perf_identify()
161 if ((dev = BUS_ADD_CHILD(parent, 0, "acpi_perf", in acpi_perf_identify()
162 device_get_unit(parent))) != NULL) in acpi_perf_identify()
165 device_printf(parent, "add acpi_perf child failed\n"); in acpi_perf_identify()
218 sc->dev = dev; in acpi_perf_attach()
219 sc->handle = acpi_get_handle(dev); in acpi_perf_attach()
220 sc->px_max_avail = 0; in acpi_perf_attach()
221 sc->px_curr_state = CPUFREQ_VAL_UNKNOWN; in acpi_perf_attach()
225 if (!sc->info_only) in acpi_perf_attach()
255 status = AcpiEvaluateObject(sc->handle, "_PSS", NULL, &buf); in acpi_perf_evaluate()
264 sc->px_count = pkg->Package.Count; in acpi_perf_evaluate()
266 sc->px_states = malloc(sc->px_count * sizeof(struct acpi_px), in acpi_perf_evaluate()
275 for (i = 0; i < sc->px_count; i++) { in acpi_perf_evaluate()
276 res = &pkg->Package.Elements[i]; in acpi_perf_evaluate()
286 p = &sc->px_states[count].core_freq; in acpi_perf_evaluate()
294 if (sc->px_states[count].core_freq == 0 || in acpi_perf_evaluate()
295 sc->px_states[count].core_freq == 9999 || in acpi_perf_evaluate()
296 sc->px_states[count].core_freq == 0x9999 || in acpi_perf_evaluate()
297 sc->px_states[count].core_freq >= 0xffff) in acpi_perf_evaluate()
302 sc->px_states[count - 1].core_freq == in acpi_perf_evaluate()
303 sc->px_states[count].core_freq) in acpi_perf_evaluate()
308 sc->px_count = count; in acpi_perf_evaluate()
318 status = AcpiEvaluateObject(sc->handle, "_PCT", NULL, &buf); in acpi_perf_evaluate()
329 error = acpi_PkgGas(sc->dev, pkg, 0, &sc->perf_ctrl_type, &sc->px_rid, in acpi_perf_evaluate()
330 &sc->perf_ctrl, 0); in acpi_perf_evaluate()
334 * info, we can't get or set new settings. in acpi_perf_evaluate()
337 sc->info_only = TRUE; in acpi_perf_evaluate()
343 sc->px_rid++; in acpi_perf_evaluate()
345 error = acpi_PkgGas(sc->dev, pkg, 1, &sc->perf_sts_type, &sc->px_rid, in acpi_perf_evaluate()
346 &sc->perf_status, 0); in acpi_perf_evaluate()
349 sc->info_only = TRUE; in acpi_perf_evaluate()
355 sc->px_rid++; in acpi_perf_evaluate()
359 AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, in acpi_perf_evaluate()
365 if (sc->px_states) { in acpi_perf_evaluate()
366 free(sc->px_states, M_ACPIPERF); in acpi_perf_evaluate()
367 sc->px_states = NULL; in acpi_perf_evaluate()
369 if (sc->perf_ctrl) { in acpi_perf_evaluate()
370 bus_release_resource(sc->dev, sc->perf_ctrl_type, 0, in acpi_perf_evaluate()
371 sc->perf_ctrl); in acpi_perf_evaluate()
372 bus_delete_resource(sc->dev, sc->perf_ctrl_type, 0); in acpi_perf_evaluate()
373 sc->perf_ctrl = NULL; in acpi_perf_evaluate()
375 if (sc->perf_status) { in acpi_perf_evaluate()
376 bus_release_resource(sc->dev, sc->perf_sts_type, 1, in acpi_perf_evaluate()
377 sc->perf_status); in acpi_perf_evaluate()
378 bus_delete_resource(sc->dev, sc->perf_sts_type, 1); in acpi_perf_evaluate()
379 sc->perf_status = NULL; in acpi_perf_evaluate()
381 sc->px_rid = 0; in acpi_perf_evaluate()
382 sc->px_count = 0; in acpi_perf_evaluate()
416 * Find the highest currently-supported performance state.
424 struct cf_setting set; in acpi_px_available() local
426 status = acpi_GetInteger(sc->handle, "_PPC", &sc->px_max_avail); in acpi_px_available()
428 /* If the old state is too high, set current state to the new max. */ in acpi_px_available()
430 if (sc->px_curr_state != CPUFREQ_VAL_UNKNOWN && in acpi_px_available()
431 sc->px_curr_state > sc->px_max_avail) { in acpi_px_available()
432 acpi_px_to_set(sc->dev, in acpi_px_available()
433 &sc->px_states[sc->px_max_avail], &set); in acpi_px_available()
434 acpi_px_set(sc->dev, &set); in acpi_px_available()
437 sc->px_max_avail = 0; in acpi_px_available()
441 acpi_px_to_set(device_t dev, struct acpi_px *px, struct cf_setting *set) in acpi_px_to_set() argument
444 if (px == NULL || set == NULL) in acpi_px_to_set()
447 set->freq = px->core_freq; in acpi_px_to_set()
448 set->power = px->power; in acpi_px_to_set()
450 set->lat = px->trans_lat; in acpi_px_to_set()
451 set->volts = CPUFREQ_VAL_UNKNOWN; in acpi_px_to_set()
452 set->dev = dev; in acpi_px_to_set()
453 set->spec[PX_SPEC_CONTROL] = px->ctrl_val; in acpi_px_to_set()
454 set->spec[PX_SPEC_STATUS] = px->sts_val; in acpi_px_to_set()
468 if (*count < sc->px_count - sc->px_max_avail) in acpi_px_settings()
473 for (x = sc->px_max_avail; x < sc->px_count; x++, y++) in acpi_px_settings()
474 acpi_px_to_set(dev, &sc->px_states[x], &sets[y]); in acpi_px_settings()
475 *count = sc->px_count - sc->px_max_avail; in acpi_px_settings()
481 acpi_px_set(device_t dev, const struct cf_setting *set) in acpi_px_set() argument
486 if (set == NULL) in acpi_px_set()
490 /* If we can't set new states, return immediately. */ in acpi_px_set()
491 if (sc->info_only) in acpi_px_set()
495 for (i = sc->px_max_avail; i < sc->px_count; i++) { in acpi_px_set()
496 if (CPUFREQ_CMP(set->freq, sc->px_states[i].core_freq)) in acpi_px_set()
499 if (i == sc->px_count) in acpi_px_set()
503 PX_SET_REG(sc->perf_ctrl, sc->px_states[i].ctrl_val); in acpi_px_set()
510 sts_val = sc->px_states[i].sts_val; in acpi_px_set()
512 status = PX_GET_REG(sc->perf_status); in acpi_px_set()
517 * appears some systems (IBM R32) expect byte-wide access in acpi_px_set()
518 * even though the standard says the register is 32-bit. in acpi_px_set()
527 sc->px_states[i].core_freq); in acpi_px_set()
530 sc->px_curr_state = i; in acpi_px_set()
536 acpi_px_get(device_t dev, struct cf_setting *set) in acpi_px_get() argument
539 uint64_t rate; in acpi_px_get() local
543 if (set == NULL) in acpi_px_get()
548 if (sc->info_only) in acpi_px_get()
551 /* If we've set the rate before, use the cached value. */ in acpi_px_get()
552 if (sc->px_curr_state != CPUFREQ_VAL_UNKNOWN) { in acpi_px_get()
553 acpi_px_to_set(dev, &sc->px_states[sc->px_curr_state], set); in acpi_px_get()
561 cpu_est_clockrate(pc->pc_cpuid, &rate); in acpi_px_get()
562 rate /= 1000000; in acpi_px_get()
563 for (i = 0; i < sc->px_count; i++) { in acpi_px_get()
564 if (CPUFREQ_CMP(sc->px_states[i].core_freq, rate)) { in acpi_px_get()
565 sc->px_curr_state = i; in acpi_px_get()
566 acpi_px_to_set(dev, &sc->px_states[i], set); in acpi_px_get()
572 if (i == sc->px_count) { in acpi_px_get()
573 sc->px_curr_state = CPUFREQ_VAL_UNKNOWN; in acpi_px_get()
574 set->freq = CPUFREQ_VAL_UNKNOWN; in acpi_px_get()
590 if (sc->info_only) in acpi_px_type()