br_resetc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * common reset-controller functions for B&R boards
  4. *
  5. * Copyright (C) 2019 Hannes Schmelzer <oe5hpm@oevsv.at>
  6. * B&R Industrial Automation GmbH - http://www.br-automation.com/ *
  7. */
  8. #include <common.h>
  9. #include <env.h>
  10. #include <errno.h>
  11. #include <i2c.h>
  12. #include <dm/uclass.h>
  13. #include <linux/delay.h>
  14. #include "br_resetc.h"
  15. /* I2C Address of controller */
  16. #define RSTCTRL_ADDR_PSOC 0x75
  17. #define RSTCTRL_ADDR_STM32 0x60
  18. #define BMODE_DEFAULTAR 0
  19. #define BMODE_SERVICE 2
  20. #define BMODE_RUN 4
  21. #define BMODE_PME 12
  22. #define BMODE_DIAG 15
  23. #if CONFIG_IS_ENABLED(LCD) && !CONFIG_IS_ENABLED(DM_VIDEO)
  24. #include <lcd.h>
  25. #define LCD_SETCURSOR(x, y) lcd_position_cursor(x, y)
  26. #define LCD_PUTS(x) lcd_puts(x)
  27. #else
  28. #define LCD_SETCURSOR(x, y)
  29. #define LCD_PUTS(x)
  30. #endif /* CONFIG_LCD */
  31. static const char *bootmodeascii[16] = {
  32. "BOOT", "reserved", "reserved", "reserved",
  33. "RUN", "reserved", "reserved", "reserved",
  34. "reserved", "reserved", "reserved", "reserved",
  35. "PME", "reserved", "reserved", "DIAG",
  36. };
  37. struct br_reset_t {
  38. struct udevice *i2cdev;
  39. u8 is_psoc;
  40. };
  41. static struct br_reset_t resetc;
  42. __weak int board_boot_key(void)
  43. {
  44. return 0;
  45. }
  46. __weak void board_boot_led(unsigned int on)
  47. {
  48. }
  49. static int resetc_init(void)
  50. {
  51. struct udevice *i2cbus;
  52. int rc;
  53. rc = uclass_get_device_by_seq(UCLASS_I2C, 0, &i2cbus);
  54. if (rc) {
  55. printf("Cannot find I2C bus #0!\n");
  56. return -1;
  57. }
  58. resetc.is_psoc = 1;
  59. rc = dm_i2c_probe(i2cbus,
  60. RSTCTRL_ADDR_PSOC, 0, &resetc.i2cdev);
  61. if (rc) {
  62. resetc.is_psoc = 0;
  63. rc = dm_i2c_probe(i2cbus,
  64. RSTCTRL_ADDR_STM32, 0, &resetc.i2cdev);
  65. }
  66. if (rc)
  67. printf("Warning: cannot probe BuR resetcontroller!\n");
  68. return rc;
  69. }
  70. int br_resetc_regget(u8 reg, u8 *dst)
  71. {
  72. int rc = 0;
  73. if (!resetc.i2cdev)
  74. rc = resetc_init();
  75. if (rc != 0)
  76. return rc;
  77. return dm_i2c_read(resetc.i2cdev, reg, dst, 1);
  78. }
  79. int br_resetc_regset(u8 reg, u8 val)
  80. {
  81. int rc = 0;
  82. u16 regw = (val << 8) | val;
  83. if (!resetc.i2cdev)
  84. rc = resetc_init();
  85. if (rc != 0)
  86. return rc;
  87. if (resetc.is_psoc)
  88. return dm_i2c_write(resetc.i2cdev, reg, (u8 *)&regw, 2);
  89. return dm_i2c_write(resetc.i2cdev, reg, (u8 *)&regw, 1);
  90. }
  91. int br_resetc_bmode(void)
  92. {
  93. int rc = 0;
  94. u16 regw;
  95. u8 regb, scr;
  96. int cnt;
  97. unsigned int bmode = 0;
  98. if (!resetc.i2cdev)
  99. rc = resetc_init();
  100. if (rc != 0)
  101. return rc;
  102. rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_ENHSTATUS, &regb, 1);
  103. if (rc != 0) {
  104. printf("WARN: cannot read ENHSTATUS from resetcontroller!\n");
  105. return -1;
  106. }
  107. rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_SCRATCHREG0, &scr, 1);
  108. if (rc != 0) {
  109. printf("WARN: cannot read SCRATCHREG from resetcontroller!\n");
  110. return -1;
  111. }
  112. board_boot_led(1);
  113. /* special bootmode from resetcontroller */
  114. if (regb & 0x4) {
  115. bmode = BMODE_DIAG;
  116. } else if (regb & 0x8) {
  117. bmode = BMODE_DEFAULTAR;
  118. } else if (board_boot_key() != 0) {
  119. cnt = 4;
  120. do {
  121. LCD_SETCURSOR(1, 8);
  122. switch (cnt) {
  123. case 4:
  124. LCD_PUTS
  125. ("release KEY to enter SERVICE-mode. ");
  126. break;
  127. case 3:
  128. LCD_PUTS
  129. ("release KEY to enter DIAGNOSE-mode. ");
  130. break;
  131. case 2:
  132. LCD_PUTS
  133. ("release KEY to enter BOOT-mode. ");
  134. break;
  135. }
  136. mdelay(1000);
  137. cnt--;
  138. if (board_boot_key() == 0)
  139. break;
  140. } while (cnt);
  141. switch (cnt) {
  142. case 0:
  143. bmode = BMODE_PME;
  144. break;
  145. case 1:
  146. bmode = BMODE_DEFAULTAR;
  147. break;
  148. case 2:
  149. bmode = BMODE_DIAG;
  150. break;
  151. case 3:
  152. bmode = BMODE_SERVICE;
  153. break;
  154. }
  155. } else if ((regb & 0x1) || scr == 0xCC) {
  156. bmode = BMODE_PME;
  157. } else {
  158. bmode = BMODE_RUN;
  159. }
  160. LCD_SETCURSOR(1, 8);
  161. switch (bmode) {
  162. case BMODE_PME:
  163. LCD_PUTS("entering PME-Mode (netscript). ");
  164. regw = 0x0C0C;
  165. break;
  166. case BMODE_DEFAULTAR:
  167. LCD_PUTS("entering BOOT-mode. ");
  168. regw = 0x0000;
  169. break;
  170. case BMODE_DIAG:
  171. LCD_PUTS("entering DIAGNOSE-mode. ");
  172. regw = 0x0F0F;
  173. break;
  174. case BMODE_SERVICE:
  175. LCD_PUTS("entering SERVICE mode. ");
  176. regw = 0xB4B4;
  177. break;
  178. case BMODE_RUN:
  179. LCD_PUTS("loading OS... ");
  180. regw = 0x0404;
  181. break;
  182. }
  183. board_boot_led(0);
  184. if (resetc.is_psoc)
  185. rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0,
  186. (u8 *)&regw, 2);
  187. else
  188. rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0,
  189. (u8 *)&regw, 1);
  190. if (rc != 0)
  191. printf("WARN: cannot write into resetcontroller!\n");
  192. if (resetc.is_psoc)
  193. printf("Reset: PSOC controller\n");
  194. else
  195. printf("Reset: STM32 controller\n");
  196. printf("Mode: %s\n", bootmodeascii[regw & 0x0F]);
  197. env_set_ulong("b_mode", regw & 0x0F);
  198. return rc;
  199. }