diff mbox series

hw/ufs: Raise interrupt on UIC power mode change

Message ID 32d8c778f8cc6b28f0eaa39809e0f0b949b2e265.1705893262.git.jeuk20.kim@samsung.com
State New
Headers show
Series hw/ufs: Raise interrupt on UIC power mode change | expand

Commit Message

Jeuk Kim Jan. 22, 2024, 4:46 a.m. UTC
This patch allows the qemu ufs to raise an interrupt on
the DME_SET (PA_PWRMODE) command.

Signed-off-by: Jeuk Kim <jeuk20.kim@samsung.com>
---
 hw/ufs/ufs.c        | 15 ++++++++++-
 include/block/ufs.h | 65 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c
index eccdb852a0..e95f732a9f 100644
--- a/hw/ufs/ufs.c
+++ b/hw/ufs/ufs.c
@@ -301,6 +301,19 @@  static void ufs_process_uiccmd(UfsHc *u, uint32_t val)
      * are implemented.
      */
     switch (val) {
+    case UFS_UIC_CMD_DME_SET:
+        if (FIELD_EX32(u->reg.ucmdarg1, UCMDARG1, MIBattribute) ==
+            UFS_UNIPRO_PA_PWRMODE) {
+            u->reg.hcs = FIELD_DP32(u->reg.hcs, HCS, UPMCRS, UFS_PWR_LOCAL);
+            u->reg.is = FIELD_DP32(u->reg.is, IS, UPMS, 1);
+        }
+        u->reg.ucmdarg2 = UFS_UIC_CMD_RESULT_SUCCESS;
+        break;
+    case UFS_UIC_CMD_DME_GET:
+    case UFS_UIC_CMD_DME_PEER_GET:
+    case UFS_UIC_CMD_DME_PEER_SET:
+        u->reg.ucmdarg2 = UFS_UIC_CMD_RESULT_SUCCESS;
+        break;
     case UFS_UIC_CMD_DME_LINK_STARTUP:
         u->reg.hcs = FIELD_DP32(u->reg.hcs, HCS, DP, 1);
         u->reg.hcs = FIELD_DP32(u->reg.hcs, HCS, UTRLRDY, 1);
@@ -434,7 +447,6 @@  static const MemoryRegionOps ufs_mmio_ops = {
     },
 };
 
-
 void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
                            uint8_t response, uint8_t scsi_status,
                            uint16_t data_segment_length)
@@ -1237,6 +1249,7 @@  static void ufs_init_hc(UfsHc *u)
     u->geometry_desc.supported_memory_types = cpu_to_be16(0x8001);
 
     memset(&u->attributes, 0, sizeof(u->attributes));
+    u->attributes.current_power_mode = 0x11; /* Active Power Mode */
     u->attributes.max_data_in_size = 0x08;
     u->attributes.max_data_out_size = 0x08;
     u->attributes.ref_clk_freq = 0x01; /* 26 MHz */
diff --git a/include/block/ufs.h b/include/block/ufs.h
index d61598b8f3..fe2f2ce944 100644
--- a/include/block/ufs.h
+++ b/include/block/ufs.h
@@ -125,6 +125,8 @@  REG32(UTMRLCLR, offsetof(UfsReg, utmrlclr))
 REG32(UTMRLRSR, offsetof(UfsReg, utmrlrsr))
 REG32(UICCMD, offsetof(UfsReg, uiccmd))
 REG32(UCMDARG1, offsetof(UfsReg, ucmdarg1))
+    FIELD(UCMDARG1, GenSelectorIndex, 0, 16)
+    FIELD(UCMDARG1, MIBattribute, 16, 16)
 REG32(UCMDARG2, offsetof(UfsReg, ucmdarg2))
 REG32(UCMDARG3, offsetof(UfsReg, ucmdarg3))
 REG32(CCAP, offsetof(UfsReg, ccap))
@@ -1064,6 +1066,69 @@  typedef struct QEMU_PACKED UtpUpiuRsp {
     };
 } UtpUpiuRsp;
 
