summaryrefslogtreecommitdiffstats
path: root/hw/misc/aspeed_scu.c
diff options
context:
space:
mode:
authorRichard Henderson2022-05-03 16:05:39 +0200
committerRichard Henderson2022-05-03 16:05:39 +0200
commit5f14cfe187e2fc3c71f4536b2021b8118d224239 (patch)
treea45e5abd752ac09f7379a0a23d08a761b8d89a53 /hw/misc/aspeed_scu.c
parentMerge tag 'pull-9p-20220501' of https://github.com/cschoenebeck/qemu into sta... (diff)
parentaspeed/hace: Support AST1030 HACE (diff)
downloadqemu-5f14cfe187e2fc3c71f4536b2021b8118d224239.tar.gz
qemu-5f14cfe187e2fc3c71f4536b2021b8118d224239.tar.xz
qemu-5f14cfe187e2fc3c71f4536b2021b8118d224239.zip
Merge tag 'pull-aspeed-20220503' of https://github.com/legoater/qemu into staging
aspeed queue: * New AST1030 SoC and eval board * Accumulative mode support for HACE controller * GPIO fix and unit test * Clock modeling adjustments for the AST2600 * Dummy eMMC Boot Controller model * Change of AST2500 EVB and AST2600 EVB flash model (for quad IO) # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmJwwq8ACgkQUaNDx8/7 # 7KF0IhAApbCCcg06PR66pmaDBFY2RWmU0XShDoCEeHyT5huQFcAJWNoqVAJ52E8L # ZCPEeORQthxMwmtw7JLIGCFhDx4P4YzfNZRPANRosKs7BR0GequVgHp7c6fXhD/3 # A3w42hfuNR4Hrbsil/yhN2vxFAYXudA+NPez2ibex3UyVc/ZUu71nCqZTxh3wZdN # XQTuqxWerA5RRBRtVn8n/aBp+3mo5enD4dx44KWMZxKxJaFJfZQHVZttGHU9azF+ # fXJ1lmrJZ7eHmWjCEvgnHXwl0nWiMwkLZ9/MKOAPkdjUG1JciGRxbJki0bGuS7Jr # NzOyO0f++ZtOsuLGA03WiwR1oo3GmG7lBFqBcdzMwN2EMvDvVvJUp3v8IdV/L10P # OJ10rBi6FDJuKGHJGIQywlFSYYjPb+DgNEWId2rugVVm4dR02Cn69amuL40OO9by # /C7hO9gSvRTqSSdjFcdkbI2h+kx0354F2/gR2LFLBh1KUHulTJ4ErthrKBiuNPC8 # tsELzYVnxWVT+nc30Nmidg3uCW3/5zBlaj0qlL4aiFjKR5na6Wpz+oE/aNiNdyT3 # IBI+J5zvbtn/prNTWLW1TCuGdwj357LfYfkfkH8eqZWfX5vGq+5hVTc/m8EW5Cx8 # yV8JrbjX8uDI379skdl4imtedbKZhPLd7csM/zrorsJhBBwSoLA= # =+hIh # -----END PGP SIGNATURE----- # gpg: Signature made Mon 02 May 2022 10:50:39 PM PDT # 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 * tag 'pull-aspeed-20220503' of https://github.com/legoater/qemu: aspeed/hace: Support AST1030 HACE hw/gpio/aspeed_gpio: Fix QOM pin property tests/qtest: Add test for Aspeed HACE accumulative mode aspeed/hace: Support AST2600 HACE aspeed/hace: Support HMAC Key Buffer register. hw/arm/aspeed: fix AST2500/AST2600 EVB fmc model test/avocado/machine_aspeed.py: Add ast1030 test case aspeed: Add an AST1030 eval board aspeed/soc : Add AST1030 support aspeed/scu: Add AST1030 support aspeed/timer: Add AST1030 support aspeed/wdt: Add AST1030 support aspeed/wdt: Fix ast2500/ast2600 default reload value aspeed/smc: Add AST1030 support aspeed/adc: Add AST1030 support aspeed: Add eMMC Boot Controller stub aspeed: sbc: Correct default reset values hw: aspeed_scu: Introduce clkin_25Mhz attribute hw: aspeed_scu: Add AST2600 apb_freq and hpll calculation function Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/misc/aspeed_scu.c')
-rw-r--r--hw/misc/aspeed_scu.c108
1 files changed, 106 insertions, 2 deletions
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index d06e179a6e..19b03471fc 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -214,6 +214,11 @@ static uint32_t aspeed_scu_get_random(void)
uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s)
{
+ return ASPEED_SCU_GET_CLASS(s)->get_apb(s);
+}
+
+static uint32_t aspeed_2400_scu_get_apb_freq(AspeedSCUState *s)
+{
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
uint32_t hpll = asc->calc_hpll(s, s->regs[HPLL_PARAM]);
@@ -221,6 +226,24 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s)
/ asc->apb_divider;
}
+static uint32_t aspeed_2600_scu_get_apb_freq(AspeedSCUState *s)
+{
+ AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+ uint32_t hpll = asc->calc_hpll(s, s->regs[AST2600_HPLL_PARAM]);
+
+ return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[AST2600_CLK_SEL]) + 1)
+ / asc->apb_divider;
+}
+
+static uint32_t aspeed_1030_scu_get_apb_freq(AspeedSCUState *s)
+{
+ AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+ uint32_t hpll = asc->calc_hpll(s, s->regs[AST2600_HPLL_PARAM]);
+
+ return hpll / (SCU_AST1030_CLK_GET_PCLK_DIV(s->regs[AST2600_CLK_SEL4]) + 1)
+ / asc->apb_divider;
+}
+
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
{
AspeedSCUState *s = ASPEED_SCU(opaque);
@@ -357,7 +380,8 @@ static const MemoryRegionOps aspeed_ast2500_scu_ops = {
static uint32_t aspeed_scu_get_clkin(AspeedSCUState *s)
{
- if (s->hw_strap1 & SCU_HW_STRAP_CLK_25M_IN) {
+ if (s->hw_strap1 & SCU_HW_STRAP_CLK_25M_IN ||
+ ASPEED_SCU_GET_CLASS(s)->clkin_25Mhz) {
return 25000000;
} else if (s->hw_strap1 & SCU_HW_STRAP_CLK_48M_IN) {
return 48000000;
@@ -426,6 +450,26 @@ static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
return clkin * multiplier;
}
+static uint32_t aspeed_2600_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
+{
+ uint32_t multiplier = 1;
+ uint32_t clkin = aspeed_scu_get_clkin(s);
+
+ if (hpll_reg & SCU_AST2600_H_PLL_OFF) {
+ return 0;
+ }
+
+ if (!(hpll_reg & SCU_AST2600_H_PLL_BYPASS_EN)) {
+ uint32_t p = (hpll_reg >> 19) & 0xf;
+ uint32_t n = (hpll_reg >> 13) & 0x3f;
+ uint32_t m = hpll_reg & 0x1fff;
+
+ multiplier = ((m + 1) / (n + 1)) / (p + 1);
+ }
+
+ return clkin * multiplier;
+}
+
static void aspeed_scu_reset(DeviceState *dev)
{
AspeedSCUState *s = ASPEED_SCU(dev);
@@ -447,6 +491,8 @@ static uint32_t aspeed_silicon_revs[] = {
AST2600_A1_SILICON_REV,
AST2600_A2_SILICON_REV,
AST2600_A3_SILICON_REV,
+ AST1030_A0_SILICON_REV,
+ AST1030_A1_SILICON_REV,
};
bool is_supported_silicon_rev(uint32_t silicon_rev)
@@ -525,8 +571,10 @@ static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2400 System Control Unit";
asc->resets = ast2400_a0_resets;
asc->calc_hpll = aspeed_2400_scu_calc_hpll;
+ asc->get_apb = aspeed_2400_scu_get_apb_freq;
asc->apb_divider = 2;
asc->nr_regs = ASPEED_SCU_NR_REGS;
+ asc->clkin_25Mhz = false;
asc->ops = &aspeed_ast2400_scu_ops;
}
@@ -545,8 +593,10 @@ static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2500 System Control Unit";
asc->resets = ast2500_a1_resets;
asc->calc_hpll = aspeed_2500_scu_calc_hpll;
+ asc->get_apb = aspeed_2400_scu_get_apb_freq;
asc->apb_divider = 4;
asc->nr_regs = ASPEED_SCU_NR_REGS;
+ asc->clkin_25Mhz = false;
asc->ops = &aspeed_ast2500_scu_ops;
}
@@ -716,9 +766,11 @@ static void aspeed_2600_scu_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2600 System Control Unit";
dc->reset = aspeed_ast2600_scu_reset;
asc->resets = ast2600_a3_resets;
- asc->calc_hpll = aspeed_2500_scu_calc_hpll; /* No change since AST2500 */
+ asc->calc_hpll = aspeed_2600_scu_calc_hpll;
+ asc->get_apb = aspeed_2600_scu_get_apb_freq;
asc->apb_divider = 4;
asc->nr_regs = ASPEED_AST2600_SCU_NR_REGS;
+ asc->clkin_25Mhz = true;
asc->ops = &aspeed_ast2600_scu_ops;
}
@@ -729,12 +781,64 @@ static const TypeInfo aspeed_2600_scu_info = {
.class_init = aspeed_2600_scu_class_init,
};
+static const uint32_t ast1030_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = {
+ [AST2600_SYS_RST_CTRL] = 0xFFC3FED8,
+ [AST2600_SYS_RST_CTRL2] = 0x09FFFFFC,
+ [AST2600_CLK_STOP_CTRL] = 0xFFFF7F8A,
+ [AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
+ [AST2600_DEBUG_CTRL2] = 0x00000000,
+ [AST2600_HPLL_PARAM] = 0x10004077,
+ [AST2600_HPLL_EXT] = 0x00000031,
+ [AST2600_CLK_SEL4] = 0x43F90900,
+ [AST2600_CLK_SEL5] = 0x40000000,
+ [AST2600_CHIP_ID0] = 0xDEADBEEF,
+ [AST2600_CHIP_ID1] = 0x0BADCAFE,
+};
+
+static void aspeed_ast1030_scu_reset(DeviceState *dev)
+{
+ AspeedSCUState *s = ASPEED_SCU(dev);
+ AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
+
+ memcpy(s->regs, asc->resets, asc->nr_regs * 4);
+
+ s->regs[AST2600_SILICON_REV] = AST1030_A1_SILICON_REV;
+ s->regs[AST2600_SILICON_REV2] = s->silicon_rev;
+ s->regs[AST2600_HW_STRAP1] = s->hw_strap1;
+ s->regs[AST2600_HW_STRAP2] = s->hw_strap2;
+ s->regs[PROT_KEY] = s->hw_prot_key;
+}
+
+static void aspeed_1030_scu_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
+
+ dc->desc = "ASPEED 1030 System Control Unit";
+ dc->reset = aspeed_ast1030_scu_reset;
+ asc->resets = ast1030_a1_resets;
+ asc->calc_hpll = aspeed_2600_scu_calc_hpll;
+ asc->get_apb = aspeed_1030_scu_get_apb_freq;
+ asc->apb_divider = 2;
+ asc->nr_regs = ASPEED_AST2600_SCU_NR_REGS;
+ asc->clkin_25Mhz = true;
+ asc->ops = &aspeed_ast2600_scu_ops;
+}
+
+static const TypeInfo aspeed_1030_scu_info = {
+ .name = TYPE_ASPEED_1030_SCU,
+ .parent = TYPE_ASPEED_SCU,
+ .instance_size = sizeof(AspeedSCUState),
+ .class_init = aspeed_1030_scu_class_init,
+};
+
static void aspeed_scu_register_types(void)
{
type_register_static(&aspeed_scu_info);
type_register_static(&aspeed_2400_scu_info);
type_register_static(&aspeed_2500_scu_info);
type_register_static(&aspeed_2600_scu_info);
+ type_register_static(&aspeed_1030_scu_info);
}
type_init(aspeed_scu_register_types);