reset.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Board-specific reboot/shutdown routines
  3. *
  4. * Copyright (c) 2009 Philippe Vachon <[email protected]>
  5. *
  6. * Copyright (C) 2009 Lemote Inc.
  7. * Author: Wu Zhangjin, [email protected]
  8. */
  9. #include <linux/io.h>
  10. #include <linux/delay.h>
  11. #include <linux/types.h>
  12. #include <asm/bootinfo.h>
  13. #include <loongson.h>
  14. #include <cs5536/cs5536.h>
  15. #include "ec_kb3310b.h"
  16. static void reset_cpu(void)
  17. {
  18. /*
  19. * reset cpu to full speed, this is needed when enabling cpu frequency
  20. * scalling
  21. */
  22. writel(readl(LOONGSON_CHIPCFG) | 0x7, LOONGSON_CHIPCFG);
  23. }
  24. /* reset support for fuloong2f */
  25. static void fl2f_reboot(void)
  26. {
  27. reset_cpu();
  28. /* send a reset signal to south bridge.
  29. *
  30. * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset
  31. * normally with this reset operation and it will not work in PMON, but
  32. * you can type halt command and then reboot, seems the hardware reset
  33. * logic not work normally.
  34. */
  35. {
  36. u32 hi, lo;
  37. _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
  38. lo |= 0x00000001;
  39. _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
  40. }
  41. }
  42. static void fl2f_shutdown(void)
  43. {
  44. u32 hi, lo, val;
  45. int gpio_base;
  46. /* get gpio base */
  47. _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
  48. gpio_base = lo & 0xff00;
  49. /* make cs5536 gpio13 output enable */
  50. val = inl(gpio_base + GPIOL_OUT_EN);
  51. val &= ~(1 << (16 + 13));
  52. val |= (1 << 13);
  53. outl(val, gpio_base + GPIOL_OUT_EN);
  54. mmiowb();
  55. /* make cs5536 gpio13 output low level voltage. */
  56. val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13));
  57. val |= (1 << (16 + 13));
  58. outl(val, gpio_base + GPIOL_OUT_VAL);
  59. mmiowb();
  60. }
  61. /* reset support for yeeloong2f and mengloong2f notebook */
  62. static void ml2f_reboot(void)
  63. {
  64. reset_cpu();
  65. /* sending an reset signal to EC(embedded controller) */
  66. ec_write(REG_RESET, BIT_RESET_ON);
  67. }
  68. #define yl2f89_reboot ml2f_reboot
  69. /* menglong(7inches) laptop has different shutdown logic from 8.9inches */
  70. #define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d
  71. #define EC_SHUTDOWN_IO_PORT_LOW 0xff2e
  72. #define EC_SHUTDOWN_IO_PORT_DATA 0xff2f
  73. #define REG_SHUTDOWN_HIGH 0xFC
  74. #define REG_SHUTDOWN_LOW 0x29
  75. #define BIT_SHUTDOWN_ON (1 << 1)
  76. static void ml2f_shutdown(void)
  77. {
  78. u8 val;
  79. u64 i;
  80. outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH);
  81. outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW);
  82. mmiowb();
  83. val = inb(EC_SHUTDOWN_IO_PORT_DATA);
  84. outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA);
  85. mmiowb();
  86. /* need enough wait here... how many microseconds needs? */
  87. for (i = 0; i < 0x10000; i++)
  88. delay();
  89. outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA);
  90. mmiowb();
  91. }
  92. static void yl2f89_shutdown(void)
  93. {
  94. /* cpu-gpio0 output low */
  95. LOONGSON_GPIODATA &= ~0x00000001;
  96. /* cpu-gpio0 as output */
  97. LOONGSON_GPIOIE &= ~0x00000001;
  98. }
  99. void mach_prepare_reboot(void)
  100. {
  101. switch (mips_machtype) {
  102. case MACH_LEMOTE_FL2F:
  103. case MACH_LEMOTE_NAS:
  104. case MACH_LEMOTE_LL2F:
  105. fl2f_reboot();
  106. break;
  107. case MACH_LEMOTE_ML2F7:
  108. ml2f_reboot();
  109. break;
  110. case MACH_LEMOTE_YL2F89:
  111. yl2f89_reboot();
  112. break;
  113. default:
  114. break;
  115. }
  116. }
  117. void mach_prepare_shutdown(void)
  118. {
  119. switch (mips_machtype) {
  120. case MACH_LEMOTE_FL2F:
  121. case MACH_LEMOTE_NAS:
  122. case MACH_LEMOTE_LL2F:
  123. fl2f_shutdown();
  124. break;
  125. case MACH_LEMOTE_ML2F7:
  126. ml2f_shutdown();
  127. break;
  128. case MACH_LEMOTE_YL2F89:
  129. yl2f89_shutdown();
  130. break;
  131. default:
  132. break;
  133. }
  134. }