@@ -124,6 +124,13 @@
/* SPI dummy cycle data */
#define R_DUMMY_DATA (0x54 / 4)
+/* FMC_WDT2 Control/Status Register for Alternate Boot (AST2600) */
+#define R_FMC_WDT2_CTRL (0x64 / 4)
+#define FMC_WDT2_CTRL_ALT_BOOT_MODE BIT(6) /* O: 2 chips 1: 1 chip */
+#define FMC_WDT2_CTRL_SINGLE_BOOT_MODE BIT(5)
+#define FMC_WDT2_CTRL_BOOT_SOURCE BIT(4) /* O: primary 1: alternate */
+#define FMC_WDT2_CTRL_EN BIT(0)
+
/* DMA Control/Status Register */
#define R_DMA_CTRL (0x80 / 4)
#define DMA_CTRL_REQUEST (1 << 31)
@@ -263,12 +270,18 @@ static void aspeed_2600_smc_dma_ctrl(AspeedSMCState *s, uint32_t value);
#define ASPEED_SMC_FEATURE_DMA 0x1
#define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
+#define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
static inline bool aspeed_smc_has_dma(const AspeedSMCState *s)
{
return !!(s->ctrl->features & ASPEED_SMC_FEATURE_DMA);
}
+static inline bool aspeed_smc_has_wdt_control(const AspeedSMCState *s)
+{
+ return !!(s->ctrl->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
+}
+
static const AspeedSMCController controllers[] = {
{
.name = "aspeed.smc-ast2400",
@@ -388,7 +401,8 @@ static const AspeedSMCController controllers[] = {
.segments = aspeed_segments_ast2600_fmc,
.flash_window_base = ASPEED26_SOC_FMC_FLASH_BASE,
.flash_window_size = 0x10000000,
- .features = ASPEED_SMC_FEATURE_DMA,
+ .features = ASPEED_SMC_FEATURE_DMA |
+ ASPEED_SMC_FEATURE_WDT_CONTROL,
.dma_flash_mask = 0x0FFFFFFC,
.dma_dram_mask = 0x3FFFFFFC,
.nregs = ASPEED_SMC_R_MAX,
@@ -1019,6 +1033,7 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
addr == R_CE_CMD_CTRL ||
addr == R_INTR_CTRL ||
addr == R_DUMMY_DATA ||
+ (aspeed_smc_has_wdt_control(s) && addr == R_FMC_WDT2_CTRL) ||
(aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) ||
(aspeed_smc_has_dma(s) && addr == R_DMA_FLASH_ADDR) ||
(aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR) ||
@@ -1350,6 +1365,8 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
s->regs[addr] = value & 0xff;
} else if (addr == R_DUMMY_DATA) {
s->regs[addr] = value & 0xff;
+ } else if (aspeed_smc_has_wdt_control(s) && addr == R_FMC_WDT2_CTRL) {
+ s->regs[addr] = value & FMC_WDT2_CTRL_EN;
} else if (addr == R_INTR_CTRL) {
s->regs[addr] = value;
} else if (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) {