power.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * Copyright (C) 2018 bzt (bztsrc@github)
  3. *
  4. * Permission is hereby granted, free of charge, to any person
  5. * obtaining a copy of this software and associated documentation
  6. * files (the "Software"), to deal in the Software without
  7. * restriction, including without limitation the rights to use, copy,
  8. * modify, merge, publish, distribute, sublicense, and/or sell copies
  9. * of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be
  13. * included in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. * DEALINGS IN THE SOFTWARE.
  23. *
  24. */
  25. #include "gpio.h"
  26. #include "mbox.h"
  27. #include "delays.h"
  28. #define PM_RSTC ((volatile unsigned int*)(MMIO_BASE+0x0010001c))
  29. #define PM_RSTS ((volatile unsigned int*)(MMIO_BASE+0x00100020))
  30. #define PM_WDOG ((volatile unsigned int*)(MMIO_BASE+0x00100024))
  31. #define PM_WDOG_MAGIC 0x5a000000
  32. #define PM_RSTC_FULLRST 0x00000020
  33. /**
  34. * Shutdown the board
  35. */
  36. void power_off()
  37. {
  38. unsigned long r;
  39. // power off devices one by one
  40. for(r=0;r<16;r++) {
  41. mbox[0]=8*4;
  42. mbox[1]=MBOX_REQUEST;
  43. mbox[2]=MBOX_TAG_SETPOWER; // set power state
  44. mbox[3]=8;
  45. mbox[4]=8;
  46. mbox[5]=(unsigned int)r; // device id
  47. mbox[6]=0; // bit 0: off, bit 1: no wait
  48. mbox[7]=MBOX_TAG_LAST;
  49. mbox_call(MBOX_CH_PROP);
  50. }
  51. // power off gpio pins (but not VCC pins)
  52. *GPFSEL0 = 0; *GPFSEL1 = 0; *GPFSEL2 = 0; *GPFSEL3 = 0; *GPFSEL4 = 0; *GPFSEL5 = 0;
  53. *GPPUD = 0;
  54. wait_cycles(150);
  55. *GPPUDCLK0 = 0xffffffff; *GPPUDCLK1 = 0xffffffff;
  56. wait_cycles(150);
  57. *GPPUDCLK0 = 0; *GPPUDCLK1 = 0; // flush GPIO setup
  58. // power off the SoC (GPU + CPU)
  59. r = *PM_RSTS; r &= ~0xfffffaaa;
  60. r |= 0x555; // partition 63 used to indicate halt
  61. *PM_RSTS = PM_WDOG_MAGIC | r;
  62. *PM_WDOG = PM_WDOG_MAGIC | 10;
  63. *PM_RSTC = PM_WDOG_MAGIC | PM_RSTC_FULLRST;
  64. }
  65. /**
  66. * Reboot
  67. */
  68. void reset()
  69. {
  70. unsigned int r;
  71. // trigger a restart by instructing the GPU to boot from partition 0
  72. r = *PM_RSTS; r &= ~0xfffffaaa;
  73. *PM_RSTS = PM_WDOG_MAGIC | r; // boot from partition 0
  74. *PM_WDOG = PM_WDOG_MAGIC | 10;
  75. *PM_RSTC = PM_WDOG_MAGIC | PM_RSTC_FULLRST;
  76. }