br_resetc.c 4.5 KB

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