All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junze Cao <caojunze424@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, chao.liu@processmission.com,
	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,
	Junze Cao <caojunze424@gmail.com>
Subject: [PATCH 3/3] tests/qtest: Add K230 DDR controller tests
Date: Thu, 16 Jul 2026 21:24:23 +0800	[thread overview]
Message-ID: <20260716132423.931427-4-caojunze424@gmail.com> (raw)
In-Reply-To: <20260716132423.931427-1-caojunze424@gmail.com>

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>
---
 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



  parent reply	other threads:[~2026-07-16 13:27 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 ` Junze Cao [this message]
2026-07-22 20:16   ` [PATCH 3/3] tests/qtest: Add K230 DDR controller tests Daniel Henrique Barboza
2026-07-23  8:42   ` Chao Liu

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=20260716132423.931427-4-caojunze424@gmail.com \
    --to=caojunze424@gmail.com \
    --cc=alistair.francis@wdc.com \
    --cc=chao.liu@processmission.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.