summaryrefslogtreecommitdiff
path: root/drivers/ufs/ufs.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ufs/ufs.h')
-rw-r--r--drivers/ufs/ufs.h224
1 files changed, 203 insertions, 21 deletions
diff --git a/drivers/ufs/ufs.h b/drivers/ufs/ufs.h
index 43042c294bb..00ecca350c3 100644
--- a/drivers/ufs/ufs.h
+++ b/drivers/ufs/ufs.h
@@ -3,6 +3,7 @@
#define __UFS_H
#include <linux/types.h>
+#include <asm/io.h>
#include "unipro.h"
struct udevice;
@@ -695,11 +696,177 @@ struct ufs_dev_cmd {
struct ufs_hba_ops {
int (*init)(struct ufs_hba *hba);
+ int (*get_max_pwr_mode)(struct ufs_hba *hba,
+ struct ufs_pwr_mode_info *max_pwr_info);
int (*hce_enable_notify)(struct ufs_hba *hba,
enum ufs_notify_change_status);
int (*link_startup_notify)(struct ufs_hba *hba,
enum ufs_notify_change_status);
int (*phy_initialization)(struct ufs_hba *hba);
+ int (*device_reset)(struct ufs_hba *hba);
+};
+
+enum ufshcd_quirks {
+ /* Interrupt aggregation support is broken */
+ UFSHCD_QUIRK_BROKEN_INTR_AGGR = 1 << 0,
+
+ /*
+ * delay before each dme command is required as the unipro
+ * layer has shown instabilities
+ */
+ UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS = 1 << 1,
+
+ /*
+ * If UFS host controller is having issue in processing LCC (Line
+ * Control Command) coming from device then enable this quirk.
+ * When this quirk is enabled, host controller driver should disable
+ * the LCC transmission on UFS device (by clearing TX_LCC_ENABLE
+ * attribute of device to 0).
+ */
+ UFSHCD_QUIRK_BROKEN_LCC = 1 << 2,
+
+ /*
+ * The attribute PA_RXHSUNTERMCAP specifies whether or not the
+ * inbound Link supports unterminated line in HS mode. Setting this
+ * attribute to 1 fixes moving to HS gear.
+ */
+ UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP = 1 << 3,
+
+ /*
+ * This quirk needs to be enabled if the host controller only allows
+ * accessing the peer dme attributes in AUTO mode (FAST AUTO or
+ * SLOW AUTO).
+ */
+ UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE = 1 << 4,
+
+ /*
+ * This quirk needs to be enabled if the host controller doesn't
+ * advertise the correct version in UFS_VER register. If this quirk
+ * is enabled, standard UFS host driver will call the vendor specific
+ * ops (get_ufs_hci_version) to get the correct version.
+ */
+ UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION = 1 << 5,
+
+ /*
+ * Clear handling for transfer/task request list is just opposite.
+ */
+ UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR = 1 << 6,
+
+ /*
+ * This quirk needs to be enabled if host controller doesn't allow
+ * that the interrupt aggregation timer and counter are reset by s/w.
+ */
+ UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR = 1 << 7,
+
+ /*
+ * This quirks needs to be enabled if host controller cannot be
+ * enabled via HCE register.
+ */
+ UFSHCI_QUIRK_BROKEN_HCE = 1 << 8,
+
+ /*
+ * This quirk needs to be enabled if the host controller regards
+ * resolution of the values of PRDTO and PRDTL in UTRD as byte.
+ */
+ UFSHCD_QUIRK_PRDT_BYTE_GRAN = 1 << 9,
+
+ /*
+ * This quirk needs to be enabled if the host controller reports
+ * OCS FATAL ERROR with device error through sense data
+ */
+ UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR = 1 << 10,
+
+ /*
+ * This quirk needs to be enabled if the host controller has
+ * auto-hibernate capability but it doesn't work.
+ */
+ UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8 = 1 << 11,
+
+ /*
+ * This quirk needs to disable manual flush for write booster
+ */
+ UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL = 1 << 12,
+
+ /*
+ * This quirk needs to disable unipro timeout values
+ * before power mode change
+ */
+ UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13,
+
+ /*
+ * This quirk needs to be enabled if the host controller does not
+ * support UIC command
+ */
+ UFSHCD_QUIRK_BROKEN_UIC_CMD = 1 << 15,
+
+ /*
+ * This quirk needs to be enabled if the host controller cannot
+ * support physical host configuration.
+ */
+ UFSHCD_QUIRK_SKIP_PH_CONFIGURATION = 1 << 16,
+
+ /*
+ * This quirk needs to be enabled if the host controller has
+ * 64-bit addressing supported capability but it doesn't work.
+ */
+ UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS = 1 << 17,
+
+ /*
+ * This quirk needs to be enabled if the host controller has
+ * auto-hibernate capability but it's FASTAUTO only.
+ */
+ UFSHCD_QUIRK_HIBERN_FASTAUTO = 1 << 18,
+
+ /*
+ * This quirk needs to be enabled if the host controller needs
+ * to reinit the device after switching to maximum gear.
+ */
+ UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH = 1 << 19,
+
+ /*
+ * Some host raises interrupt (per queue) in addition to
+ * CQES (traditional) when ESI is disabled.
+ * Enable this quirk will disable CQES and use per queue interrupt.
+ */
+ UFSHCD_QUIRK_MCQ_BROKEN_INTR = 1 << 20,
+
+ /*
+ * Some host does not implement SQ Run Time Command (SQRTC) register
+ * thus need this quirk to skip related flow.
+ */
+ UFSHCD_QUIRK_MCQ_BROKEN_RTC = 1 << 21,
+
+ /*
+ * This quirk needs to be enabled if the host controller supports inline
+ * encryption but it needs to initialize the crypto capabilities in a
+ * nonstandard way and/or needs to override blk_crypto_ll_ops. If
+ * enabled, the standard code won't initialize the blk_crypto_profile;
+ * ufs_hba_variant_ops::init() must do it instead.
+ */
+ UFSHCD_QUIRK_CUSTOM_CRYPTO_PROFILE = 1 << 22,
+
+ /*
+ * This quirk needs to be enabled if the host controller supports inline
+ * encryption but does not support the CRYPTO_GENERAL_ENABLE bit, i.e.
+ * host controller initialization fails if that bit is set.
+ */
+ UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE = 1 << 23,
+
+ /*
+ * This quirk needs to be enabled if the host controller driver copies
+ * cryptographic keys into the PRDT in order to send them to hardware,
+ * and therefore the PRDT should be zeroized after each request (as per
+ * the standard best practice for managing keys).
+ */
+ UFSHCD_QUIRK_KEYS_IN_PRDT = 1 << 24,
+
+ /*
+ * This quirk indicates that the controller reports the value 1 (not
+ * supported) in the Legacy Single DoorBell Support (LSDBS) bit of the
+ * Controller Capabilities register although it supports the legacy
+ * single doorbell mode.
+ */
+ UFSHCD_QUIRK_BROKEN_LSDBS_CAP = 1 << 25,
};
struct ufs_hba {
@@ -710,27 +877,7 @@ struct ufs_hba {
u32 capabilities;
u32 version;
u32 intr_mask;
- u32 quirks;
-/*
- * If UFS host controller is having issue in processing LCC (Line
- * Control Command) coming from device then enable this quirk.
- * When this quirk is enabled, host controller driver should disable
- * the LCC transmission on UFS device (by clearing TX_LCC_ENABLE
- * attribute of device to 0).
- */
-#define UFSHCD_QUIRK_BROKEN_LCC BIT(0)
-
-/*
- * This quirk needs to be enabled if the host controller has
- * 64-bit addressing supported capability but it doesn't work.
- */
-#define UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS BIT(1)
-
-/*
- * This quirk needs to be enabled if the host controller has
- * auto-hibernate capability but it's FASTAUTO only.
- */
-#define UFSHCD_QUIRK_HIBERN_FASTAUTO BIT(2)
+ enum ufshcd_quirks quirks;
/* Virtual memory reference */
struct utp_transfer_cmd_desc *ucdl;
@@ -758,6 +905,15 @@ static inline int ufshcd_ops_init(struct ufs_hba *hba)
return 0;
}
+static inline int ufshcd_ops_get_max_pwr_mode(struct ufs_hba *hba,
+ struct ufs_pwr_mode_info *max_pwr_info)
+{
+ if (hba->ops && hba->ops->get_max_pwr_mode)
+ return hba->ops->get_max_pwr_mode(hba, max_pwr_info);
+
+ return 0;
+}
+
static inline int ufshcd_ops_hce_enable_notify(struct ufs_hba *hba,
bool status)
{
@@ -776,6 +932,14 @@ static inline int ufshcd_ops_link_startup_notify(struct ufs_hba *hba,
return 0;
}
+static inline int ufshcd_vops_device_reset(struct ufs_hba *hba)
+{
+ if (hba->ops && hba->ops->device_reset)
+ return hba->ops->device_reset(hba);
+
+ return 0;
+}
+
/* Controller UFSHCI version */
enum {
UFSHCI_VERSION_10 = 0x00010000, /* 1.0 */
@@ -784,6 +948,7 @@ enum {
UFSHCI_VERSION_21 = 0x00000210, /* 2.1 */
UFSHCI_VERSION_30 = 0x00000300, /* 3.0 */
UFSHCI_VERSION_31 = 0x00000310, /* 3.1 */
+ UFSHCI_VERSION_40 = 0x00000400, /* 4.0 */
};
/* Interrupt disable masks */
@@ -921,6 +1086,23 @@ enum {
#define ufshcd_readl(hba, reg) \
readl((hba)->mmio_base + (reg))
+/**
+ * ufshcd_rmwl - perform read/modify/write for a controller register
+ * @hba: per adapter instance
+ * @mask: mask to apply on read value
+ * @val: actual value to write
+ * @reg: register address
+ */
+static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg)
+{
+ u32 tmp;
+
+ tmp = ufshcd_readl(hba, reg);
+ tmp &= ~mask;
+ tmp |= (val & mask);
+ ufshcd_writel(hba, tmp, reg);
+}
+
/* UTRLRSR - UTP Transfer Request Run-Stop Register 60h */
#define UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT 0x1