summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2026-07-02 10:44:34 +0200
committerStefan Hajnoczi <stefanha@redhat.com>2026-07-02 10:44:34 +0200
commit8241394f7e749401e1fb84d412eab40a0e7a23bc (patch)
treef041956c768e0af9018828721e09cb5d9f102891
parent654b54fb372180924f8206d6dfd29cecdef1d8ac (diff)
parent20c03709b353d6c985bfa3174c4563d57ff47275 (diff)
downloadqemu-8241394f7e749401e1fb84d412eab40a0e7a23bc.tar.gz
qemu-8241394f7e749401e1fb84d412eab40a0e7a23bc.zip
Merge tag 'pull-ufs-20260701' of https://gitlab.com/jeuk20.kim/qemu into staging
ufs queue # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEUBfYMVl8eKPZB+73EuIgTA5dtgIFAmpEoa0ACgkQEuIgTA5d # tgLm1Q//Vqj6g2tNoiGqfIhuuUGjYiMifyfRzF9ZGVKBUwXeduaJ0gXE05duVbCx # FZyheWVUzvovDyWMgvpk0NwBz0WIEUWmWj9GtKnGMpRU9cFxATlUuFbYU+tY2aZC # dt6Ck3saRrVDvcrETucgkzL8HuEehXtZCfnqNmEkggXuhuaPJnkm8bKzs5fxapF/ # QT4T1j2RTFkWtHTfvnXrQiDmqVTGpRlI2USjCdCd3RUFxnKbFZJ8EcLJVAYPGrBR # RRi2eY4M2hCbZnNctpYfj86GltbFypnPfuhT+HVbIsue9+FEWScTa7BGeWpZETjJ # Drj19XAWbponVYXya57Me7I83b3+UJjSQe2eH4OGB0iTeqAlTQggAkmofzHWqD50 # +OyY6zT0TkPDpLmcBUbIwk94A+qV9iVETOLc0W2jX5CYrawD+lI9tAKeGtO6lv8c # Os5dy1vHvulDhd8H4tuCyepwLmU8KETZMDbSRwyQfgBKJx1eknqY0ITKynXbalIr # y1y5SzW+KnvB/2Dap3wfbYxpT441PEMlpN9cQslEALP+oHg80g+DdR47VJVJIkPM # 4ZR9T8LN8bm0hyzGVooQ0VpeKTA5ualAr9f0kT40a/8MuhedsXSy9XQBe9PYTiOe # 3MHqqPQFmwOXH6dzMUV44r0K9mW0QheBC9gLywq1yy4EIJ5DWMs= # =pbB1 # -----END PGP SIGNATURE----- # gpg: Signature made Wed 01 Jul 2026 07:12:13 CEST # gpg: using RSA key 5017D831597C78A3D907EEF712E2204C0E5DB602 # gpg: Good signature from "Jeuk Kim <jeuk20.kim@samsung.com>" [unknown] # gpg: aka "Jeuk Kim <jeuk20.kim@gmail.com>" [unknown] # 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: 5017 D831 597C 78A3 D907 EEF7 12E2 204C 0E5D B602 * tag 'pull-ufs-20260701' of https://gitlab.com/jeuk20.kim/qemu: hw/ufs: Populate cqe.task_tag for UFSHCI 4.1 tag decoding hw/ufs: Emulate DME_GET/SET for PA layer attributes Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--hw/ufs/ufs.c46
-rw-r--r--include/block/ufs.h18
2 files changed, 63 insertions, 1 deletions
diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c
index 35c2444385..464fd465b3 100644
--- a/hw/ufs/ufs.c
+++ b/hw/ufs/ufs.c
@@ -363,8 +363,32 @@ static void ufs_process_db(UfsHc *u, uint32_t val)
qemu_bh_schedule(u->doorbell_bh);
}
+/*
+ * Return canned PA layer attribute values. The emulated link has no PHY,
+ * so these are purely declarative: a single lane in HS-Gear 4, FAST_MODE.
+ */
+static uint32_t ufs_uic_dme_get_value(uint16_t attr_id)
+{
+ switch (attr_id) {
+ case UFS_ATTR_PA_AVAILTXDATALANES:
+ case UFS_ATTR_PA_AVAILRXDATALANES:
+ case UFS_ATTR_PA_CONNECTEDTXDATALANES:
+ case UFS_ATTR_PA_CONNECTEDRXDATALANES:
+ return 1;
+ case UFS_ATTR_PA_MAXRXHSGEAR:
+ case UFS_ATTR_PA_MAXRXPWMGEAR:
+ return 4;
+ case UFS_ATTR_PA_PWRMODE:
+ return (1 << 4) | 1;
+ default:
+ return 0;
+ }
+}
+
static void ufs_process_uiccmd(UfsHc *u, uint32_t val)
{
+ uint16_t attr_id;
+
trace_ufs_process_uiccmd(val, u->reg.ucmdarg1, u->reg.ucmdarg2,
u->reg.ucmdarg3);
/*
@@ -378,6 +402,22 @@ static void ufs_process_uiccmd(UfsHc *u, uint32_t val)
u->reg.hcs = FIELD_DP32(u->reg.hcs, HCS, UTMRLRDY, 1);
u->reg.ucmdarg2 = UFS_UIC_CMD_RESULT_SUCCESS;
break;
+ case UFS_UIC_CMD_DME_GET:
+ case UFS_UIC_CMD_DME_PEER_GET:
+ attr_id = (u->reg.ucmdarg1 >> 16) & 0xFFFF;
+ u->reg.ucmdarg3 = ufs_uic_dme_get_value(attr_id);
+ u->reg.ucmdarg2 = UFS_UIC_CMD_RESULT_SUCCESS;
+ break;
+ case UFS_UIC_CMD_DME_SET:
+ case UFS_UIC_CMD_DME_PEER_SET:
+ attr_id = (u->reg.ucmdarg1 >> 16) & 0xFFFF;
+ u->reg.ucmdarg2 = UFS_UIC_CMD_RESULT_SUCCESS;
+ /* DME_SET(PA_PWRMODE) is a power-mode-change trigger. */
+ if (val == UFS_UIC_CMD_DME_SET && attr_id == UFS_ATTR_PA_PWRMODE) {
+ u->reg.is = FIELD_DP32(u->reg.is, IS, UPMS, 1);
+ u->reg.hcs = FIELD_DP32(u->reg.hcs, HCS, UPMCRS, UFS_PWR_LOCAL);
+ }
+ break;
/*
* TODO: Revisit after PM implementation
* Power Management is not supported in current QEMU-UFS,
@@ -480,6 +520,12 @@ static void ufs_mcq_process_cq(void *opaque)
req->cqe.prdt_off = cpu_to_le16(prdt_off);
req->cqe.status = status;
req->cqe.error = 0;
+ /*
+ * From UFSHCI 4.1 the host derives the request tag from cqe.task_tag
+ * rather than decoding it from utp_addr.
+ */
+ req->cqe.task_tag = req->req_upiu.header.task_tag;
+ req->cqe.lun = req->req_upiu.header.lun;
ret = ufs_addr_write(u, cq->addr + tail, &req->cqe, sizeof(req->cqe));
if (ret) {
diff --git a/include/block/ufs.h b/include/block/ufs.h
index 6dd91181e5..d19b3c65ef 100644
--- a/include/block/ufs.h
+++ b/include/block/ufs.h
@@ -629,6 +629,18 @@ enum {
#define UFS_MASK_UIC_COMMAND_RESULT 0xFF
/*
+ * MIPI UniPro PHY Adapter (PA) layer attribute IDs accessed via
+ * DME_GET / DME_SET / DME_PEER_{GET,SET} UIC commands.
+ */
+#define UFS_ATTR_PA_AVAILTXDATALANES 0x1520
+#define UFS_ATTR_PA_AVAILRXDATALANES 0x1540
+#define UFS_ATTR_PA_CONNECTEDTXDATALANES 0x1561
+#define UFS_ATTR_PA_PWRMODE 0x1571
+#define UFS_ATTR_PA_CONNECTEDRXDATALANES 0x1581
+#define UFS_ATTR_PA_MAXRXPWMGEAR 0x1586
+#define UFS_ATTR_PA_MAXRXHSGEAR 0x1587
+
+/*
* Request Descriptor Definitions
*/
@@ -1321,7 +1333,11 @@ typedef struct QEMU_PACKED UfsCqEntry {
uint8_t status;
uint8_t error;
uint16_t rsvd1;
- uint32_t rsvd2[3];
+ uint8_t task_tag;
+ uint8_t lun;
+ uint8_t iid_ext_iid;
+ uint8_t rsvd2;
+ uint32_t rsvd3[2];
} UfsCqEntry;
static inline void _ufs_check_size(void)