return ret;
}
-#ifdef CONFIG_CMD_GSC
static void read_hwmon(const char *name, uint reg, uint size)
{
unsigned char buf[3];
}
}
-int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int gsc_info(int verbose)
{
const char *model = getenv("model");
+ unsigned char buf[16];
i2c_set_bus_num(0);
+ if (gsc_i2c_read(GSC_SC_ADDR, 0, 1, buf, 16))
+ return CMD_RET_FAILURE;
+
+ printf("GSC: v%d", buf[GSC_SC_FWVER]);
+ printf(" 0x%04x", buf[GSC_SC_FWCRC] | buf[GSC_SC_FWCRC+1]<<8);
+ printf(" WDT:%sabled", (buf[GSC_SC_CTRL1] & (1<<GSC_SC_CTRL1_WDEN))
+ ? "en" : "dis");
+ if (buf[GSC_SC_STATUS] & (1 << GSC_SC_IRQ_WATCHDOG)) {
+ buf[GSC_SC_STATUS] &= ~(1 << GSC_SC_IRQ_WATCHDOG);
+ puts(" WDT_RESET");
+ gsc_i2c_write(GSC_SC_ADDR, GSC_SC_STATUS, 1,
+ &buf[GSC_SC_STATUS], 1);
+ }
+ puts("\n");
+ if (!verbose)
+ return CMD_RET_SUCCESS;
+
read_hwmon("Temp", GSC_HWMON_TEMP, 2);
read_hwmon("VIN", GSC_HWMON_VIN, 3);
read_hwmon("VBATT", GSC_HWMON_VBATT, 3);
return 0;
}
-U_BOOT_CMD(gsc, 1, 1, do_gsc,
- "GSC test",
- ""
-);
+#ifdef CONFIG_CMD_GSC
+static int do_gsc_wd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ unsigned char reg;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ if (strcasecmp(argv[1], "enable") == 0) {
+ int timeout = 0;
+
+ if (argc > 2)
+ timeout = simple_strtoul(argv[2], NULL, 10);
+ i2c_set_bus_num(0);
+ if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1))
+ return CMD_RET_FAILURE;
+ reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME));
+ if (timeout == 60)
+ reg |= (1 << GSC_SC_CTRL1_WDTIME);
+ else
+ timeout = 30;
+ reg |= (1 << GSC_SC_CTRL1_WDEN);
+ if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1))
+ return CMD_RET_FAILURE;
+ printf("GSC Watchdog enabled with timeout=%d seconds\n",
+ timeout);
+ } else if (strcasecmp(argv[1], "disable") == 0) {
+ i2c_set_bus_num(0);
+ if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1))
+ return CMD_RET_FAILURE;
+ reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME));
+ if (gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 1))
+ return CMD_RET_FAILURE;
+ printf("GSC Watchdog disabled\n");
+ } else {
+ return CMD_RET_USAGE;
+ }
+ return CMD_RET_SUCCESS;
+}
+
+static int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ if (argc < 2)
+ return gsc_info(1);
+
+ if (strcasecmp(argv[1], "wd") == 0)
+ return do_gsc_wd(cmdtp, flag, --argc, ++argv);
+
+ return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+ gsc, 4, 1, do_gsc, "GSC configuration",
+ "[wd enable [30|60]]|[wd disable]\n"
+ );
#endif /* CONFIG_CMD_GSC */
GSC_SC_CTRL0 = 0x00,
GSC_SC_CTRL1 = 0x01,
GSC_SC_STATUS = 0x0a,
+ GSC_SC_FWCRC = 0x0c,
GSC_SC_FWVER = 0x0e,
};
/* System Controller Control1 bits */
enum {
- GSC_SC_CTRL1_WDDIS = 7, /* 1 = disable watchdog */
+ GSC_SC_CTRL1_WDTIME = 4, /* 1 = 60s timeout, 0 = 30s timeout */
+ GSC_SC_CTRL1_WDEN = 5, /* 1 = enable, 0 = disable */
+ GSC_SC_CTRL1_WDDIS = 7, /* 1 = disable boot watchdog */
};
/* System Controller Interrupt bits */
*/
int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len);
int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len);
+int gsc_info(int verbose);
#endif
return 0;
/* Display GSC firmware revision/CRC/status */
- i2c_set_bus_num(CONFIG_I2C_GSC);
- if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_FWVER, 1, buf, 1)) {
- printf("GSC: v%d", buf[0]);
- if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_STATUS, 1, buf, 4)) {
- printf(" 0x%04x", buf[2] | buf[3]<<8); /* CRC */
- printf(" 0x%02x", buf[0]); /* irq status */
- }
- puts("\n");
- }
+ gsc_info(0);
+
/* Display RTC */
if (!gsc_i2c_read(GSC_RTC_ADDR, 0x00, 1, buf, 4)) {
printf("RTC: %d\n",
} else {
puts("Error: could not disable GSC Watchdog\n");
}
- if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_STATUS, 1, ®, 1)) {
- if (reg & (1 << GSC_SC_IRQ_WATCHDOG)) { /* watchdog timeout */
- puts("GSC boot watchdog timeout detected\n");
- reg &= ~(1 << GSC_SC_IRQ_WATCHDOG); /* clear flag */
- gsc_i2c_write(GSC_SC_ADDR, GSC_SC_STATUS, 1, ®, 1);
- }
- }
return 0;
}