From: Chao Liu <chao.liu@processmission.com>
To: Junze Cao <caojunze424@gmail.com>
Cc: qemu-devel@nongnu.org, qemu-riscv@nongnu.org,
pierrick.bouvier@oss.qualcomm.com, palmer@dabbelt.com,
alistair.francis@wdc.com, liwei1518@gmail.com,
daniel.barboza@oss.qualcomm.com, zhiwei_liu@linux.alibaba.com,
farosas@suse.de, lvivier@redhat.com, pbonzini@redhat.com
Subject: Re: [PATCH 3/3] tests/qtest: Add K230 DDR controller tests
Date: Thu, 23 Jul 2026 16:42:28 +0800 [thread overview]
Message-ID: <amHT6_8b9qEbtGO8@ChaodeMacBook-Pro.local> (raw)
In-Reply-To: <20260716132423.931427-4-caojunze424@gmail.com>
On Thu, Jul 16, 2026 at 09:24:23PM +0800, Junze Cao wrote:
> Add qtests for DDRC and PHY reset values, register access policy, the
> software-update handshake, and PHY register ownership.
>
> Exercise PHY training and mailbox acknowledgement through the DFI
> initialization sequence. Include negative coverage to ensure DFI cannot
> complete before PHY training or enter Normal mode before completion is
> enabled.
>
> Signed-off-by: Junze Cao <caojunze424@gmail.com>
Suggested-by: Chao Liu <chao.liu@processmission.com>
Thanks,
Chao
> ---
> MAINTAINERS | 1 +
> tests/qtest/k230-ddr-test.c | 226 ++++++++++++++++++++++++++++++++++++
> tests/qtest/meson.build | 3 +-
> 3 files changed, 229 insertions(+), 1 deletion(-)
> create mode 100644 tests/qtest/k230-ddr-test.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1cb3ef6c02..ace7def55e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1833,6 +1833,7 @@ F: include/hw/misc/k230_ddr.h
> F: include/hw/riscv/k230.h
> F: include/hw/watchdog/k230_wdt.h
> F: tests/functional/riscv64/test_k230.py
> +F: tests/qtest/k230-ddr-test.c
> F: tests/qtest/k230-wdt-test.c
>
> RX Machines
> diff --git a/tests/qtest/k230-ddr-test.c b/tests/qtest/k230-ddr-test.c
> new file mode 100644
> index 0000000000..72362929bc
> --- /dev/null
> +++ b/tests/qtest/k230-ddr-test.c
> @@ -0,0 +1,226 @@
> +/*
> + * QTest testcase for the K230 DDR controller and PHY
> + *
> + * Exercises register access, reset, PHY ownership, training mailbox, and DFI
> + * initialization.
> + *
> + * Copyright (c) 2026 Junze Cao <caojunze424@gmail.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "libqtest.h"
> +
> +#define K230_DDRC_BASE UINT64_C(0x98000000)
> +#define K230_DDR_PHY_BASE UINT64_C(0x9a000000)
> +
> +#define K230_DDRC_MSTR 0x000
> +#define K230_DDRC_STAT 0x004
> +#define K230_DDRC_DRAMTMG4 0x110
> +#define K230_DDRC_DFIMISC 0x1b0
> +#define K230_DDRC_DFISTAT 0x1bc
> +#define K230_DDRC_SWCTL 0x320
> +#define K230_DDRC_SWSTAT 0x324
> +
> +#define K230_DDRC_STAT_OPERATING_MODE_MASK 0x7
> +#define K230_DDRC_DFISTAT_DFI_INIT_COMPLETE_MASK 0x1
> +
> +#define K230_DDR_PHY_CSR(index) \
> + (K230_DDR_PHY_BASE + (uint64_t)(index) * sizeof(uint32_t))
> +
> +#define K230_DDR_PHY_ATX_IMPEDANCE 0x00043
> +#define K230_DDR_PHY_TX_IMPEDANCE_CTRL1 0x10049
> +#define K230_DDR_PHY_VREF_IN_GLOBAL 0x200b2
> +#define K230_DDR_PHY_MICRO_CONT_MUX_SEL 0xd0000
> +#define K230_DDR_PHY_TRAINING_STATUS 0xd0004
> +#define K230_DDR_PHY_TRAINING_ACK 0xd0031
> +#define K230_DDR_PHY_TRAINING_MESSAGE 0xd0032
> +#define K230_DDR_PHY_TRAINING_TRIGGER 0xd0099
> +
> +static void complete_phy_training(QTestState *qts)
> +{
> + qtest_writel(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_MICRO_CONT_MUX_SEL), 1);
> + qtest_writel(qts, K230_DDR_PHY_CSR(K230_DDR_PHY_TRAINING_TRIGGER), 9);
> + qtest_writel(qts, K230_DDR_PHY_CSR(K230_DDR_PHY_TRAINING_TRIGGER), 1);
> + qtest_writel(qts, K230_DDR_PHY_CSR(K230_DDR_PHY_TRAINING_TRIGGER), 0);
> +}
> +
> +static void test_reset_and_register_access(void)
> +{
> + QTestState *qts = qtest_init("-machine k230");
> +
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_MSTR),
> + ==, 0x01040000);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_STAT),
> + ==, 0x00000000);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_DRAMTMG4),
> + ==, 0x05040405);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_DFIMISC),
> + ==, 0x00000001);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_SWCTL),
> + ==, 0x00000001);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_SWSTAT),
> + ==, 0x00000001);
> +
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_ATX_IMPEDANCE)),
> + ==, 0x03ff);
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_TX_IMPEDANCE_CTRL1)),
> + ==, 0x0fff);
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_VREF_IN_GLOBAL)),
> + ==, 0x0200);
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_MSTR, 0x01040008);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_MSTR),
> + ==, 0x01040008);
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_STAT, 0xffffffff);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_STAT),
> + ==, 0x00000000);
> +
> + qtest_writel(qts, K230_DDR_PHY_CSR(K230_DDR_PHY_VREF_IN_GLOBAL),
> + 0xffffffff);
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_VREF_IN_GLOBAL)),
> + ==, 0x7fff);
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_DRAMTMG4, 0);
> +
> + qtest_system_reset(qts);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_MSTR),
> + ==, 0x01040000);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_DRAMTMG4),
> + ==, 0x05040405);
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_VREF_IN_GLOBAL)),
> + ==, 0x0200);
> +
> + qtest_quit(qts);
> +}
> +
> +static void test_software_update_handshake(void)
> +{
> + QTestState *qts = qtest_init("-machine k230");
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_SWCTL, 0);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_SWSTAT),
> + ==, 0);
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_SWCTL, 1);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_SWSTAT),
> + ==, 1);
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_SWSTAT, 0);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_SWSTAT),
> + ==, 1);
> +
> + qtest_quit(qts);
> +}
> +
> +static void test_phy_ownership(void)
> +{
> + QTestState *qts = qtest_init("-machine k230");
> + uint64_t atx = K230_DDR_PHY_CSR(K230_DDR_PHY_ATX_IMPEDANCE);
> + uint64_t mux = K230_DDR_PHY_CSR(K230_DDR_PHY_MICRO_CONT_MUX_SEL);
> +
> + qtest_writel(qts, atx, 0x155);
> + g_assert_cmphex(qtest_readl(qts, atx), ==, 0x155);
> +
> + qtest_writel(qts, mux, 1);
> + qtest_writel(qts, atx, 0x2aa);
> + g_assert_cmphex(qtest_readl(qts, atx), ==, 0x155);
> +
> + qtest_writel(qts, mux, 0);
> + qtest_writel(qts, atx, 0x2aa);
> + g_assert_cmphex(qtest_readl(qts, atx), ==, 0x2aa);
> +
> + qtest_quit(qts);
> +}
> +
> +static void test_dfi_prerequisites(void)
> +{
> + QTestState *qts = qtest_init("-machine k230");
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_DFIMISC, 0x20);
> +
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDRC_BASE + K230_DDRC_DFISTAT) &
> + K230_DDRC_DFISTAT_DFI_INIT_COMPLETE_MASK,
> + ==, 0);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_STAT) &
> + K230_DDRC_STAT_OPERATING_MODE_MASK,
> + ==, 0);
> +
> + qtest_quit(qts);
> +}
> +
> +static void test_dfi_complete_enable(void)
> +{
> + QTestState *qts = qtest_init("-machine k230");
> +
> + complete_phy_training(qts);
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_DFIMISC, 0x20);
> +
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDRC_BASE + K230_DDRC_DFISTAT) &
> + K230_DDRC_DFISTAT_DFI_INIT_COMPLETE_MASK,
> + ==, 1);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_STAT) &
> + K230_DDRC_STAT_OPERATING_MODE_MASK,
> + ==, 0);
> +
> + qtest_quit(qts);
> +}
> +
> +static void test_training_and_dfi_handshake(void)
> +{
> + QTestState *qts = qtest_init("-machine k230");
> +
> + complete_phy_training(qts);
> +
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_TRAINING_STATUS)),
> + ==, 0);
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_TRAINING_MESSAGE)),
> + ==, 0x07);
> +
> + qtest_writel(qts, K230_DDR_PHY_CSR(K230_DDR_PHY_TRAINING_ACK), 0);
> + g_assert_cmphex(qtest_readl(qts,
> + K230_DDR_PHY_CSR(K230_DDR_PHY_TRAINING_STATUS)),
> + ==, 1);
> + qtest_writel(qts, K230_DDR_PHY_CSR(K230_DDR_PHY_TRAINING_ACK), 1);
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_DFIMISC, 0x20);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_DFISTAT),
> + ==, 1);
> +
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_DFIMISC, 0);
> + qtest_writel(qts, K230_DDRC_BASE + K230_DDRC_DFIMISC, 1);
> + g_assert_cmphex(qtest_readl(qts, K230_DDRC_BASE + K230_DDRC_STAT) & 0x7,
> + ==, 1);
> +
> + qtest_quit(qts);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + g_test_init(&argc, &argv, NULL);
> +
> + qtest_add_func("/k230-ddr/reset-and-register-access",
> + test_reset_and_register_access);
> + qtest_add_func("/k230-ddr/software-update-handshake",
> + test_software_update_handshake);
> + qtest_add_func("/k230-ddr/phy-ownership", test_phy_ownership);
> + qtest_add_func("/k230-ddr/dfi-prerequisites", test_dfi_prerequisites);
> + qtest_add_func("/k230-ddr/dfi-complete-enable",
> + test_dfi_complete_enable);
> + qtest_add_func("/k230-ddr/training-and-dfi-handshake",
> + test_training_and_dfi_handshake);
> +
> + return g_test_run();
> +}
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 56ff860e21..dc110f72c8 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -297,7 +297,8 @@ qtests_riscv64 = ['riscv-csr-test'] + \
> (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and
> config_all_devices.has_key('CONFIG_RISCV_IOMMU') ?
> ['iommu-riscv-test'] : []) + \
> - (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test'] : [])
> + (config_all_devices.has_key('CONFIG_K230') ?
> + ['k230-ddr-test', 'k230-wdt-test'] : [])
>
> qtests_hexagon = ['boot-serial-test']
>
> --
> 2.53.0
>
prev parent reply other threads:[~2026-07-23 8:42 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 13:24 [PATCH 0/3] riscv: Add K230 DDR controller and PHY models Junze Cao
2026-07-16 13:24 ` [PATCH 1/3] hw/misc: " Junze Cao
2026-07-22 20:06 ` Daniel Henrique Barboza
2026-07-23 8:41 ` Chao Liu
2026-07-16 13:24 ` [PATCH 2/3] hw/riscv: Connect " Junze Cao
2026-07-22 20:08 ` Daniel Henrique Barboza
2026-07-23 8:42 ` Chao Liu
2026-07-16 13:24 ` [PATCH 3/3] tests/qtest: Add K230 DDR controller tests Junze Cao
2026-07-22 20:16 ` Daniel Henrique Barboza
2026-07-23 8:42 ` Chao Liu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=amHT6_8b9qEbtGO8@ChaodeMacBook-Pro.local \
--to=chao.liu@processmission.com \
--cc=alistair.francis@wdc.com \
--cc=caojunze424@gmail.com \
--cc=daniel.barboza@oss.qualcomm.com \
--cc=farosas@suse.de \
--cc=liwei1518@gmail.com \
--cc=lvivier@redhat.com \
--cc=palmer@dabbelt.com \
--cc=pbonzini@redhat.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=zhiwei_liu@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox