Skip to content

Commit 7d748c5

Browse files
jaeyoon-choibsdimp
authored andcommitted
ufshci: Add WriteBooster support
This patch enables WriteBooster to improve write performance. It reserves SLC space from normal (TLC) storage to handle incoming writes, reducing latency and handling bursty writes. The buffer can be dedicated to a single LU or shared across multiple LUs, depending on configuration. Data staged in SLC is later flushed back to TLC automatically or on demand, without changing data placement. The following table shows WriteBooster performance as tested on a Galaxy Book S + UFS 4.0(HS-GEAR 4) device. ``` ---------------------------------------------------------------- | Workload | BS | QD | WriteBooster | Bandwidth | ---------------------------------------------------------------- | Sequential Write | 1MB | 32 | On | 1568 MiB/s | | Sequential Write | 1MB | 32 | Off | 556 MiB/s | ---------------------------------------------------------------- ``` Also, this function adds a power mode change quirk to the Intel Lakefield UFS controller. Sponsored by: Samsung Electronics Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D51893
1 parent fb37e38 commit 7d748c5

File tree

8 files changed

+489
-12
lines changed

8 files changed

+489
-12
lines changed

sys/dev/ufshci/ufshci.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,42 @@ struct ufshci_device_descriptor {
716716
_Static_assert(sizeof(struct ufshci_device_descriptor) == 89,
717717
"bad size for ufshci_device_descriptor");
718718

719+
/* Defines the bit field of dExtendedUfsFeaturesSupport. */
720+
enum ufshci_desc_wb_ext_ufs_feature {
721+
UFSHCI_DESC_EXT_UFS_FEATURE_FFU = (1 << 0),
722+
UFSHCI_DESC_EXT_UFS_FEATURE_PSA = (1 << 1),
723+
UFSHCI_DESC_EXT_UFS_FEATURE_DEV_LIFE_SPAN = (1 << 2),
724+
UFSHCI_DESC_EXT_UFS_FEATURE_REFRESH_OP = (1 << 3),
725+
UFSHCI_DESC_EXT_UFS_FEATURE_TOO_HIGH_TEMP = (1 << 4),
726+
UFSHCI_DESC_EXT_UFS_FEATURE_TOO_LOW_TEMP = (1 << 5),
727+
UFSHCI_DESC_EXT_UFS_FEATURE_EXT_TEMP = (1 << 6),
728+
UFSHCI_DESC_EXT_UFS_FEATURE_HPB_SUPPORT = (1 << 7),
729+
UFSHCI_DESC_EXT_UFS_FEATURE_WRITE_BOOSTER = (1 << 8),
730+
UFSHCI_DESC_EXT_UFS_FEATURE_PERF_THROTTLING = (1 << 9),
731+
UFSHCI_DESC_EXT_UFS_FEATURE_ADVANCED_RPMB = (1 << 10),
732+
UFSHCI_DESC_EXT_UFS_FEATURE_ZONED_UFS_EXTENSION = (1 << 11),
733+
UFSHCI_DESC_EXT_UFS_FEATURE_DEV_LEVEL_EXCEPTION = (1 << 12),
734+
UFSHCI_DESC_EXT_UFS_FEATURE_HID = (1 << 13),
735+
UFSHCI_DESC_EXT_UFS_FEATURE_BARRIER = (1 << 14),
736+
UFSHCI_DESC_EXT_UFS_FEATURE_CLEAR_ERROR_HISTORY = (1 << 15),
737+
UFSHCI_DESC_EXT_UFS_FEATURE_EXT_IID = (1 << 16),
738+
UFSHCI_DESC_EXT_UFS_FEATURE_FBO = (1 << 17),
739+
UFSHCI_DESC_EXT_UFS_FEATURE_FAST_RECOVERY_MODE = (1 << 18),
740+
UFSHCI_DESC_EXT_UFS_FEATURE_RPMB_VENDOR_CMD = (1 << 19),
741+
};
742+
743+
/* Defines the bit field of bWriteBoosterBufferType. */
744+
enum ufshci_desc_wb_buffer_type {
745+
UFSHCI_DESC_WB_BUF_TYPE_LU_DEDICATED = 0x00,
746+
UFSHCI_DESC_WB_BUF_TYPE_SINGLE_SHARED = 0x01,
747+
};
748+
749+
/* Defines the bit field of bWriteBoosterBufferPreserveUserSpaceEn. */
750+
enum ufshci_desc_user_space_config {
751+
UFSHCI_DESC_WB_BUF_USER_SPACE_REDUCTION = 0x00,
752+
UFSHCI_DESC_WB_BUF_PRESERVE_USER_SPACE = 0x01,
753+
};
754+
719755
/*
720756
* UFS Spec 4.1, section 14.1.5.3 "Configuration Descriptor"
721757
* ConfigurationDescriptor use big-endian byte ordering.
@@ -1014,4 +1050,37 @@ enum ufshci_attributes {
10141050
UFSHCI_ATTR_B_REFRESH_METHOD = 0x2f,
10151051
};
10161052

1053+
/* bAvailableWriteBoosterBufferSize codes (UFS WriteBooster abailable buffer
1054+
* left %) */
1055+
enum ufshci_wb_available_buffer_Size {
1056+
UFSHCI_ATTR_WB_AVAILABLE_0 = 0x00, /* 0% buffer remains */
1057+
UFSHCI_ATTR_WB_AVAILABLE_10 = 0x01, /* 10% buffer remains */
1058+
UFSHCI_ATTR_WB_AVAILABLE_20 = 0x02, /* 20% buffer remains */
1059+
UFSHCI_ATTR_WB_AVAILABLE_30 = 0x03, /* 30% buffer remains */
1060+
UFSHCI_ATTR_WB_AVAILABLE_40 = 0x04, /* 40% buffer remains */
1061+
UFSHCI_ATTR_WB_AVAILABLE_50 = 0x05, /* 50% buffer remains */
1062+
UFSHCI_ATTR_WB_AVAILABLE_60 = 0x06, /* 60% buffer remains */
1063+
UFSHCI_ATTR_WB_AVAILABLE_70 = 0x07, /* 70% buffer remains */
1064+
UFSHCI_ATTR_WB_AVAILABLE_80 = 0x08, /* 80% buffer remains */
1065+
UFSHCI_ATTR_WB_AVAILABLE_90 = 0x09, /* 90% buffer remains */
1066+
UFSHCI_ATTR_WB_AVAILABLE_100 = 0x0A, /* 100% buffer remains */
1067+
};
1068+
1069+
/* bWriteBoosterBufferLifeTimeEst codes (UFS WriteBooster buffer life %) */
1070+
enum ufshci_wb_lifetime {
1071+
UFSHCI_ATTR_WB_LIFE_DISABLED = 0x00, /* Info not available */
1072+
UFSHCI_ATTR_WB_LIFE_0_10 = 0x01, /* 0%–10% used */
1073+
UFSHCI_ATTR_WB_LIFE_10_20 = 0x02, /* 10%–20% used */
1074+
UFSHCI_ATTR_WB_LIFE_20_30 = 0x03, /* 20%–30% used */
1075+
UFSHCI_ATTR_WB_LIFE_30_40 = 0x04, /* 30%–40% used */
1076+
UFSHCI_ATTR_WB_LIFE_40_50 = 0x05, /* 40%–50% used */
1077+
UFSHCI_ATTR_WB_LIFE_50_60 = 0x06, /* 50%–60% used */
1078+
UFSHCI_ATTR_WB_LIFE_60_70 = 0x07, /* 60%–70% used */
1079+
UFSHCI_ATTR_WB_LIFE_70_80 = 0x08, /* 70%–80% used */
1080+
UFSHCI_ATTR_WB_LIFE_80_90 = 0x09, /* 80%–90% used */
1081+
UFSHCI_ATTR_WB_LIFE_90_100 = 0x0A, /* 90%–100% used */
1082+
UFSHCI_ATTR_WB_LIFE_EXCEEDED =
1083+
0x0B, /* Exceeded estimated life (treat as WB disabled) */
1084+
};
1085+
10171086
#endif /* __UFSHCI_H__ */

sys/dev/ufshci/ufshci_ctrlr.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ ufshci_ctrlr_enable_host_ctrlr(struct ufshci_controller *ctrlr)
6161
int
6262
ufshci_ctrlr_construct(struct ufshci_controller *ctrlr, device_t dev)
6363
{
64-
uint32_t ver, cap, hcs, ie;
64+
uint32_t ver, cap, hcs, ie, ahit;
6565
uint32_t timeout_period, retry_count;
6666
int error;
6767

@@ -127,6 +127,13 @@ ufshci_ctrlr_construct(struct ufshci_controller *ctrlr, device_t dev)
127127
if (error)
128128
return (error);
129129

130+
/* Read the UECPA register to clear */
131+
ufshci_mmio_read_4(ctrlr, uecpa);
132+
133+
/* Diable Auto-hibernate */
134+
ahit = 0;
135+
ufshci_mmio_write_4(ctrlr, ahit, ahit);
136+
130137
/*
131138
* The device_present(UFSHCI_HCS_REG_DP) bit becomes true if the host
132139
* controller has successfully received a Link Startup UIC command
@@ -342,18 +349,19 @@ ufshci_ctrlr_start(struct ufshci_controller *ctrlr)
342349
return;
343350
}
344351

345-
/* Read Controller Descriptor (Device, Geometry)*/
352+
/* Read Controller Descriptor (Device, Geometry) */
346353
if (ufshci_dev_get_descriptor(ctrlr) != 0) {
347354
ufshci_ctrlr_fail(ctrlr, false);
348355
return;
349356
}
350357

351-
/* TODO: Configure Write Protect */
358+
if (ufshci_dev_config_write_booster(ctrlr)) {
359+
ufshci_ctrlr_fail(ctrlr, false);
360+
return;
361+
}
352362

353363
/* TODO: Configure Background Operations */
354364

355-
/* TODO: Configure Write Booster */
356-
357365
if (ufshci_sim_attach(ctrlr) != 0) {
358366
ufshci_ctrlr_fail(ctrlr, false);
359367
return;

0 commit comments

Comments
 (0)