blob: 76cc68d3766029a0fc19f7ff927fa509544fcd78 [file]
// Copyright 2026 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <debug.h>
#include <dev/power/iris/init.h>
#include <dev/psci.h>
#include <pdev/power.h>
namespace {
// Vendor-specific (bit 31) SYSTEM_RESET2 reset type to request a warm reset on Iris.
constexpr uint32_t kVendorSpecificWarmResetType = 0x80000000;
// Reboot modes passed as the cookie in SYSTEM_RESET2, recognized by the bootloader.
enum class RebootMode : uint32_t {
kNormal = 0x00, // Standard boot
kCharge = 0x0A, // Boot into off-mode-charging UI.
kRescue = 0xF9, // Reboot into Rescue mode.
kFastboot = 0xFA, // Reboot into userspace fastbootd.
kBootloader = 0xFC, // Reboot into ABL fastboot mode.
kFactory = 0xFD, // Reboot into Factory testing mode.
kRomRecovery = 0xFE, // Reboot into BootROM recovery mode.
kRecovery = 0xFF, // Reboot into Recovery.
};
const char* ToString(RebootMode cookie) {
switch (cookie) {
case RebootMode::kNormal:
return "Normal";
case RebootMode::kCharge:
return "Charge";
case RebootMode::kRescue:
return "Rescue";
case RebootMode::kFastboot:
return "Fastboot";
case RebootMode::kBootloader:
return "Bootloader";
case RebootMode::kFactory:
return "Factory";
case RebootMode::kRomRecovery:
return "RomRecovery";
case RebootMode::kRecovery:
return "Recovery";
}
return "Unknown";
}
zx_status_t iris_reboot(power_reboot_flags flags) {
RebootMode cookie;
switch (flags) {
case power_reboot_flags::REBOOT_BOOTLOADER:
cookie = RebootMode::kBootloader;
break;
case power_reboot_flags::REBOOT_RECOVERY:
cookie = RebootMode::kRecovery;
break;
case power_reboot_flags::REBOOT_NORMAL:
cookie = RebootMode::kNormal;
break;
}
dprintf(INFO, "Iris reboot: flags %u, cookie %#x (%s)\n", static_cast<uint32_t>(flags),
static_cast<uint32_t>(cookie), ToString(cookie));
return psci_system_reset2_raw(kVendorSpecificWarmResetType, static_cast<uint32_t>(cookie));
}
const struct pdev_power_ops iris_power_ops = {
.reboot = iris_reboot,
.shutdown = psci_system_off,
.cpu_off = psci_cpu_off,
.cpu_on = psci_cpu_on,
.get_cpu_state = psci_get_cpu_state,
};
} // namespace
void iris_power_init_early() {
dprintf(INFO, "POWER: registering iris power hooks\n");
pdev_register_power(&iris_power_ops);
}