From 3f75a92fd294df87b42ed9c038d3059eb949973d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 7 May 2019 09:32:37 -0700 Subject: [PATCH] boot: implement pmc wake config init (todo: events) --- stratosphere/boot/source/boot_main.cpp | 5 +- .../boot/source/boot_registers_pmc.hpp | 3 ++ .../boot/source/boot_wake_control_configs.hpp | 41 +++++++++++++++ stratosphere/boot/source/boot_wake_pins.cpp | 51 +++++++++++++++++++ 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 stratosphere/boot/source/boot_wake_control_configs.hpp create mode 100644 stratosphere/boot/source/boot_wake_pins.cpp diff --git a/stratosphere/boot/source/boot_main.cpp b/stratosphere/boot/source/boot_main.cpp index 30e503c58..60f4ee169 100644 --- a/stratosphere/boot/source/boot_main.cpp +++ b/stratosphere/boot/source/boot_main.cpp @@ -107,8 +107,6 @@ int main(int argc, char **argv) { consoleDebugInit(debugDevice_SVC); - /* TODO: Implement the boot sysmodule -- boot_old to be broadly rewritten. */ - /* Change voltage from 3.3v to 1.8v for select devices. */ Boot::ChangeGpioVoltageTo1_8v(); @@ -133,7 +131,8 @@ int main(int argc, char **argv) /* Configure pinmux + drive pads. */ Boot::ConfigurePinmux(); - /* TODO: SetInitialWakePinConfiguration(); */ + /* Configure the PMC wake pin settings. */ + Boot::SetInitialWakePinConfiguration(); if (hw_type != HardwareType_Copper) { Boot::SetInitialClockConfiguration(); diff --git a/stratosphere/boot/source/boot_registers_pmc.hpp b/stratosphere/boot/source/boot_registers_pmc.hpp index 356cf94ad..46cf89454 100644 --- a/stratosphere/boot/source/boot_registers_pmc.hpp +++ b/stratosphere/boot/source/boot_registers_pmc.hpp @@ -24,8 +24,10 @@ static constexpr uintptr_t PmcBase = 0x7000E400ul; static constexpr size_t APBDEV_PMC_CNTRL = 0x0; static constexpr u32 PMC_CNTRL_MAIN_RST = (1 << 4); static constexpr size_t APBDEV_PMC_SEC_DISABLE = 0x4; +static constexpr size_t APBDEV_PMC_DPD_PADS_ORIDE = 0x1C; static constexpr size_t APBDEV_PMC_PWRGATE_TOGGLE = 0x30; static constexpr size_t APBDEV_PMC_PWRGATE_STATUS = 0x38; +static constexpr size_t APBDEV_PMC_BLINK_TIMER = 0x40; static constexpr size_t APBDEV_PMC_NO_IOPOWER = 0x44; static constexpr size_t APBDEV_PMC_SCRATCH0 = 0x50; static constexpr size_t APBDEV_PMC_SCRATCH1 = 0x54; @@ -61,6 +63,7 @@ static constexpr size_t APBDEV_PMC_IO_DPD3_REQ = 0x45C; static constexpr size_t APBDEV_PMC_IO_DPD4_REQ = 0x464; static constexpr size_t APBDEV_PMC_UTMIP_PAD_CFG1 = 0x4C4; static constexpr size_t APBDEV_PMC_UTMIP_PAD_CFG3 = 0x4CC; +static constexpr size_t APBDEV_PMC_WAKE_DEBOUNCE_EN = 0x4D8; static constexpr size_t APBDEV_PMC_DDR_CNTRL = 0x4E4; static constexpr size_t APBDEV_PMC_SEC_DISABLE4 = 0x5B0; static constexpr size_t APBDEV_PMC_SEC_DISABLE5 = 0x5B4; diff --git a/stratosphere/boot/source/boot_wake_control_configs.hpp b/stratosphere/boot/source/boot_wake_control_configs.hpp new file mode 100644 index 000000000..ecb22fb1e --- /dev/null +++ b/stratosphere/boot/source/boot_wake_control_configs.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +#include "boot_types.hpp" +#include "boot_registers_pmc.hpp" + +struct WakeControlConfig { + u32 reg_offset; + u32 mask_val; + bool flag_val; +}; + +static constexpr WakeControlConfig WakeControlConfigs[] = { + {APBDEV_PMC_CNTRL, 0x0800, true}, + {APBDEV_PMC_CNTRL, 0x0400, false}, + {APBDEV_PMC_CNTRL, 0x0200, true}, + {APBDEV_PMC_CNTRL, 0x0100, false}, + {APBDEV_PMC_CNTRL, 0x0040, false}, + {APBDEV_PMC_CNTRL, 0x0020, false}, + {APBDEV_PMC_CNTRL2, 0x4000, true}, + {APBDEV_PMC_CNTRL2, 0x0200, false}, + {APBDEV_PMC_CNTRL2, 0x0001, true}, +}; + +static constexpr size_t NumWakeControlConfigs = sizeof(WakeControlConfigs) / sizeof(WakeControlConfigs[0]); diff --git a/stratosphere/boot/source/boot_wake_pins.cpp b/stratosphere/boot/source/boot_wake_pins.cpp new file mode 100644 index 000000000..667ad711e --- /dev/null +++ b/stratosphere/boot/source/boot_wake_pins.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "boot_functions.hpp" +#include "boot_registers_pmc.hpp" +#include "boot_wake_control_configs.hpp" + +static void UpdatePmcControlBit(const u32 reg_offset, const u32 mask_val, const bool flag) { + Boot::WritePmcRegister(PmcBase + reg_offset, flag ? UINT32_MAX : 0, mask_val); + Boot::ReadPmcRegister(PmcBase + reg_offset); +} + +static void InitializePmcWakeConfiguration(const bool is_blink) { + /* Initialize APBDEV_PMC_WAKE_DEBOUNCE_EN, do a dummy read. */ + Boot::WritePmcRegister(PmcBase + APBDEV_PMC_WAKE_DEBOUNCE_EN, 0); + Boot::ReadPmcRegister(PmcBase + APBDEV_PMC_WAKE_DEBOUNCE_EN); + + /* Initialize APBDEV_PMC_BLINK_TIMER, do a dummy read. */ + Boot::WritePmcRegister(PmcBase + APBDEV_PMC_BLINK_TIMER, 0x8008800); + Boot::ReadPmcRegister(PmcBase + APBDEV_PMC_BLINK_TIMER); + + /* Set control bits, do dummy reads. */ + for (size_t i = 0; i < NumWakeControlConfigs; i++) { + UpdatePmcControlBit(WakeControlConfigs[i].reg_offset, WakeControlConfigs[i].mask_val, WakeControlConfigs[i].flag_val); + } + + /* Set bit 0x80 in APBDEV_PMC_CNTRL based on is_blink, do dummy read. */ + UpdatePmcControlBit(APBDEV_PMC_CNTRL, 0x80, is_blink); + + /* Set bit 0x100000 in APBDEV_PMC_DPD_PADS_ORIDE based on is_blink, do dummy read. */ + UpdatePmcControlBit(APBDEV_PMC_DPD_PADS_ORIDE, 0x100000, is_blink); +} + +void Boot::SetInitialWakePinConfiguration() { + InitializePmcWakeConfiguration(false); + + /* TODO: Wake event levels, wake event enables. */ +}