aboutsummaryrefslogtreecommitdiff
path: root/hw/misc
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-09-03 14:12:48 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-09-03 14:12:48 +0100
commit3dd23a4fb8fd72d2220a90a809f213999ffe7f3a (patch)
treee45f68da4c497881301b8b773817810f0acdde02 /hw/misc
parente4d8b7c1a95fffcfa4bdab9aa7ffd1cf590cdcf5 (diff)
parentddd8ab19749b8639fc08bfe4d0df0204eec049f0 (diff)
downloadqemu-3dd23a4fb8fd72d2220a90a809f213999ffe7f3a.zip
qemu-3dd23a4fb8fd72d2220a90a809f213999ffe7f3a.tar.gz
qemu-3dd23a4fb8fd72d2220a90a809f213999ffe7f3a.tar.bz2
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.c9
-rw-r--r--hw/misc/aspeed_sdmc.c125
2 files changed, 74 insertions, 60 deletions
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index ec4fef9..dc6dd87 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 855848b..08f856c 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;
}