aspeed/sdmc: Add AST2600 support
The AST2600 SDMC controller is slightly different from its predecessor (DRAM training). Max memory is now 2G on the AST2600. Signed-off-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-id: 20190925143248.10000-10-clg@kaod.org [clg: - improved commit log - reworked model integration into new object class ] Signed-off-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
8e00d1a97d
commit
1550d72679
|
@ -99,6 +99,7 @@
|
|||
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
|
||||
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
|
||||
#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94)
|
||||
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
|
||||
#define AST2600_HPLL_PARAM TO_REG(0x200)
|
||||
#define AST2600_HPLL_EXT TO_REG(0x204)
|
||||
#define AST2600_MPLL_EXT TO_REG(0x224)
|
||||
|
@ -602,6 +603,7 @@ static const uint32_t ast2600_a0_resets[ASPEED_AST2600_SCU_NR_REGS] = {
|
|||
[AST2600_SYS_RST_CTRL2] = 0xFFFFFFFC,
|
||||
[AST2600_CLK_STOP_CTRL] = 0xEFF43E8B,
|
||||
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
|
||||
[AST2600_SDRAM_HANDSHAKE] = 0x00000040, /* SoC completed DRAM init */
|
||||
[AST2600_HPLL_PARAM] = 0x1000405F,
|
||||
};
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
/* Control/Status Register #1 (ast2500) */
|
||||
#define R_STATUS1 (0x60 / 4)
|
||||
#define PHY_BUSY_STATE BIT(0)
|
||||
#define PHY_PLL_LOCK_STATUS BIT(4)
|
||||
|
||||
#define R_ECC_TEST_CTRL (0x70 / 4)
|
||||
#define ECC_TEST_FINISHED BIT(12)
|
||||
|
@ -85,6 +86,11 @@
|
|||
#define ASPEED_SDMC_AST2500_512MB 0x2
|
||||
#define ASPEED_SDMC_AST2500_1024MB 0x3
|
||||
|
||||
#define ASPEED_SDMC_AST2600_256MB 0x0
|
||||
#define ASPEED_SDMC_AST2600_512MB 0x1
|
||||
#define ASPEED_SDMC_AST2600_1024MB 0x2
|
||||
#define ASPEED_SDMC_AST2600_2048MB 0x3
|
||||
|
||||
#define ASPEED_SDMC_AST2500_READONLY_MASK \
|
||||
(ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE | \
|
||||
ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT | \
|
||||
|
@ -186,6 +192,28 @@ static int ast2500_rambits(AspeedSDMCState *s)
|
|||
return ASPEED_SDMC_AST2500_512MB;
|
||||
}
|
||||
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
||||
/* use a common default */
|
||||
warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
|
||||
s->ram_size);
|
||||
s->ram_size = 512 << 20;
|
||||
return ASPEED_SDMC_AST2600_512MB;
|
||||
}
|
||||
|
||||
static void aspeed_sdmc_reset(DeviceState *dev)
|
||||
{
|
||||
AspeedSDMCState *s = ASPEED_SDMC(dev);
|
||||
|
@ -340,11 +368,65 @@ static const TypeInfo aspeed_2500_sdmc_info = {
|
|||
.class_init = aspeed_2500_sdmc_class_init,
|
||||
};
|
||||
|
||||
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));
|
||||
|
||||
/* Make sure readonly bits are kept (use ast2500 mask) */
|
||||
data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
|
||||
|
||||
return data | fixed_conf;
|
||||
}
|
||||
|
||||
static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
|
||||
uint32_t data)
|
||||
{
|
||||
switch (reg) {
|
||||
case R_CONF:
|
||||
data = aspeed_2600_sdmc_compute_conf(s, data);
|
||||
break;
|
||||
case R_STATUS1:
|
||||
/* Will never return 'busy'. 'lock status' is always set */
|
||||
data &= ~PHY_BUSY_STATE;
|
||||
data |= PHY_PLL_LOCK_STATUS;
|
||||
break;
|
||||
case R_ECC_TEST_CTRL:
|
||||
/* Always done, always happy */
|
||||
data |= ECC_TEST_FINISHED;
|
||||
data &= ~ECC_TEST_FAIL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
s->regs[reg] = data;
|
||||
}
|
||||
|
||||
static void aspeed_2600_sdmc_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2600 SDRAM Memory Controller";
|
||||
asc->max_ram_size = 2048 << 20;
|
||||
asc->compute_conf = aspeed_2600_sdmc_compute_conf;
|
||||
asc->write = aspeed_2600_sdmc_write;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2600_sdmc_info = {
|
||||
.name = TYPE_ASPEED_2600_SDMC,
|
||||
.parent = TYPE_ASPEED_SDMC,
|
||||
.class_init = aspeed_2600_sdmc_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_sdmc_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_sdmc_info);
|
||||
type_register_static(&aspeed_2400_sdmc_info);
|
||||
type_register_static(&aspeed_2500_sdmc_info);
|
||||
type_register_static(&aspeed_2600_sdmc_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_sdmc_register_types);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define ASPEED_SDMC(obj) OBJECT_CHECK(AspeedSDMCState, (obj), TYPE_ASPEED_SDMC)
|
||||
#define TYPE_ASPEED_2400_SDMC TYPE_ASPEED_SDMC "-ast2400"
|
||||
#define TYPE_ASPEED_2500_SDMC TYPE_ASPEED_SDMC "-ast2500"
|
||||
#define TYPE_ASPEED_2600_SDMC TYPE_ASPEED_SDMC "-ast2600"
|
||||
|
||||
#define ASPEED_SDMC_NR_REGS (0x174 >> 2)
|
||||
|
||||
|
|
Loading…
Reference in a new issue