+/*
+ * PHY Adapter attributes
+ */
+#define UFS_UNIPRO_PA_PHY_TYPE 0x1500
+#define UFS_UNIPRO_PA_AVAILTXDATALANES 0x1520
+#define UFS_UNIPRO_PA_MAXTXSPEEDFAST 0x1521
+#define UFS_UNIPRO_PA_MAXTXSPEEDSLOW 0x1522
+#define UFS_UNIPRO_PA_MAXRXSPEEDFAST 0x1541
+#define UFS_UNIPRO_PA_MAXRXSPEEDSLOW 0x1542
+#define UFS_UNIPRO_PA_TXLINKSTARTUPHS 0x1544
+#define UFS_UNIPRO_PA_AVAILRXDATALANES 0x1540
+#define UFS_UNIPRO_PA_MINRXTRAILINGCLOCKS 0x1543
+#define UFS_UNIPRO_PA_LOCAL_TX_LCC_ENABLE 0x155E
+#define UFS_UNIPRO_PA_ACTIVETXDATALANES 0x1560
+#define UFS_UNIPRO_PA_CONNECTEDTXDATALANES 0x1561
+#define UFS_UNIPRO_PA_TXFORCECLOCK 0x1562
+#define UFS_UNIPRO_PA_TXPWRMODE 0x1563
+#define UFS_UNIPRO_PA_TXTRAILINGCLOCKS 0x1564
+#define UFS_UNIPRO_PA_TXSPEEDFAST 0x1565
+#define UFS_UNIPRO_PA_TXSPEEDSLOW 0x1566
+#define UFS_UNIPRO_PA_TXPWRSTATUS 0x1567
+#define UFS_UNIPRO_PA_TXGEAR 0x1568
+#define UFS_UNIPRO_PA_TXTERMINATION 0x1569
+#define UFS_UNIPRO_PA_HSSERIES 0x156A
+#define UFS_UNIPRO_PA_LEGACYDPHYESCDL 0x1570
+#define UFS_UNIPRO_PA_PWRMODE 0x1571
+#define UFS_UNIPRO_PA_ACTIVERXDATALANES 0x1580
+#define UFS_UNIPRO_PA_CONNECTEDRXDATALANES 0x1581
+#define UFS_UNIPRO_PA_RXPWRSTATUS 0x1582
+#define UFS_UNIPRO_PA_RXGEAR 0x1583
+#define UFS_UNIPRO_PA_RXTERMINATION 0x1584
+#define UFS_UNIPRO_PA_MAXRXPWMGEAR 0x1586
+#define UFS_UNIPRO_PA_MAXRXHSGEAR 0x1587
+#define UFS_UNIPRO_PA_PACPREQTIMEOUT 0x1590
+#define UFS_UNIPRO_PA_PACPREQEOBTIMEOUT 0x1591
+#define UFS_UNIPRO_PA_REMOTEVERINFO 0x15A0
+#define UFS_UNIPRO_PA_LOGICALLANEMAP 0x15A1
+#define UFS_UNIPRO_PA_SLEEPNOCONFIGTIME 0x15A2
+#define UFS_UNIPRO_PA_STALLNOCONFIGTIME 0x15A3
+#define UFS_UNIPRO_PA_SAVECONFIGTIME 0x15A4
+#define UFS_UNIPRO_PA_RXHSUNTERMCAP 0x15A5
+#define UFS_UNIPRO_PA_RXLSTERMCAP 0x15A6
+#define UFS_UNIPRO_PA_HIBERN8TIME 0x15A7
+#define UFS_UNIPRO_PA_LOCALVERINFO 0x15A9
+#define UFS_UNIPRO_PA_GRANULARITY 0x15AA
+#define UFS_UNIPRO_PA_TACTIVATE 0x15A8
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA0 0x15B0
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA1 0x15B1
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA2 0x15B2
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA3 0x15B3
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA4 0x15B4
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA5 0x15B5
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA6 0x15B6
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA7 0x15B7
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA8 0x15B8
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA9 0x15B9
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA10 0x15BA
+#define UFS_UNIPRO_PA_PWRMODEUSERDATA11 0x15BB
+#define UFS_UNIPRO_PA_PACPFRAMECOUNT 0x15C0
+#define UFS_UNIPRO_PA_PACPERRORCOUNT 0x15C1
+#define UFS_UNIPRO_PA_PHYTESTCONTROL 0x15C2
+#define UFS_UNIPRO_PA_TXHSADAPTTYPE 0x15D4
+
 static inline void _ufs_check_size(void)
 {
     QEMU_BUILD_BUG_ON(sizeof(UfsReg) != 0x104);