@@ -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 */
@@ -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);
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(-)