Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142134195
D54004.id167459.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D54004.id167459.diff
View Options
diff --git a/sys/dev/ufshci/ufshci_ctrlr.c b/sys/dev/ufshci/ufshci_ctrlr.c
--- a/sys/dev/ufshci/ufshci_ctrlr.c
+++ b/sys/dev/ufshci/ufshci_ctrlr.c
@@ -92,6 +92,8 @@
return;
}
+ ufshci_dev_init_auto_hibernate(ctrlr);
+
/* TODO: Configure Write Protect */
/* TODO: Configure Background Operations */
@@ -674,5 +676,7 @@
}
}
+ ufshci_dev_enable_auto_hibernate(ctrlr);
+
return (0);
}
diff --git a/sys/dev/ufshci/ufshci_dev.c b/sys/dev/ufshci/ufshci_dev.c
--- a/sys/dev/ufshci/ufshci_dev.c
+++ b/sys/dev/ufshci/ufshci_dev.c
@@ -449,6 +449,33 @@
return (0);
}
+void
+ufshci_dev_enable_auto_hibernate(struct ufshci_controller *ctrlr)
+{
+ if (!ctrlr->ufs_dev.auto_hibernation_supported)
+ return;
+
+ ufshci_mmio_write_4(ctrlr, ahit, ctrlr->ufs_dev.ahit);
+}
+
+void
+ufshci_dev_init_auto_hibernate(struct ufshci_controller *ctrlr)
+{
+ ctrlr->ufs_dev.auto_hibernation_supported =
+ UFSHCIV(UFSHCI_CAP_REG_AUTOH8, ctrlr->cap) &&
+ !(ctrlr->quirks & UFSHCI_QUIRK_BROKEN_AUTO_HIBERNATE);
+
+ if (!ctrlr->ufs_dev.auto_hibernation_supported)
+ return;
+
+ /* The default value for auto hibernation is 150 ms */
+ ctrlr->ufs_dev.ahit = 0;
+ ctrlr->ufs_dev.ahit |= UFSHCIF(UFSHCI_AHIT_REG_AH8ITV, 150);
+ ctrlr->ufs_dev.ahit |= UFSHCIF(UFSHCI_AHIT_REG_TS, 3);
+
+ ufshci_dev_enable_auto_hibernate(ctrlr);
+}
+
void
ufshci_dev_init_uic_link_state(struct ufshci_controller *ctrlr)
{
diff --git a/sys/dev/ufshci/ufshci_pci.c b/sys/dev/ufshci/ufshci_pci.c
--- a/sys/dev/ufshci/ufshci_pci.c
+++ b/sys/dev/ufshci/ufshci_pci.c
@@ -58,7 +58,8 @@
UFSHCI_REF_CLK_19_2MHz,
UFSHCI_QUIRK_LONG_PEER_PA_TACTIVATE |
UFSHCI_QUIRK_WAIT_AFTER_POWER_MODE_CHANGE |
- UFSHCI_QUIRK_CHANGE_LANE_AND_GEAR_SEPARATELY },
+ UFSHCI_QUIRK_CHANGE_LANE_AND_GEAR_SEPARATELY |
+ UFSHCI_QUIRK_BROKEN_AUTO_HIBERNATE },
{ 0x54ff8086, "Intel UFS Host Controller", UFSHCI_REF_CLK_19_2MHz },
{ 0x00000000, NULL } };
diff --git a/sys/dev/ufshci/ufshci_private.h b/sys/dev/ufshci/ufshci_private.h
--- a/sys/dev/ufshci/ufshci_private.h
+++ b/sys/dev/ufshci/ufshci_private.h
@@ -293,6 +293,10 @@
bool power_mode_supported;
enum ufshci_dev_pwr power_mode;
enum ufshci_uic_link_state link_state;
+
+ /* Auto Hibernation */
+ bool auto_hibernation_supported;
+ uint32_t ahit;
};
/*
@@ -314,6 +318,9 @@
16 /* QEMU does not support Task Management Request */
#define UFSHCI_QUIRK_SKIP_WELL_KNOWN_LUNS \
32 /* QEMU does not support Well known logical units*/
+#define UFSHCI_QUIRK_BROKEN_AUTO_HIBERNATE \
+ 64 /* Some controllers have the Auto hibernate feature enabled but it \
+ does not work. */
uint32_t ref_clk;
@@ -457,6 +464,8 @@
int ufshci_dev_reset(struct ufshci_controller *ctrlr);
int ufshci_dev_init_reference_clock(struct ufshci_controller *ctrlr);
int ufshci_dev_init_unipro(struct ufshci_controller *ctrlr);
+void ufshci_dev_enable_auto_hibernate(struct ufshci_controller *ctrlr);
+void ufshci_dev_init_auto_hibernate(struct ufshci_controller *ctrlr);
int ufshci_dev_init_uic_power_mode(struct ufshci_controller *ctrlr);
void ufshci_dev_init_uic_link_state(struct ufshci_controller *ctrlr);
int ufshci_dev_init_ufs_power_mode(struct ufshci_controller *ctrlr);
diff --git a/sys/dev/ufshci/ufshci_sysctl.c b/sys/dev/ufshci/ufshci_sysctl.c
--- a/sys/dev/ufshci/ufshci_sysctl.c
+++ b/sys/dev/ufshci/ufshci_sysctl.c
@@ -11,6 +11,7 @@
#include <sys/sysctl.h>
#include "ufshci_private.h"
+#include "ufshci_reg.h"
static int
ufshci_sysctl_timeout_period(SYSCTL_HANDLER_ARGS)
@@ -106,6 +107,22 @@
return (sysctl_handle_64(oidp, &num_failures, 0, req));
}
+static int
+ufshci_sysctl_ahit(SYSCTL_HANDLER_ARGS)
+{
+ struct ufshci_controller *ctrlr = arg1;
+ int64_t scale, timer;
+ const int64_t scale_factor = 10;
+
+ scale = UFSHCIV(UFSHCI_AHIT_REG_TS, ctrlr->ufs_dev.ahit);
+ timer = UFSHCIV(UFSHCI_AHIT_REG_AH8ITV, ctrlr->ufs_dev.ahit);
+
+ while (scale--)
+ timer *= scale_factor;
+
+ return (sysctl_handle_64(oidp, &timer, 0, req));
+}
+
static void
ufshci_sysctl_initialize_queue(struct ufshci_hw_queue *hwq,
struct sysctl_ctx_list *ctrlr_ctx, struct sysctl_oid *que_tree)
@@ -201,6 +218,17 @@
CTLFLAG_RD, &dev->power_mode_supported, 0,
"Device power mode support");
+ SYSCTL_ADD_BOOL(ctrlr_ctx, ctrlr_list, OID_AUTO,
+ "auto_hibernation_supported", CTLFLAG_RD,
+ &dev->auto_hibernation_supported, 0,
+ "Device auto hibernation support");
+
+ SYSCTL_ADD_PROC(ctrlr_ctx, ctrlr_list, OID_AUTO,
+ "auto_hibernate_idle_timer_value",
+ CTLTYPE_S64 | CTLFLAG_RD | CTLFLAG_MPSAFE, ctrlr, 0,
+ ufshci_sysctl_ahit, "IU",
+ "Auto-Hibernate Idle Timer Value (in microseconds)");
+
SYSCTL_ADD_UINT(ctrlr_ctx, ctrlr_list, OID_AUTO, "power_mode",
CTLFLAG_RD, &dev->power_mode, 0, "Current device power mode");
diff --git a/sys/dev/ufshci/ufshci_uic_cmd.c b/sys/dev/ufshci/ufshci_uic_cmd.c
--- a/sys/dev/ufshci/ufshci_uic_cmd.c
+++ b/sys/dev/ufshci/ufshci_uic_cmd.c
@@ -196,8 +196,9 @@
config_result_code = ufshci_mmio_read_4(ctrlr, ucmdarg2);
if (config_result_code) {
ufshci_printf(ctrlr,
- "Failed to send UIC command. (config result code = 0x%x)\n",
- config_result_code);
+ "Failed to send UIC command (Opcode: 0x%x"
+ ", config result code = 0x%x)\n",
+ uic_cmd->opcode, config_result_code);
}
if (return_value != NULL)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 17, 8:48 AM (22 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27682891
Default Alt Text
D54004.id167459.diff (5 KB)
Attached To
Mode
D54004: ufshci: Support UIC Auto Hibernation
Attached
Detach File
Event Timeline
Log In to Comment