| // Copyright 2021 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 <dev/hdcp/amlogic_s912/init.h> |
| #include <dev/hw_rng/amlogic_rng/init.h> |
| #include <dev/hw_rng/qcom_rng/init.h> |
| #include <dev/hw_watchdog/generic32/init.h> |
| #include <dev/init.h> |
| #include <dev/interrupt/arm_gicv2_init.h> |
| #include <dev/interrupt/arm_gicv3_init.h> |
| #include <dev/power/moonflower/init.h> |
| #include <dev/power/motmot/init.h> |
| #include <dev/psci.h> |
| #include <dev/timer/arm_generic.h> |
| #include <dev/timer/armv7_mmio_timer.h> |
| #include <ktl/type_traits.h> |
| #include <ktl/variant.h> |
| #include <phys/arch/arch-handoff.h> |
| |
| #include <ktl/enforce.h> |
| |
| namespace { |
| |
| // Overloads to satisfy the degenerate 'no config present' case in |
| // `ktl::visit(..., arch_handoff.gic_driver)` below. Related overloads defined |
| // in <dev/interrupt/arm_gicv{2,3}_init.h>. |
| void ArmGicInitEarly(const ktl::monostate& no_config) {} |
| void ArmGicInitLate(const ktl::monostate& no_config) {} |
| |
| } // namespace |
| |
| void PlatformDriverHandoffEarly(const ArchPhysHandoff& arch_handoff) { |
| // Configure the GIC first so that the remaining drivers can freely register |
| // interrupt handlers. |
| ktl::visit([](const auto& config) { ArmGicInitEarly(config); }, arch_handoff.gic_driver); |
| |
| if (arch_handoff.generic32_watchdog_driver) { |
| Generic32BitWatchdogEarlyInit(arch_handoff.generic32_watchdog_driver.value()); |
| } |
| |
| if (arch_handoff.generic_timer_driver) { |
| ArmGenericTimerInit(arch_handoff.generic_timer_driver.value()); |
| } |
| |
| // Initialize psci before the other power drivers, as they may decide to |
| // override the psci's power registration. |
| if (arch_handoff.psci_driver) { |
| PsciInit(arch_handoff.psci_driver.value(), arch_handoff.psci_cpu_suspend_driver.get()); |
| } |
| |
| if (arch_handoff.motmot_power_driver) { |
| motmot_power_init_early(); |
| } |
| |
| if (arch_handoff.moonflower_power_driver) { |
| moonflower_power_init_early(); |
| } |
| } |
| |
| void PlatformDriverHandoffLate(const ArchPhysHandoff& arch_handoff) { |
| // First, as above. |
| ktl::visit([](const auto& config) { ArmGicInitLate(config); }, arch_handoff.gic_driver); |
| |
| // TODO(johngro): we are currently initing the mmio timers rather late in the |
| // boot because we currently use the heap in the driver. Consider moving to |
| // static allocation so we can init early instead. |
| if (arch_handoff.generic_timer_mmio_driver) { |
| Armv7MmioTimer::Init(arch_handoff.generic_timer_mmio_driver.value()); |
| } |
| |
| if (arch_handoff.amlogic_hdcp_driver) { |
| AmlogicS912HdcpInit(arch_handoff.amlogic_hdcp_driver.value()); |
| } |
| |
| if (arch_handoff.amlogic_rng_driver) { |
| AmlogicRngInit(arch_handoff.amlogic_rng_driver.value()); |
| } |
| |
| if (arch_handoff.qcom_rng_driver) { |
| QcomRngInit(arch_handoff.qcom_rng_driver.value()); |
| } |
| |
| if (arch_handoff.generic32_watchdog_driver) { |
| Generic32BitWatchdogLateInit(); |
| } |
| } |