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");
160 panic("No PSCI/SMCCC call function set");
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) {
191 if (strcmp(method, "hvc") == 0)
193 else if (strcmp(method, "smc") == 0)
196 printf("psci: PSCI conduit \"%s\" invalid\n", method);
198 printf("psci: PSCI conduit not supplied in the device tree\n");
212 if (ocd->ocd_str == NULL)
215 device_set_desc(dev, "ARM Power State Co-ordination Interface Driver");
227 psci_init_def = (struct psci_init_def *)ocd->ocd_data;
229 return (psci_attach(dev, psci_init_def->psci_init,
230 psci_init_def->default_version));
249 "psci",
254 EARLY_DRIVER_MODULE(psci, acpi, psci_acpi_driver, 0, 0,
265 if (physaddr == 0)
266 return (0);
270 printf("psci: Unable to map the FADT\n");
271 return (0);
274 flags = fadt->ArmBootFlags;
284 if ((flags & ACPI_FADT_PSCI_COMPLIANT) != 0) {
285 if ((flags & ACPI_FADT_PSCI_USE_HVC) != 0)
290 printf("psci: PSCI conduit not supplied in the device tree\n");
303 if ((flags & ACPI_FADT_PSCI_COMPLIANT) != 0) {
305 BUS_PASS_CPU + BUS_PASS_ORDER_FIRST, "psci", -1);
318 if ((flags & ACPI_FADT_PSCI_COMPLIANT) == 0)
321 device_set_desc(dev, "ARM Power State Co-ordination Interface Driver");
341 KASSERT(psci_init != NULL, ("PSCI init function cannot be NULL"));
349 sc->smccc_dev = device_add_child(dev, "smccc", DEVICE_UNIT_ANY);
350 if (sc->smccc_dev == NULL)
356 return (0);
364 /* PSCI version wasn't supported in v0.1. */
365 fnid = sc->psci_fnids[PSCI_FN_VERSION];
367 return (psci_call(fnid, 0, 0, 0));
391 for (int i = 0; compat_data[i].ocd_str != NULL; i++) {
392 node = ofw_bus_find_compatible(OF_peer(0),
394 if (node != 0)
397 if (node == 0)
404 return (0);
415 if ((flags & ACPI_FADT_PSCI_COMPLIANT) == 0)
419 return (0);
432 if (error != 0)
439 if (error != 0)
457 /* The feature flags were added to PSCI 1.0 */
458 if (PSCI_VER_MAJOR(psci_softc->psci_version) < 1)
461 return (psci_call(PSCI_FNID_FEATURES, psci_func_id, 0, 0));
471 fnid = psci_softc->psci_fnids[PSCI_FN_CPU_ON];
473 /* PSCI v0.1 and v0.2 both support cpu_on. */
480 uint32_t fn = 0;
485 if ((howto & RB_POWEROFF) != 0)
486 fn = psci_softc->psci_fnids[PSCI_FN_SYSTEM_OFF];
488 psci_call(fn, 0, 0, 0);
496 uint32_t fn = 0;
501 if ((howto & RB_HALT) == 0)
502 fn = psci_softc->psci_fnids[PSCI_FN_SYSTEM_RESET];
504 psci_call(fn, 0, 0, 0);
513 psci_reboot(NULL, 0);
517 /* Only support PSCI 0.1 on FDT */
527 /* Zero out the function ID table - Is this needed ? */
530 sc->psci_fnids[psci_fn] = 0;
532 /* PSCI v0.1 doesn't specify function IDs. Get them from DT */
535 if ((len = OF_getproplen(node, "cpu_suspend")) > 0) {
537 sc->psci_fnids[PSCI_FN_CPU_SUSPEND] = psci_fnid;
540 if ((len = OF_getproplen(node, "cpu_on")) > 0) {
542 sc->psci_fnids[PSCI_FN_CPU_ON] = psci_fnid;
545 if ((len = OF_getproplen(node, "cpu_off")) > 0) {
547 sc->psci_fnids[PSCI_FN_CPU_OFF] = psci_fnid;
550 if ((len = OF_getproplen(node, "migrate")) > 0) {
552 sc->psci_fnids[PSCI_FN_MIGRATE] = psci_fnid;
555 sc->psci_version = (0 << 16) | 1;
557 device_printf(dev, "PSCI version 0.1 available\n");
559 return(0);
569 /* PSCI v0.2 specifies explicit function IDs. */
570 sc->psci_fnids[PSCI_FN_VERSION] = PSCI_FNID_VERSION;
571 sc->psci_fnids[PSCI_FN_CPU_SUSPEND] = PSCI_FNID_CPU_SUSPEND;
572 sc->psci_fnids[PSCI_FN_CPU_OFF] = PSCI_FNID_CPU_OFF;
573 sc->psci_fnids[PSCI_FN_CPU_ON] = PSCI_FNID_CPU_ON;
574 sc->psci_fnids[PSCI_FN_AFFINITY_INFO] = PSCI_FNID_AFFINITY_INFO;
575 sc->psci_fnids[PSCI_FN_MIGRATE] = PSCI_FNID_MIGRATE;
576 sc->psci_fnids[PSCI_FN_MIGRATE_INFO_TYPE] = PSCI_FNID_MIGRATE_INFO_TYPE;
577 sc->psci_fnids[PSCI_FN_MIGRATE_INFO_UP_CPU] = PSCI_FNID_MIGRATE_INFO_UP_CPU;
578 sc->psci_fnids[PSCI_FN_SYSTEM_OFF] = PSCI_FNID_SYSTEM_OFF;
579 sc->psci_fnids[PSCI_FN_SYSTEM_RESET] = PSCI_FNID_SYSTEM_RESET;
584 * U-Boot PSCI implementation doesn't have psci_get_version()
593 printf("PSCI get_version() function is not implemented, "
598 sc->psci_version = version;
599 if ((PSCI_VER_MAJOR(version) == 0 && PSCI_VER_MINOR(version) == 2) ||
602 device_printf(dev, "PSCI version 0.2 compatible\n");
615 return (0);
618 device_printf(dev, "PSCI version number mismatched with DT\n");