Lines Matching +full:psci +full:- +full:0
1 /*-
29 * This implements support for ARM's Power State Co-ordination Interface
30 * [PSCI]. The implementation adheres to version 0.2 of the PSCI specification
31 * but also supports v0.1. PSCI standardizes operations such as system reset, CPU
32 * on/off/suspend. PSCI requires a compliant firmware implementation.
34 * The PSCI specification used for this implementation is available at:
39 * - Add support for remaining PSCI calls [this implementation only
70 #include <dev/psci/psci.h>
89 #define USE_ACPI 0
105 .default_version = (1 << 16) | 0,
110 .default_version = (0 << 16) | 2,
115 .default_version = (0 << 16) | 1,
120 {"arm,psci-1.0", (uintptr_t)&psci_v1_0_init_def},
121 {"arm,psci-0.2", (uintptr_t)&psci_v0_2_init_def},
122 {"arm,psci", (uintptr_t)&psci_v0_1_init_def},
123 {NULL, 0}
142 printf("No PSCI/SMCCC call function found\n"); in psci_init()
160 panic("No PSCI/SMCCC call function set"); in psci_def_callfn()
175 "psci",
180 EARLY_DRIVER_MODULE(psci, simplebus, psci_fdt_driver, 0, 0,
182 EARLY_DRIVER_MODULE(psci, ofwbus, psci_fdt_driver, 0, 0,
190 if ((OF_getprop(node, "method", method, sizeof(method))) > 0) { in psci_fdt_get_callfn()
191 if (strcmp(method, "hvc") == 0) in psci_fdt_get_callfn()
193 else if (strcmp(method, "smc") == 0) in psci_fdt_get_callfn()
196 printf("psci: PSCI conduit \"%s\" invalid\n", method); in psci_fdt_get_callfn()
198 printf("psci: PSCI conduit not supplied in the device tree\n"); in psci_fdt_get_callfn()
212 if (ocd->ocd_str == NULL) in psci_fdt_probe()
215 device_set_desc(dev, "ARM Power State Co-ordination Interface Driver"); in psci_fdt_probe()
227 psci_init_def = (struct psci_init_def *)ocd->ocd_data; in psci_fdt_attach()
229 return (psci_attach(dev, psci_init_def->psci_init, in psci_fdt_attach()
230 psci_init_def->default_version)); in psci_fdt_attach()
249 "psci",
254 EARLY_DRIVER_MODULE(psci, acpi, psci_acpi_driver, 0, 0,
265 if (physaddr == 0) in psci_acpi_bootflags()
266 return (0); in psci_acpi_bootflags()
270 printf("psci: Unable to map the FADT\n"); in psci_acpi_bootflags()
271 return (0); in psci_acpi_bootflags()
274 flags = fadt->ArmBootFlags; in psci_acpi_bootflags()
284 if ((flags & ACPI_FADT_PSCI_COMPLIANT) != 0) { in psci_acpi_get_callfn()
285 if ((flags & ACPI_FADT_PSCI_USE_HVC) != 0) in psci_acpi_get_callfn()
290 printf("psci: PSCI conduit not supplied in the device tree\n"); in psci_acpi_get_callfn()
303 if ((flags & ACPI_FADT_PSCI_COMPLIANT) != 0) { in psci_acpi_identify()
305 BUS_PASS_CPU + BUS_PASS_ORDER_FIRST, "psci", -1); in psci_acpi_identify()
318 if ((flags & ACPI_FADT_PSCI_COMPLIANT) == 0) in psci_acpi_probe()
321 device_set_desc(dev, "ARM Power State Co-ordination Interface Driver"); in psci_acpi_probe()
341 KASSERT(psci_init != NULL, ("PSCI init function cannot be NULL")); in psci_attach()
349 sc->smccc_dev = device_add_child(dev, "smccc", DEVICE_UNIT_ANY); in psci_attach()
350 if (sc->smccc_dev == NULL) in psci_attach()
356 return (0); in psci_attach()
364 /* PSCI version wasn't supported in v0.1. */ in _psci_get_version()
365 fnid = sc->psci_fnids[PSCI_FN_VERSION]; in _psci_get_version()
367 return (psci_call(fnid, 0, 0, 0)); in _psci_get_version()
391 for (int i = 0; compat_data[i].ocd_str != NULL; i++) { in psci_fdt_callfn()
392 node = ofw_bus_find_compatible(OF_peer(0), in psci_fdt_callfn()
394 if (node != 0) in psci_fdt_callfn()
397 if (node == 0) in psci_fdt_callfn()
404 return (0); in psci_fdt_callfn()
415 if ((flags & ACPI_FADT_PSCI_COMPLIANT) == 0) in psci_acpi_callfn()
419 return (0); in psci_acpi_callfn()
432 if (error != 0) in psci_find_callfn()
439 if (error != 0) in psci_find_callfn()
457 /* The feature flags were added to PSCI 1.0 */ in psci_features()
458 if (PSCI_VER_MAJOR(psci_softc->psci_version) < 1) in psci_features()
461 return (psci_call(PSCI_FNID_FEATURES, psci_func_id, 0, 0)); in psci_features()
471 fnid = psci_softc->psci_fnids[PSCI_FN_CPU_ON]; in psci_cpu_on()
473 /* PSCI v0.1 and v0.2 both support cpu_on. */ in psci_cpu_on()
480 uint32_t fn = 0; in psci_shutdown()
485 if ((howto & RB_POWEROFF) != 0) in psci_shutdown()
486 fn = psci_softc->psci_fnids[PSCI_FN_SYSTEM_OFF]; in psci_shutdown()
488 psci_call(fn, 0, 0, 0); in psci_shutdown()
496 uint32_t fn = 0; in psci_reboot()
501 if ((howto & RB_HALT) == 0) in psci_reboot()
502 fn = psci_softc->psci_fnids[PSCI_FN_SYSTEM_RESET]; in psci_reboot()
504 psci_call(fn, 0, 0, 0); in psci_reboot()
513 psci_reboot(NULL, 0); in psci_reset()
517 /* Only support PSCI 0.1 on FDT */
527 /* Zero out the function ID table - Is this needed ? */ in psci_v0_1_init()
530 sc->psci_fnids[psci_fn] = 0; in psci_v0_1_init()
532 /* PSCI v0.1 doesn't specify function IDs. Get them from DT */ in psci_v0_1_init()
535 if ((len = OF_getproplen(node, "cpu_suspend")) > 0) { in psci_v0_1_init()
537 sc->psci_fnids[PSCI_FN_CPU_SUSPEND] = psci_fnid; in psci_v0_1_init()
540 if ((len = OF_getproplen(node, "cpu_on")) > 0) { in psci_v0_1_init()
542 sc->psci_fnids[PSCI_FN_CPU_ON] = psci_fnid; in psci_v0_1_init()
545 if ((len = OF_getproplen(node, "cpu_off")) > 0) { in psci_v0_1_init()
547 sc->psci_fnids[PSCI_FN_CPU_OFF] = psci_fnid; in psci_v0_1_init()
550 if ((len = OF_getproplen(node, "migrate")) > 0) { in psci_v0_1_init()
552 sc->psci_fnids[PSCI_FN_MIGRATE] = psci_fnid; in psci_v0_1_init()
555 sc->psci_version = (0 << 16) | 1; in psci_v0_1_init()
557 device_printf(dev, "PSCI version 0.1 available\n"); in psci_v0_1_init()
559 return(0); in psci_v0_1_init()
569 /* PSCI v0.2 specifies explicit function IDs. */ in psci_v0_2_init()
570 sc->psci_fnids[PSCI_FN_VERSION] = PSCI_FNID_VERSION; in psci_v0_2_init()
571 sc->psci_fnids[PSCI_FN_CPU_SUSPEND] = PSCI_FNID_CPU_SUSPEND; in psci_v0_2_init()
572 sc->psci_fnids[PSCI_FN_CPU_OFF] = PSCI_FNID_CPU_OFF; in psci_v0_2_init()
573 sc->psci_fnids[PSCI_FN_CPU_ON] = PSCI_FNID_CPU_ON; in psci_v0_2_init()
574 sc->psci_fnids[PSCI_FN_AFFINITY_INFO] = PSCI_FNID_AFFINITY_INFO; in psci_v0_2_init()
575 sc->psci_fnids[PSCI_FN_MIGRATE] = PSCI_FNID_MIGRATE; in psci_v0_2_init()
576 sc->psci_fnids[PSCI_FN_MIGRATE_INFO_TYPE] = PSCI_FNID_MIGRATE_INFO_TYPE; in psci_v0_2_init()
577 sc->psci_fnids[PSCI_FN_MIGRATE_INFO_UP_CPU] = PSCI_FNID_MIGRATE_INFO_UP_CPU; in psci_v0_2_init()
578 sc->psci_fnids[PSCI_FN_SYSTEM_OFF] = PSCI_FNID_SYSTEM_OFF; in psci_v0_2_init()
579 sc->psci_fnids[PSCI_FN_SYSTEM_RESET] = PSCI_FNID_SYSTEM_RESET; in psci_v0_2_init()
584 * U-Boot PSCI implementation doesn't have psci_get_version() in psci_v0_2_init()
593 printf("PSCI get_version() function is not implemented, " in psci_v0_2_init()
598 sc->psci_version = version; in psci_v0_2_init()
599 if ((PSCI_VER_MAJOR(version) == 0 && PSCI_VER_MINOR(version) == 2) || in psci_v0_2_init()
602 device_printf(dev, "PSCI version 0.2 compatible\n"); in psci_v0_2_init()
615 return (0); in psci_v0_2_init()
618 device_printf(dev, "PSCI version number mismatched with DT\n"); in psci_v0_2_init()