Page MenuHomeFreeBSD

D59298.id185607.diff
No OneTemporary

D59298.id185607.diff

diff --git a/sys/dev/ufshci/ufshci.h b/sys/dev/ufshci/ufshci.h
--- a/sys/dev/ufshci/ufshci.h
+++ b/sys/dev/ufshci/ufshci.h
@@ -41,6 +41,8 @@
#define PA_TxTermination 0x1569
#define PA_RxTermination 0x1584
#define PA_HSSeries 0x156A
+#define UFSHCI_HS_SERIES_A 1
+#define UFSHCI_HS_SERIES_B 2
#define PA_PWRModeUserData0 0x15B0
#define PA_PWRModeUserData1 0x15B1
#define PA_PWRModeUserData2 0x15B2
@@ -49,6 +51,8 @@
#define PA_PWRModeUserData5 0x15B5
#define PA_TxHsAdaptType 0x15D4
+#define PA_INITIAL_ADAPT 1
+#define PA_NO_ADAPT 3
#define PA_PWRMode 0x1571
#define DME_LocalFC0ProtectionTimeOutVal 0xD041
diff --git a/sys/dev/ufshci/ufshci_acpi.c b/sys/dev/ufshci/ufshci_acpi.c
--- a/sys/dev/ufshci/ufshci_acpi.c
+++ b/sys/dev/ufshci/ufshci_acpi.c
@@ -49,17 +49,21 @@
const char *hid;
const char *desc;
uint32_t ref_clk;
+ uint32_t hs_series;
uint32_t quirks;
} ufshci_acpi_devices[] = {
/*
* The SoC feeds the device 38.4 MHz from its CXO. The firmware
* has no property for it. Verified on the Galaxy Book 4 Edge.
+ *
+ * The firmware calibrates the PHY for Rate-A. A Rate-B link
+ * comes up dead at every gear.
*/
{ "QCOM24A5", "Qualcomm Snapdragon X Elite UFS Host Controller",
- UFSHCI_REF_CLK_38_4MHz,
+ UFSHCI_REF_CLK_38_4MHz, UFSHCI_HS_SERIES_A,
UFSHCI_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH |
UFSHCI_QUIRK_BROKEN_LSDBS_MCQS_CAP },
- { 0x00000000, NULL, 0, 0 }
+ { 0x00000000, NULL, 0, 0, 0 }
};
static char *ufshci_acpi_ids[] = { "QCOM24A5", NULL };
@@ -97,6 +101,7 @@
if (acpi_dev->hid) {
ctrlr->quirks = acpi_dev->quirks;
ctrlr->ref_clk = acpi_dev->ref_clk;
+ ctrlr->hs_series = acpi_dev->hs_series;
}
if (acpi_dev->desc) {
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
@@ -375,6 +375,13 @@
if (!(ctrlr->is_single_db_supported || ctrlr->is_mcq_supported))
return (ENXIO);
+ /* Every device table entry must name the HS series. */
+ if (ctrlr->hs_series == 0) {
+ ufshci_printf(ctrlr,
+ "hs_series is missing from the device table\n");
+ return (ENXIO);
+ }
+
/*
* The maximum transfer size supported by UFSHCI spec is 65535 * 256 KiB
* However, we limit the maximum transfer size to 1MiB(256 * 4KiB) for
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
@@ -320,8 +320,6 @@
int
ufshci_dev_init_uic_power_mode(struct ufshci_controller *ctrlr)
{
- /* HSSerise: A = 1, B = 2 */
- const uint32_t hs_series = 2;
/*
* TX/RX PWRMode:
* - TX[3:0], RX[7:4]
@@ -386,8 +384,13 @@
if (ufshci_uic_send_dme_set(ctrlr, PA_RxTermination, true))
return (ENXIO);
- /* Set HSSerise (A = 1, B = 2) */
- if (ufshci_uic_send_dme_set(ctrlr, PA_HSSeries, hs_series))
+ /* Set HSSeries */
+ if (ufshci_uic_send_dme_set(ctrlr, PA_HSSeries, ctrlr->hs_series))
+ return (ENXIO);
+
+ /* HS-G4 and above need initial adaptation. */
+ if (ctrlr->hs_gear >= 4 &&
+ ufshci_uic_send_dme_set(ctrlr, PA_TxHsAdaptType, PA_INITIAL_ADAPT))
return (ENXIO);
/* Set Timeout values */
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
@@ -49,20 +49,23 @@
uint32_t devid;
const char *desc;
uint32_t ref_clk;
+ uint32_t hs_series;
uint32_t quirks;
} pci_ids[] = { { 0x131b36, "QEMU UFS Host Controller", UFSHCI_REF_CLK_19_2MHz,
+ UFSHCI_HS_SERIES_B,
UFSHCI_QUIRK_IGNORE_UIC_POWER_MODE |
UFSHCI_QUIRK_NOT_SUPPORT_ABORT_TASK |
UFSHCI_QUIRK_SKIP_WELL_KNOWN_LUNS },
{ 0x98fa8086, "Intel Lakefield UFS Host Controller",
- UFSHCI_REF_CLK_19_2MHz,
+ UFSHCI_REF_CLK_19_2MHz, UFSHCI_HS_SERIES_B,
UFSHCI_QUIRK_LONG_PEER_PA_TACTIVATE |
UFSHCI_QUIRK_WAIT_AFTER_POWER_MODE_CHANGE |
UFSHCI_QUIRK_CHANGE_LANE_AND_GEAR_SEPARATELY |
UFSHCI_QUIRK_BROKEN_AUTO_HIBERNATE },
{ 0x54ff8086, "Intel Alder Lake-N UFS Host Controller",
- UFSHCI_REF_CLK_19_2MHz, UFSHCI_QUIRK_BROKEN_AUTO_HIBERNATE },
- { 0x00000000, NULL } };
+ UFSHCI_REF_CLK_19_2MHz, UFSHCI_HS_SERIES_B,
+ UFSHCI_QUIRK_BROKEN_AUTO_HIBERNATE },
+ { 0x00000000, NULL, 0, 0, 0 } };
static int
ufshci_pci_probe(device_t device)
@@ -77,6 +80,7 @@
if (ep->devid) {
ctrlr->quirks = ep->quirks;
ctrlr->ref_clk = ep->ref_clk;
+ ctrlr->hs_series = ep->hs_series;
}
if (ep->desc) {
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
@@ -326,6 +326,7 @@
256 /* Some controllers have their LSDB and MCQS fields reset to 0. */
uint32_t ref_clk;
+ uint32_t hs_series;
struct cam_sim *ufshci_sim;
struct cam_path *ufshci_path;

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 3, 2:24 PM (18 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37936203
Default Alt Text
D59298.id185607.diff (4 KB)

Event Timeline