diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-09-03 14:12:48 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-09-03 14:12:48 +0100 |
commit | 3dd23a4fb8fd72d2220a90a809f213999ffe7f3a (patch) | |
tree | e45f68da4c497881301b8b773817810f0acdde02 /hw/misc | |
parent | e4d8b7c1a95fffcfa4bdab9aa7ffd1cf590cdcf5 (diff) | |
parent | ddd8ab19749b8639fc08bfe4d0df0204eec049f0 (diff) |
Merge remote-tracking branch 'remotes/legoater/tags/pull-aspeed-20200901' into staging
Various fixes of Aspeed machines :
* New Supermicro X11 BMC machine (Erik)
* Fixed valid access size on AST2400 SCU
* Improved robustness of the ftgmac100 model.
* New flash models in m25p80 (Igor)
* Fixed reset sequence of SDHCI/eMMC controllers
* Improved support of the AST2600 SDMC (Joel)
* Couple of SMC cleanups
# gpg: Signature made Tue 01 Sep 2020 13:39:20 BST
# gpg: using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: A0F6 6548 F048 95EB FE6B 0B60 51A3 43C7 CFFB ECA1
* remotes/legoater/tags/pull-aspeed-20200901:
hw: add a number of SPI-flash's of m25p80 family
arm: aspeed: add strap define `25HZ` of AST2500
aspeed/smc: Open AHB window of the second chip of the AST2600 FMC controller
aspeed/sdmc: Simplify calculation of RAM bits
aspeed/sdmc: Allow writes to unprotected registers
aspeed/sdmc: Perform memory training
ftgmac100: Improve software reset
ftgmac100: Fix integer overflow in ftgmac100_do_tx()
ftgmac100: Check for invalid len and address before doing a DMA transfer
ftgmac100: Change interrupt status when a DMA error occurs
ftgmac100: Fix interrupt status "Packet moved to RX FIFO"
ftgmac100: Fix interrupt status "Packet transmitted on ethernet"
ftgmac100: Fix registers that can be read
aspeed/sdhci: Fix reset sequence
aspeed/smc: Fix max_slaves of the legacy SMC device
aspeed/smc: Fix MemoryRegionOps definition
hw/arm/aspeed: Add board model for Supermicro X11 BMC
aspeed/scu: Fix valid access size on AST2400
m25p80: Add support for n25q512ax3
m25p80: Return the JEDEC ID twice for mx25l25635e
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/misc')
-rw-r--r-- | hw/misc/aspeed_scu.c | 9 | ||||
-rw-r--r-- | hw/misc/aspeed_sdmc.c | 125 |
2 files changed, 74 insertions, 60 deletions
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index ec4fef900e..dc6dd87c22 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -328,9 +328,10 @@ static const MemoryRegionOps aspeed_ast2400_scu_ops = { .read = aspeed_scu_read, .write = aspeed_ast2400_scu_write, .endianness = DEVICE_LITTLE_ENDIAN, - .valid.min_access_size = 4, - .valid.max_access_size = 4, - .valid.unaligned = false, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, }; static const MemoryRegionOps aspeed_ast2500_scu_ops = { @@ -655,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..08f856cbda 100644 --- a/hw/misc/aspeed_sdmc.c +++ b/hw/misc/aspeed_sdmc.c @@ -33,15 +33,28 @@ /* Configuration Register */ #define R_CONF (0x04 / 4) +/* Interrupt control/status */ +#define R_ISR (0x50 / 4) + /* Control/Status Register #1 (ast2500) */ #define R_STATUS1 (0x60 / 4) #define PHY_BUSY_STATE BIT(0) #define PHY_PLL_LOCK_STATUS BIT(4) +/* Reserved */ +#define R_MCR6C (0x6c / 4) + #define R_ECC_TEST_CTRL (0x70 / 4) #define ECC_TEST_FINISHED BIT(12) #define ECC_TEST_FAIL BIT(13) +#define R_TEST_START_LEN (0x74 / 4) +#define R_TEST_FAIL_DQ (0x78 / 4) +#define R_TEST_INIT_VAL (0x7c / 4) +#define R_DRAM_SW (0x88 / 4) +#define R_DRAM_TIME (0x8c / 4) +#define R_ECC_ERR_INJECT (0xb4 / 4) + /* * Configuration register Ox4 (for Aspeed AST2400 SOC) * @@ -113,7 +126,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; } @@ -146,57 +159,6 @@ static const MemoryRegionOps aspeed_sdmc_ops = { .valid.max_access_size = 4, }; -static int ast2400_rambits(AspeedSDMCState *s) -{ - switch (s->ram_size >> 20) { - case 64: - return ASPEED_SDMC_DRAM_64MB; - case 128: - return ASPEED_SDMC_DRAM_128MB; - case 256: - return ASPEED_SDMC_DRAM_256MB; - case 512: - return ASPEED_SDMC_DRAM_512MB; - default: - g_assert_not_reached(); - break; - } -} - -static int ast2500_rambits(AspeedSDMCState *s) -{ - switch (s->ram_size >> 20) { - case 128: - return ASPEED_SDMC_AST2500_128MB; - case 256: - return ASPEED_SDMC_AST2500_256MB; - case 512: - return ASPEED_SDMC_AST2500_512MB; - case 1024: - return ASPEED_SDMC_AST2500_1024MB; - default: - g_assert_not_reached(); - break; - } -} - -static int ast2600_rambits(AspeedSDMCState *s) -{ - switch (s->ram_size >> 20) { - case 256: - return ASPEED_SDMC_AST2600_256MB; - case 512: - return ASPEED_SDMC_AST2600_512MB; - case 1024: - return ASPEED_SDMC_AST2600_1024MB; - case 2048: - return ASPEED_SDMC_AST2600_2048MB; - default: - g_assert_not_reached(); - break; - } -} - static void aspeed_sdmc_reset(DeviceState *dev) { AspeedSDMCState *s = ASPEED_SDMC(dev); @@ -206,6 +168,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, @@ -298,10 +273,32 @@ static const TypeInfo aspeed_sdmc_info = { .abstract = true, }; +static int aspeed_sdmc_get_ram_bits(AspeedSDMCState *s) +{ + AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s); + int i; + + /* + * The bitfield value encoding the RAM size is the index of the + * possible RAM size array + */ + for (i = 0; asc->valid_ram_sizes[i]; i++) { + if (s->ram_size == asc->valid_ram_sizes[i]) { + return i; + } + } + + /* + * Invalid RAM sizes should have been excluded when setting the + * SoC RAM size. + */ + g_assert_not_reached(); +} + static uint32_t aspeed_2400_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data) { uint32_t fixed_conf = ASPEED_SDMC_VGA_COMPAT | - ASPEED_SDMC_DRAM_SIZE(ast2400_rambits(s)); + ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s)); /* Make sure readonly bits are kept */ data &= ~ASPEED_SDMC_READONLY_MASK; @@ -359,7 +356,7 @@ static uint32_t aspeed_2500_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data) uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(1) | ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) | ASPEED_SDMC_CACHE_INITIAL_DONE | - ASPEED_SDMC_DRAM_SIZE(ast2500_rambits(s)); + ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s)); /* Make sure readonly bits are kept */ data &= ~ASPEED_SDMC_AST2500_READONLY_MASK; @@ -425,7 +422,7 @@ static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data) { uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(3) | ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) | - ASPEED_SDMC_DRAM_SIZE(ast2600_rambits(s)); + ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s)); /* Make sure readonly bits are kept (use ast2500 mask) */ data &= ~ASPEED_SDMC_AST2500_READONLY_MASK; @@ -436,6 +433,20 @@ static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data) static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg, uint32_t data) { + /* Unprotected registers */ + switch (reg) { + case R_ISR: + case R_MCR6C: + case R_TEST_START_LEN: + case R_TEST_FAIL_DQ: + case R_TEST_INIT_VAL: + case R_DRAM_SW: + case R_DRAM_TIME: + case R_ECC_ERR_INJECT: + s->regs[reg] = data; + return; + } + if (s->regs[R_PROT] == PROT_HARDLOCKED) { qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system reset!\n", __func__); @@ -443,7 +454,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; } |