/* * Copyright (C) 2018 bzt (bztsrc@github) * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ #include "gpio.h" #include "mbox.h" #include "delays.h" #define PM_RSTC ((volatile unsigned int*)(MMIO_BASE+0x0010001c)) #define PM_RSTS ((volatile unsigned int*)(MMIO_BASE+0x00100020)) #define PM_WDOG ((volatile unsigned int*)(MMIO_BASE+0x00100024)) #define PM_WDOG_MAGIC 0x5a000000 #define PM_RSTC_FULLRST 0x00000020 /** * Shutdown the board */ void power_off() { unsigned long r; // power off devices one by one for(r=0;r<16;r++) { mbox[0]=8*4; mbox[1]=MBOX_REQUEST; mbox[2]=MBOX_TAG_SETPOWER; // set power state mbox[3]=8; mbox[4]=8; mbox[5]=(unsigned int)r; // device id mbox[6]=0; // bit 0: off, bit 1: no wait mbox[7]=MBOX_TAG_LAST; mbox_call(MBOX_CH_PROP); } // power off gpio pins (but not VCC pins) *GPFSEL0 = 0; *GPFSEL1 = 0; *GPFSEL2 = 0; *GPFSEL3 = 0; *GPFSEL4 = 0; *GPFSEL5 = 0; *GPPUD = 0; wait_cycles(150); *GPPUDCLK0 = 0xffffffff; *GPPUDCLK1 = 0xffffffff; wait_cycles(150); *GPPUDCLK0 = 0; *GPPUDCLK1 = 0; // flush GPIO setup // power off the SoC (GPU + CPU) r = *PM_RSTS; r &= ~0xfffffaaa; r |= 0x555; // partition 63 used to indicate halt *PM_RSTS = PM_WDOG_MAGIC | r; *PM_WDOG = PM_WDOG_MAGIC | 10; *PM_RSTC = PM_WDOG_MAGIC | PM_RSTC_FULLRST; } /** * Reboot */ void reset() { unsigned int r; // trigger a restart by instructing the GPU to boot from partition 0 r = *PM_RSTS; r &= ~0xfffffaaa; *PM_RSTS = PM_WDOG_MAGIC | r; // boot from partition 0 *PM_WDOG = PM_WDOG_MAGIC | 10; *PM_RSTC = PM_WDOG_MAGIC | PM_RSTC_FULLRST; }