gsc.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2013 Gateworks Corporation
  4. *
  5. * Author: Tim Harvey <tharvey@gateworks.com>
  6. */
  7. #include <common.h>
  8. #include <command.h>
  9. #include <log.h>
  10. #include <linux/delay.h>
  11. #include <linux/errno.h>
  12. #include <common.h>
  13. #include <i2c.h>
  14. #include <linux/ctype.h>
  15. #include <asm/arch/sys_proto.h>
  16. #include "ventana_eeprom.h"
  17. #include "gsc.h"
  18. /*
  19. * The Gateworks System Controller will fail to ACK a master transaction if
  20. * it is busy, which can occur during its 1HZ timer tick while reading ADC's.
  21. * When this does occur, it will never be busy long enough to fail more than
  22. * 2 back-to-back transfers. Thus we wrap i2c_read and i2c_write with
  23. * 3 retries.
  24. */
  25. int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
  26. {
  27. int retry = 3;
  28. int n = 0;
  29. int ret;
  30. while (n++ < retry) {
  31. ret = i2c_read(chip, addr, alen, buf, len);
  32. if (!ret)
  33. break;
  34. debug("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
  35. n, ret);
  36. if (ret != -ENODEV)
  37. break;
  38. mdelay(10);
  39. }
  40. return ret;
  41. }
  42. int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
  43. {
  44. int retry = 3;
  45. int n = 0;
  46. int ret;
  47. while (n++ < retry) {
  48. ret = i2c_write(chip, addr, alen, buf, len);
  49. if (!ret)
  50. break;
  51. debug("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
  52. n, ret);
  53. if (ret != -ENODEV)
  54. break;
  55. mdelay(10);
  56. }
  57. mdelay(100);
  58. return ret;
  59. }
  60. static void read_hwmon(const char *name, uint reg, uint size)
  61. {
  62. unsigned char buf[3];
  63. uint ui;
  64. printf("%-8s:", name);
  65. memset(buf, 0, sizeof(buf));
  66. if (gsc_i2c_read(GSC_HWMON_ADDR, reg, 1, buf, size)) {
  67. puts("fRD\n");
  68. } else {
  69. ui = buf[0] | (buf[1]<<8) | (buf[2]<<16);
  70. if (size == 2 && ui > 0x8000)
  71. ui -= 0xffff;
  72. if (ui == 0xffffff)
  73. puts("invalid\n");
  74. else
  75. printf("%d\n", ui);
  76. }
  77. }
  78. int gsc_info(int verbose)
  79. {
  80. unsigned char buf[16];
  81. i2c_set_bus_num(0);
  82. if (gsc_i2c_read(GSC_SC_ADDR, 0, 1, buf, 16))
  83. return CMD_RET_FAILURE;
  84. printf("GSC: v%d", buf[GSC_SC_FWVER]);
  85. printf(" 0x%04x", buf[GSC_SC_FWCRC] | buf[GSC_SC_FWCRC+1]<<8);
  86. printf(" WDT:%sabled", (buf[GSC_SC_CTRL1] & (1<<GSC_SC_CTRL1_WDEN))
  87. ? "en" : "dis");
  88. if (buf[GSC_SC_STATUS] & (1 << GSC_SC_IRQ_WATCHDOG)) {
  89. buf[GSC_SC_STATUS] &= ~(1 << GSC_SC_IRQ_WATCHDOG);
  90. puts(" WDT_RESET");
  91. gsc_i2c_write(GSC_SC_ADDR, GSC_SC_STATUS, 1,
  92. &buf[GSC_SC_STATUS], 1);
  93. }
  94. if (!gsc_i2c_read(GSC_HWMON_ADDR, GSC_HWMON_TEMP, 1, buf, 2)) {
  95. int ui = buf[0] | buf[1]<<8;
  96. if (ui > 0x8000)
  97. ui -= 0xffff;
  98. printf(" board temp at %dC", ui / 10);
  99. }
  100. puts("\n");
  101. if (!verbose)
  102. return CMD_RET_SUCCESS;
  103. read_hwmon("Temp", GSC_HWMON_TEMP, 2);
  104. read_hwmon("VIN", GSC_HWMON_VIN, 3);
  105. read_hwmon("VBATT", GSC_HWMON_VBATT, 3);
  106. read_hwmon("VDD_3P3", GSC_HWMON_VDD_3P3, 3);
  107. read_hwmon("VDD_ARM", GSC_HWMON_VDD_CORE, 3);
  108. read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3);
  109. read_hwmon("VDD_HIGH", GSC_HWMON_VDD_HIGH, 3);
  110. read_hwmon("VDD_DDR", GSC_HWMON_VDD_DDR, 3);
  111. read_hwmon("VDD_5P0", GSC_HWMON_VDD_5P0, 3);
  112. if (strncasecmp((const char*) ventana_info.model, "GW553", 5))
  113. read_hwmon("VDD_2P5", GSC_HWMON_VDD_2P5, 3);
  114. read_hwmon("VDD_1P8", GSC_HWMON_VDD_1P8, 3);
  115. read_hwmon("VDD_IO2", GSC_HWMON_VDD_IO2, 3);
  116. switch (ventana_info.model[3]) {
  117. case '1': /* GW51xx */
  118. read_hwmon("VDD_IO3", GSC_HWMON_VDD_IO4, 3); /* -C rev */
  119. break;
  120. case '2': /* GW52xx */
  121. break;
  122. case '3': /* GW53xx */
  123. read_hwmon("VDD_IO4", GSC_HWMON_VDD_IO4, 3); /* -C rev */
  124. read_hwmon("VDD_GPS", GSC_HWMON_VDD_IO3, 3);
  125. break;
  126. case '4': /* GW54xx */
  127. read_hwmon("VDD_IO3", GSC_HWMON_VDD_IO4, 3); /* -C rev */
  128. read_hwmon("VDD_GPS", GSC_HWMON_VDD_IO3, 3);
  129. break;
  130. case '5': /* GW55xx */
  131. break;
  132. case '6': /* GW560x */
  133. read_hwmon("VDD_IO4", GSC_HWMON_VDD_IO4, 3);
  134. read_hwmon("VDD_GPS", GSC_HWMON_VDD_IO3, 3);
  135. break;
  136. case '9': /* GW590x */
  137. read_hwmon("AMONBMON", GSC_HWMON_VDD_IO3, 3);
  138. read_hwmon("BAT_VOLT", GSC_HWMON_VDD_EXT, 3);
  139. read_hwmon("BAT_TEMP", GSC_HWMON_VDD_IO4, 2);
  140. }
  141. return 0;
  142. }
  143. /*
  144. * The Gateworks System Controller implements a boot
  145. * watchdog (always enabled) as a workaround for IMX6 boot related
  146. * errata such as:
  147. * ERR005768 - no fix scheduled
  148. * ERR006282 - fixed in silicon r1.2
  149. * ERR007117 - fixed in silicon r1.3
  150. * ERR007220 - fixed in silicon r1.3
  151. * ERR007926 - no fix scheduled
  152. * see http://cache.freescale.com/files/32bit/doc/errata/IMX6DQCE.pdf
  153. *
  154. * Disable the boot watchdog
  155. */
  156. int gsc_boot_wd_disable(void)
  157. {
  158. u8 reg;
  159. i2c_set_bus_num(CONFIG_I2C_GSC);
  160. if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1)) {
  161. reg |= (1 << GSC_SC_CTRL1_WDDIS);
  162. if (!gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
  163. return 0;
  164. }
  165. puts("Error: could not disable GSC Watchdog\n");
  166. return 1;
  167. }
  168. /* determine BOM revision from model */
  169. int get_bom_rev(const char *str)
  170. {
  171. int rev_bom = 0;
  172. int i;
  173. for (i = strlen(str) - 1; i > 0; i--) {
  174. if (str[i] == '-')
  175. break;
  176. if (str[i] >= '1' && str[i] <= '9') {
  177. rev_bom = str[i] - '0';
  178. break;
  179. }
  180. }
  181. return rev_bom;
  182. }
  183. /* determine PCB revision from model */
  184. char get_pcb_rev(const char *str)
  185. {
  186. char rev_pcb = 'A';
  187. int i;
  188. for (i = strlen(str) - 1; i > 0; i--) {
  189. if (str[i] == '-')
  190. break;
  191. if (str[i] >= 'A') {
  192. rev_pcb = str[i];
  193. break;
  194. }
  195. }
  196. return rev_pcb;
  197. }
  198. /*
  199. * get dt name based on model and detail level:
  200. */
  201. const char *gsc_get_dtb_name(int level, char *buf, int sz)
  202. {
  203. const char *model = (const char *)ventana_info.model;
  204. const char *pre = is_mx6dq() ? "imx6q-" : "imx6dl-";
  205. int modelno, rev_pcb, rev_bom;
  206. /* a few board models are dt equivalents to other models */
  207. if (strncasecmp(model, "gw5906", 6) == 0)
  208. model = "gw552x-d";
  209. else if (strncasecmp(model, "gw5908", 6) == 0)
  210. model = "gw53xx-f";
  211. else if (strncasecmp(model, "gw5905", 6) == 0)
  212. model = "gw5904-a";
  213. modelno = ((model[2] - '0') * 1000)
  214. + ((model[3] - '0') * 100)
  215. + ((model[4] - '0') * 10)
  216. + (model[5] - '0');
  217. rev_pcb = tolower(get_pcb_rev(model));
  218. rev_bom = get_bom_rev(model);
  219. /* compare model/rev/bom in order of most specific to least */
  220. snprintf(buf, sz, "%s%04d", pre, modelno);
  221. switch (level) {
  222. case 0: /* full model first (ie gw5400-a1) */
  223. if (rev_bom) {
  224. snprintf(buf, sz, "%sgw%04d-%c%d", pre, modelno, rev_pcb, rev_bom);
  225. break;
  226. }
  227. fallthrough;
  228. case 1: /* don't care about bom rev (ie gw5400-a) */
  229. snprintf(buf, sz, "%sgw%04d-%c", pre, modelno, rev_pcb);
  230. break;
  231. case 2: /* don't care about the pcb rev (ie gw5400) */
  232. snprintf(buf, sz, "%sgw%04d", pre, modelno);
  233. break;
  234. case 3: /* look for generic model (ie gw540x) */
  235. snprintf(buf, sz, "%sgw%03dx", pre, modelno / 10);
  236. break;
  237. case 4: /* look for more generic model (ie gw54xx) */
  238. snprintf(buf, sz, "%sgw%02dxx", pre, modelno / 100);
  239. break;
  240. default: /* give up */
  241. return NULL;
  242. }
  243. return buf;
  244. }
  245. #if defined(CONFIG_CMD_GSC) && !defined(CONFIG_SPL_BUILD)
  246. static int do_gsc_sleep(struct cmd_tbl *cmdtp, int flag, int argc,
  247. char *const argv[])
  248. {
  249. unsigned char reg;
  250. unsigned long secs = 0;
  251. if (argc < 2)
  252. return CMD_RET_USAGE;
  253. secs = dectoul(argv[1], NULL);
  254. printf("GSC Sleeping for %ld seconds\n", secs);
  255. i2c_set_bus_num(0);
  256. reg = (secs >> 24) & 0xff;
  257. if (gsc_i2c_write(GSC_SC_ADDR, 9, 1, &reg, 1))
  258. goto error;
  259. reg = (secs >> 16) & 0xff;
  260. if (gsc_i2c_write(GSC_SC_ADDR, 8, 1, &reg, 1))
  261. goto error;
  262. reg = (secs >> 8) & 0xff;
  263. if (gsc_i2c_write(GSC_SC_ADDR, 7, 1, &reg, 1))
  264. goto error;
  265. reg = secs & 0xff;
  266. if (gsc_i2c_write(GSC_SC_ADDR, 6, 1, &reg, 1))
  267. goto error;
  268. if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
  269. goto error;
  270. reg |= (1 << 2);
  271. if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
  272. goto error;
  273. reg &= ~(1 << 2);
  274. reg |= 0x3;
  275. if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
  276. goto error;
  277. return CMD_RET_SUCCESS;
  278. error:
  279. printf("i2c error\n");
  280. return CMD_RET_FAILURE;
  281. }
  282. static int do_gsc_wd(struct cmd_tbl *cmdtp, int flag, int argc,
  283. char *const argv[])
  284. {
  285. unsigned char reg;
  286. if (argc < 2)
  287. return CMD_RET_USAGE;
  288. if (strcasecmp(argv[1], "enable") == 0) {
  289. int timeout = 0;
  290. if (argc > 2)
  291. timeout = dectoul(argv[2], NULL);
  292. i2c_set_bus_num(0);
  293. if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
  294. return CMD_RET_FAILURE;
  295. reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME));
  296. if (timeout == 60)
  297. reg |= (1 << GSC_SC_CTRL1_WDTIME);
  298. else
  299. timeout = 30;
  300. reg |= (1 << GSC_SC_CTRL1_WDEN);
  301. if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
  302. return CMD_RET_FAILURE;
  303. printf("GSC Watchdog enabled with timeout=%d seconds\n",
  304. timeout);
  305. } else if (strcasecmp(argv[1], "disable") == 0) {
  306. i2c_set_bus_num(0);
  307. if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
  308. return CMD_RET_FAILURE;
  309. reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME));
  310. if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
  311. return CMD_RET_FAILURE;
  312. printf("GSC Watchdog disabled\n");
  313. } else {
  314. return CMD_RET_USAGE;
  315. }
  316. return CMD_RET_SUCCESS;
  317. }
  318. static int do_gsc(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
  319. {
  320. if (argc < 2)
  321. return gsc_info(1);
  322. if (strcasecmp(argv[1], "wd") == 0)
  323. return do_gsc_wd(cmdtp, flag, --argc, ++argv);
  324. else if (strcasecmp(argv[1], "sleep") == 0)
  325. return do_gsc_sleep(cmdtp, flag, --argc, ++argv);
  326. return CMD_RET_USAGE;
  327. }
  328. U_BOOT_CMD(
  329. gsc, 4, 1, do_gsc, "GSC configuration",
  330. "[wd enable [30|60]]|[wd disable]|[sleep <secs>]\n"
  331. );
  332. #endif /* CONFIG_CMD_GSC */