diff options
author | Joel Stanley <joel@jms.id.au> | 2020-09-01 14:21:51 +0200 |
---|---|---|
committer | Cédric Le Goater <clg@kaod.org> | 2020-09-01 14:21:51 +0200 |
commit | 14c179541bbf083f4b215ddb389828ad8b9d0b28 (patch) | |
tree | c620b503af9345237463bd9f3e7adc5ffe30c634 /hw/misc | |
parent | e0059c8883944605d1f5c4dc9c60a881c4b3be39 (diff) |
aspeed/sdmc: Perform memory training
This allows qemu to run the "normal" power on reset boot path through
u-boot, where the DDR is trained.
An enhancement would be to have the SCU bit stick across qemu reboots,
but be unset on initial boot.
Proper modelling would be to discard all writes to the phy setting regs
at offset 0x100 - 0x400 and to model the phy status regs at offset
0x400.
The status regs model would only need to account for offets 0x00,
0x50, 0x68 and 0x7c.
Signed-off-by: Joel Stanley <joel@jms.id.au>
[ clg: checkpatch fixes ]
Message-Id: <20200819100956.2216690-17-clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'hw/misc')
-rw-r--r-- | hw/misc/aspeed_scu.c | 2 | ||||
-rw-r--r-- | hw/misc/aspeed_sdmc.c | 19 |
2 files changed, 18 insertions, 3 deletions
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index 764222404b..dc6dd87c22 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -656,7 +656,7 @@ static const uint32_t ast2600_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = { [AST2600_SYS_RST_CTRL2] = 0xFFFFFFFC, [AST2600_CLK_STOP_CTRL] = 0xFFFF7F8A, [AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0, - [AST2600_SDRAM_HANDSHAKE] = 0x00000040, /* SoC completed DRAM init */ + [AST2600_SDRAM_HANDSHAKE] = 0x00000000, [AST2600_HPLL_PARAM] = 0x1000405F, [AST2600_CHIP_ID0] = 0x1234ABCD, [AST2600_CHIP_ID1] = 0x88884444, diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c index 855848b7d2..ff2809a099 100644 --- a/hw/misc/aspeed_sdmc.c +++ b/hw/misc/aspeed_sdmc.c @@ -113,7 +113,7 @@ static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size) if (addr >= ARRAY_SIZE(s->regs)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n", - __func__, addr); + __func__, addr * 4); return 0; } @@ -206,6 +206,19 @@ static void aspeed_sdmc_reset(DeviceState *dev) /* Set ram size bit and defaults values */ s->regs[R_CONF] = asc->compute_conf(s, 0); + + /* + * PHY status: + * - set phy status ok (set bit 1) + * - initial PVT calibration ok (clear bit 3) + * - runtime calibration ok (clear bit 5) + */ + s->regs[0x100] = BIT(1); + + /* PHY eye window: set all as passing */ + s->regs[0x100 | (0x68 / 4)] = 0xff; + s->regs[0x100 | (0x7c / 4)] = 0xff; + s->regs[0x100 | (0x50 / 4)] = 0xfffffff; } static void aspeed_sdmc_get_ram_size(Object *obj, Visitor *v, const char *name, @@ -443,7 +456,9 @@ static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg, } if (reg != R_PROT && s->regs[R_PROT] == PROT_SOFTLOCKED) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__); + qemu_log_mask(LOG_GUEST_ERROR, + "%s: SDMC is locked! (write to MCR%02x blocked)\n", + __func__, reg * 4); return; } |