1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2022 Gateworks Corporation 4 */ 5 6#include <command.h> 7#include <gsc.h> 8#include <i2c.h> 9#include <rtc.h> 10#include <asm/unaligned.h> 11#include <linux/delay.h> 12#include <dm/device.h> 13#include <dm/device-internal.h> 14#include <dm/ofnode.h> 15#include <dm/read.h> 16 17#define GSC_BUSNO 0 18#define GSC_SC_ADDR 0x20 19#define GSC_HWMON_ADDR 0x29 20#define GSC_RTC_ADDR 0x68 21 22/* System Controller registers */ 23enum { 24 GSC_SC_CTRL0 = 0, 25 GSC_SC_CTRL1 = 1, 26 GSC_SC_TIME = 2, 27 GSC_SC_TIME_ADD = 6, 28 GSC_SC_STATUS = 10, 29 GSC_SC_FWCRC = 12, 30 GSC_SC_FWVER = 14, 31 GSC_SC_WP = 15, 32 GSC_SC_RST_CAUSE = 16, 33 GSC_SC_THERM_PROTECT = 19, 34}; 35 36/* System Controller Control1 bits */ 37enum { 38 GSC_SC_CTRL1_SLEEP_EN = 0, /* 1 = enable sleep */ 39 GSC_SC_CTRL1_SLEEP_ACTIVATE = 1, /* 1 = activate sleep */ 40 GSC_SC_CTRL1_SLEEP_ADD = 2, /* 1 = latch and add sleep time */ 41 GSC_SC_CTRL1_SLEEP_NOWAKEPB = 3, /* 1 = do not wake on sleep on button press */ 42 GSC_SC_CTRL1_WDTIME = 4, /* 1 = 60s timeout, 0 = 30s timeout */ 43 GSC_SC_CTRL1_WDEN = 5, /* 1 = enable, 0 = disable */ 44 GSC_SC_CTRL1_BOOT_CHK = 6, /* 1 = enable alt boot check */ 45 GSC_SC_CTRL1_WDDIS = 7, /* 1 = disable boot watchdog */ 46}; 47 48/* System Controller Interrupt bits */ 49enum { 50 GSC_SC_IRQ_PB = 0, /* Pushbutton switch */ 51 GSC_SC_IRQ_SECURE = 1, /* Secure Key erase operation complete */ 52 GSC_SC_IRQ_EEPROM_WP = 2, /* EEPROM write violation */ 53 GSC_SC_IRQ_GPIO = 4, /* GPIO change */ 54 GSC_SC_IRQ_TAMPER = 5, /* Tamper detect */ 55 GSC_SC_IRQ_WATCHDOG = 6, /* Watchdog trip */ 56 GSC_SC_IRQ_PBLONG = 7, /* Pushbutton long hold */ 57}; 58 59/* System Controller WP bits */ 60enum { 61 GSC_SC_WP_ALL = 0, /* Write Protect All EEPROM regions */ 62 GSC_SC_WP_BOARDINFO = 1, /* Write Protect Board Info region */ 63}; 64 65/* System Controller Reset Cause */ 66enum { 67 GSC_SC_RST_CAUSE_VIN = 0, 68 GSC_SC_RST_CAUSE_PB = 1, 69 GSC_SC_RST_CAUSE_WDT = 2, 70 GSC_SC_RST_CAUSE_CPU = 3, 71 GSC_SC_RST_CAUSE_TEMP_LOCAL = 4, 72 GSC_SC_RST_CAUSE_TEMP_REMOTE = 5, 73 GSC_SC_RST_CAUSE_SLEEP = 6, 74 GSC_SC_RST_CAUSE_BOOT_WDT = 7, 75 GSC_SC_RST_CAUSE_BOOT_WDT_MAN = 8, 76 GSC_SC_RST_CAUSE_SOFT_PWR = 9, 77 GSC_SC_RST_CAUSE_MAX = 10, 78}; 79 80#if CONFIG_IS_ENABLED(DM_I2C) 81 82struct gsc_priv { 83 int gscver; 84 int fwver; 85 int fwcrc; 86 struct udevice *hwmon; 87 struct udevice *rtc; 88}; 89 90/* 91 * GSCv2 will fail to ACK an I2C transaction if it is busy, which can occur 92 * during its 1HZ timer tick while reading ADC's. When this does occur, 93 * it will never be busy longer than 2 back-to-back transfers so retry 3 times. 94 */ 95static int gsc_i2c_read(struct udevice *dev, uint addr, u8 *buf, int len) 96{ 97 struct gsc_priv *priv = dev_get_priv(dev); 98 int retry = (priv->gscver == 3) ? 1 : 3; 99 int n = 0; 100 int ret; 101 102 while (n++ < retry) { 103 ret = dm_i2c_read(dev, addr, buf, len); 104 if (!ret) 105 break; 106 if (ret != -EREMOTEIO) 107 break; 108 mdelay(10); 109 } 110 return ret; 111} 112 113static int gsc_i2c_write(struct udevice *dev, uint addr, const u8 *buf, int len) 114{ 115 struct gsc_priv *priv = dev_get_priv(dev); 116 int retry = (priv->gscver == 3) ? 1 : 3; 117 int n = 0; 118 int ret; 119 120 while (n++ < retry) { 121 ret = dm_i2c_write(dev, addr, buf, len); 122 if (!ret) 123 break; 124 if (ret != -EREMOTEIO) 125 break; 126 mdelay(10); 127 } 128 return ret; 129} 130 131static struct udevice *gsc_get_dev(int busno, int slave) 132{ 133 struct udevice *dev, *bus; 134 int ret; 135 136 ret = uclass_get_device_by_seq(UCLASS_I2C, busno, &bus); 137 if (ret) 138 return NULL; 139 ret = dm_i2c_probe(bus, slave, 0, &dev); 140 if (ret) 141 return NULL; 142 143 return dev; 144} 145 146static int gsc_thermal_get_info(struct udevice *dev, u8 *outreg, int *tmax, bool *enable) 147{ 148 struct gsc_priv *priv = dev_get_priv(dev); 149 int ret; 150 u8 reg; 151 152 if (priv->gscver > 2 && priv->fwver > 52) { 153 ret = gsc_i2c_read(dev, GSC_SC_THERM_PROTECT, ®, 1); 154 if (!ret) { 155 if (outreg) 156 *outreg = reg; 157 if (tmax) { 158 *tmax = ((reg & 0xf8) >> 3) * 2; 159 if (*tmax) 160 *tmax += 70; 161 else 162 *tmax = 120; 163 } 164 if (enable) 165 *enable = reg & 1; 166 } 167 } else { 168 ret = -ENODEV; 169 } 170 171 return ret; 172} 173 174static int gsc_thermal_get_temp(struct udevice *dev) 175{ 176 struct gsc_priv *priv = dev_get_priv(dev); 177 u32 reg, mode, val; 178 const char *label; 179 ofnode node; 180 u8 buf[2]; 181 182 ofnode_for_each_subnode(node, dev_read_subnode(dev, "adc")) { 183 if (ofnode_read_u32(node, "reg", ®)) 184 reg = -1; 185 if (ofnode_read_u32(node, "gw,mode", &mode)) 186 mode = -1; 187 label = ofnode_read_string(node, "label"); 188 189 if ((reg == -1) || (mode == -1) || !label) 190 continue; 191 192 if (mode != 0 || strcmp(label, "temp")) 193 continue; 194 195 memset(buf, 0, sizeof(buf)); 196 if (!gsc_i2c_read(priv->hwmon, reg, buf, sizeof(buf))) { 197 val = buf[0] | buf[1] << 8; 198 if (val > 0x8000) 199 val -= 0xffff; 200 return val; 201 } 202 } 203 204 return 0; 205} 206 207static void gsc_thermal_info(struct udevice *dev) 208{ 209 struct gsc_priv *priv = dev_get_priv(dev); 210 211 switch (priv->gscver) { 212 case 2: 213 printf("board_temp:%dC ", gsc_thermal_get_temp(dev) / 10); 214 break; 215 case 3: 216 if (priv->fwver > 52) { 217 bool enabled; 218 int tmax; 219 220 if (!gsc_thermal_get_info(dev, NULL, &tmax, &enabled)) { 221 puts("Thermal protection:"); 222 if (enabled) 223 printf("enabled at %dC ", tmax); 224 else 225 puts("disabled "); 226 } 227 } 228 break; 229 } 230} 231 232static void gsc_reset_info(struct udevice *dev) 233{ 234 struct gsc_priv *priv = dev_get_priv(dev); 235 static const char * const names[] = { 236 "VIN", 237 "PB", 238 "WDT", 239 "CPU", 240 "TEMP_L", 241 "TEMP_R", 242 "SLEEP", 243 "BOOT_WDT1", 244 "BOOT_WDT2", 245 "SOFT_PWR", 246 }; 247 u8 reg; 248 249 /* reset cause */ 250 switch (priv->gscver) { 251 case 2: 252 if (!gsc_i2c_read(dev, GSC_SC_STATUS, ®, 1)) { 253 if (reg & BIT(GSC_SC_IRQ_WATCHDOG)) { 254 puts("RST:WDT"); 255 reg &= ~BIT(GSC_SC_IRQ_WATCHDOG); 256 gsc_i2c_write(dev, GSC_SC_STATUS, ®, 1); 257 } else { 258 puts("RST:VIN"); 259 } 260 printf(" WDT:%sabled ", 261 (reg & BIT(GSC_SC_CTRL1_WDEN)) ? "en" : "dis"); 262 } 263 break; 264 case 3: 265 if (priv->fwver > 52 && 266 !gsc_i2c_read(dev, GSC_SC_RST_CAUSE, ®, 1)) { 267 puts("RST:"); 268 if (reg < ARRAY_SIZE(names)) 269 printf("%s ", names[reg]); 270 else 271 printf("0x%02x ", reg); 272 } 273 break; 274 } 275} 276 277/* display hardware monitor ADC channels */ 278static int gsc_hwmon(struct udevice *dev) 279{ 280 struct gsc_priv *priv = dev_get_priv(dev); 281 u32 reg, mode, val, offset; 282 const char *label; 283 ofnode node; 284 u8 buf[2]; 285 u32 r[2]; 286 int ret; 287 288 /* iterate over hwmon nodes */ 289 ofnode_for_each_subnode(node, dev_read_subnode(dev, "adc")) { 290 if (ofnode_read_u32(node, "reg", ®)) 291 reg = -1; 292 if (ofnode_read_u32(node, "gw,mode", &mode)) 293 mode = -1; 294 label = ofnode_read_string(node, "label"); 295 if ((reg == -1) || (mode == -1) || !label) 296 continue; 297 298 memset(buf, 0, sizeof(buf)); 299 ret = gsc_i2c_read(priv->hwmon, reg, buf, sizeof(buf)); 300 if (ret) { 301 printf("i2c error: %d\n", ret); 302 continue; 303 } 304 val = buf[0] | buf[1] << 8; 305 306 switch (mode) { 307 case 0: /* temperature (C*10) */ 308 if (val > 0x8000) 309 val -= 0xffff; 310 printf("%-8s: %d.%ldC\n", label, val / 10, abs(val % 10)); 311 break; 312 case 1: /* prescaled voltage */ 313 if (val != 0xffff) 314 printf("%-8s: %d.%03dV\n", label, val / 1000, val % 1000); 315 break; 316 case 2: /* scaled based on ref volt and resolution */ 317 val *= 2500; 318 val /= 1 << 12; 319 320 /* apply pre-scaler voltage divider */ 321 if (!ofnode_read_u32_index(node, "gw,voltage-divider-ohms", 0, &r[0]) && 322 !ofnode_read_u32_index(node, "gw,voltage-divider-ohms", 1, &r[1]) && 323 r[0] && r[1]) { 324 val *= (r[0] + r[1]); 325 val /= r[1]; 326 } 327 328 /* adjust by offset */ 329 val += (offset / 1000); 330 331 printf("%-8s: %d.%03dV\n", label, val / 1000, val % 1000); 332 break; 333 } 334 } 335 336 return 0; 337} 338 339static int gsc_banner(struct udevice *dev) 340{ 341 struct gsc_priv *priv = dev_get_priv(dev); 342 343 /* banner */ 344 printf("GSCv%d : v%d 0x%04x ", priv->gscver, priv->fwver, priv->fwcrc); 345 gsc_reset_info(dev); 346 gsc_thermal_info(dev); 347 puts("\n"); 348 349 /* Display RTC */ 350 if (priv->rtc) { 351 u8 buf[4]; 352 time_t timestamp; 353 struct rtc_time tm; 354 355 if (!gsc_i2c_read(priv->rtc, 0, buf, 4)) { 356 timestamp = get_unaligned_le32(buf); 357 rtc_to_tm(timestamp, &tm); 358 printf("RTC : %4d-%02d-%02d %2d:%02d:%02d UTC\n", 359 tm.tm_year, tm.tm_mon, tm.tm_mday, 360 tm.tm_hour, tm.tm_min, tm.tm_sec); 361 } 362 } 363 364 return 0; 365} 366 367static int gsc_probe(struct udevice *dev) 368{ 369 struct gsc_priv *priv = dev_get_priv(dev); 370 u8 buf[32]; 371 int ret; 372 373 ret = gsc_i2c_read(dev, 0, buf, sizeof(buf)); 374 if (ret) 375 return ret; 376 377 /* 378 * GSC chip version: 379 * GSCv2 has 16 registers (which overlap) 380 * GSCv3 has 32 registers 381 */ 382 priv->gscver = memcmp(buf, buf + 16, 16) ? 3 : 2; 383 priv->fwver = buf[GSC_SC_FWVER]; 384 priv->fwcrc = buf[GSC_SC_FWCRC] | buf[GSC_SC_FWCRC + 1] << 8; 385 priv->hwmon = gsc_get_dev(GSC_BUSNO, GSC_HWMON_ADDR); 386 if (priv->hwmon) 387 dev_set_priv(priv->hwmon, priv); 388 priv->rtc = gsc_get_dev(GSC_BUSNO, GSC_RTC_ADDR); 389 if (priv->rtc) 390 dev_set_priv(priv->rtc, priv); 391 392#ifdef CONFIG_SPL_BUILD 393 gsc_banner(dev); 394#endif 395 396 return 0; 397}; 398 399static const struct udevice_id gsc_ids[] = { 400 { .compatible = "gw,gsc", }, 401 { } 402}; 403 404U_BOOT_DRIVER(gsc) = { 405 .name = "gsc", 406 .id = UCLASS_MISC, 407 .of_match = gsc_ids, 408 .probe = gsc_probe, 409 .priv_auto = sizeof(struct gsc_priv), 410 .flags = DM_FLAG_PRE_RELOC, 411}; 412 413static int gsc_sleep(struct udevice *dev, unsigned long secs) 414{ 415 u8 regs[4]; 416 int ret; 417 418 printf("GSC Sleeping for %ld seconds\n", secs); 419 put_unaligned_le32(secs, regs); 420 ret = gsc_i2c_write(dev, GSC_SC_TIME_ADD, regs, sizeof(regs)); 421 if (ret) 422 goto err; 423 ret = gsc_i2c_read(dev, GSC_SC_CTRL1, regs, 1); 424 if (ret) 425 goto err; 426 regs[0] |= BIT(GSC_SC_CTRL1_SLEEP_ADD); 427 ret = gsc_i2c_write(dev, GSC_SC_CTRL1, regs, 1); 428 if (ret) 429 goto err; 430 regs[0] &= ~BIT(GSC_SC_CTRL1_SLEEP_ADD); 431 regs[0] |= BIT(GSC_SC_CTRL1_SLEEP_EN) | BIT(GSC_SC_CTRL1_SLEEP_ACTIVATE); 432 ret = gsc_i2c_write(dev, GSC_SC_CTRL1, regs, 1); 433 if (ret) 434 goto err; 435 436 return 0; 437 438err: 439 printf("i2c error: %d\n", ret); 440 return ret; 441} 442 443static int gsc_wd_disable(struct udevice *dev) 444{ 445 int ret; 446 u8 reg; 447 448 ret = gsc_i2c_read(dev, GSC_SC_CTRL1, ®, 1); 449 if (ret) 450 goto err; 451 reg |= BIT(GSC_SC_CTRL1_WDDIS); 452 reg &= ~BIT(GSC_SC_CTRL1_BOOT_CHK); 453 ret = gsc_i2c_write(dev, GSC_SC_CTRL1, ®, 1); 454 if (ret) 455 goto err; 456 puts("GSC : boot watchdog disabled\n"); 457 458 return 0; 459 460err: 461 puts("i2c error"); 462 return ret; 463} 464 465static int gsc_thermal(struct udevice *dev, const char *cmd, const char *val) 466{ 467 struct gsc_priv *priv = dev_get_priv(dev); 468 int ret, tmax; 469 bool enabled; 470 u8 reg; 471 472 if (priv->gscver < 3 || priv->fwver < 53) 473 return -EINVAL; 474 ret = gsc_thermal_get_info(dev, ®, &tmax, &enabled); 475 if (ret) 476 return ret; 477 if (cmd && !strcmp(cmd, "enable")) { 478 if (val && *val) { 479 tmax = clamp((int)simple_strtoul(val, NULL, 0), 72, 122); 480 reg &= ~0xf8; 481 reg |= ((tmax - 70) / 2) << 3; 482 } 483 reg |= BIT(0); 484 gsc_i2c_write(dev, GSC_SC_THERM_PROTECT, ®, 1); 485 } else if (cmd && !strcmp(cmd, "disable")) { 486 reg &= ~BIT(0); 487 gsc_i2c_write(dev, GSC_SC_THERM_PROTECT, ®, 1); 488 } else if (cmd) { 489 return -EINVAL; 490 } 491 492 /* show status */ 493 gsc_thermal_info(dev); 494 puts("\n"); 495 496 return 0; 497} 498 499/* override in board files to display additional board EEPROM info */ 500__weak void board_gsc_info(void) 501{ 502} 503 504static void gsc_info(struct udevice *dev) 505{ 506 gsc_banner(dev); 507 board_gsc_info(); 508} 509 510static int do_gsc(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) 511{ 512 struct udevice *dev; 513 int ret; 514 515 /* get/probe driver */ 516 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(gsc), &dev); 517 if (ret) 518 return CMD_RET_USAGE; 519 if (argc < 2) { 520 gsc_info(dev); 521 return CMD_RET_SUCCESS; 522 } else if (strcasecmp(argv[1], "sleep") == 0) { 523 if (argc < 3) 524 return CMD_RET_USAGE; 525 if (!gsc_sleep(dev, dectoul(argv[2], NULL))) 526 return CMD_RET_SUCCESS; 527 } else if (strcasecmp(argv[1], "hwmon") == 0) { 528 if (!gsc_hwmon(dev)) 529 return CMD_RET_SUCCESS; 530 } else if (strcasecmp(argv[1], "wd-disable") == 0) { 531 if (!gsc_wd_disable(dev)) 532 return CMD_RET_SUCCESS; 533 } else if (strcasecmp(argv[1], "thermal") == 0) { 534 const char *cmd, *val; 535 536 cmd = cmd_arg2(argc, argv); 537 val = cmd_arg3(argc, argv); 538 if (!gsc_thermal(dev, cmd, val)) 539 return CMD_RET_SUCCESS; 540 } 541 542 return CMD_RET_USAGE; 543} 544 545U_BOOT_CMD(gsc, 4, 1, do_gsc, "Gateworks System Controller", 546 "[sleep <secs>]|[hwmon]|[wd-disable][thermal [disable|enable [temp]]]\n"); 547 548/* disable boot watchdog - useful for an SPL that wants to use falcon mode */ 549int gsc_boot_wd_disable(void) 550{ 551 struct udevice *dev; 552 int ret; 553 554 /* get/probe driver */ 555 ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(gsc), &dev); 556 if (!ret) 557 ret = gsc_wd_disable(dev); 558 559 return ret; 560} 561 562# else 563 564/* 565 * GSCv2 will fail to ACK an I2C transaction if it is busy, which can occur 566 * during its 1HZ timer tick while reading ADC's. When this does occur, 567 * it will never be busy longer than 2 back-to-back transfers so retry 3 times. 568 */ 569static int gsc_i2c_read(uint chip, uint addr, u8 *buf, int len) 570{ 571 int retry = 3; 572 int n = 0; 573 int ret; 574 575 while (n++ < retry) { 576 ret = i2c_read(chip, addr, 1, buf, len); 577 if (!ret) 578 break; 579 if (ret != -EREMOTEIO) 580 break; 581printf("%s 0x%02x retry %d\n", __func__, addr, n); 582 mdelay(10); 583 } 584 return ret; 585} 586 587static int gsc_i2c_write(uint chip, uint addr, u8 *buf, int len) 588{ 589 int retry = 3; 590 int n = 0; 591 int ret; 592 593 while (n++ < retry) { 594 ret = i2c_write(chip, addr, 1, buf, len); 595 if (!ret) 596 break; 597 if (ret != -EREMOTEIO) 598 break; 599printf("%s 0x%02x retry %d\n", __func__, addr, n); 600 mdelay(10); 601 } 602 return ret; 603} 604 605/* disable boot watchdog - useful for an SPL that wants to use falcon mode */ 606int gsc_boot_wd_disable(void) 607{ 608 u8 buf[32]; 609 int ret; 610 611 i2c_set_bus_num(GSC_BUSNO); 612 ret = gsc_i2c_read(GSC_SC_ADDR, 0, buf, sizeof(buf)); 613 if (!ret) { 614 buf[GSC_SC_CTRL1] |= BIT(GSC_SC_CTRL1_WDDIS); 615 ret = gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, &buf[GSC_SC_CTRL1], 1); 616 printf("GSCv%d: v%d 0x%04x ", 617 memcmp(buf, buf + 16, 16) ? 3 : 2, 618 buf[GSC_SC_FWVER], 619 buf[GSC_SC_FWCRC] | buf[GSC_SC_FWCRC + 1] << 8); 620 if (buf[GSC_SC_STATUS] & BIT(GSC_SC_IRQ_WATCHDOG)) { 621 puts("RST:WDT "); 622 buf[GSC_SC_STATUS] &= ~BIT(GSC_SC_IRQ_WATCHDOG); 623 gsc_i2c_write(GSC_SC_ADDR, GSC_SC_STATUS, &buf[GSC_SC_STATUS], 1); 624 } else { 625 puts("RST:VIN "); 626 } 627 puts("WDT:disabled\n"); 628 } 629 630 return ret; 631} 632 633#endif 634