From 5a244e0ea67b293abb1d26c825db2ddde5f2862f Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Wed, 29 Jan 2020 18:52:50 +0800 Subject: scsi: ufs: fix Auto-Hibern8 error detection Auto-Hibern8 may be disabled by some vendors or sysfs in runtime even if Auto-Hibern8 capability is supported by host. If Auto-Hibern8 capability is supported by host but not actually enabled, Auto-Hibern8 error shall not happen. To fix this, provide a way to detect if Auto-Hibern8 is actually enabled first, and bypass Auto-Hibern8 disabling case in ufshcd_is_auto_hibern8_error(). Fixes: 821744403913 ("scsi: ufs: Add error-handling of Auto-Hibernate") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200129105251.12466-4-stanley.chu@mediatek.com Reviewed-by: Bean Huo Reviewed-by: Alim Akhtar Reviewed-by: Asutosh Das Reviewed-by: Can Guo Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 2ae6c7c8528c..81c71a3e3474 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -55,6 +55,7 @@ #include #include #include +#include #include "unipro.h" #include @@ -773,6 +774,11 @@ static inline bool ufshcd_is_auto_hibern8_supported(struct ufs_hba *hba) return (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT); } +static inline bool ufshcd_is_auto_hibern8_enabled(struct ufs_hba *hba) +{ + return FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, hba->ahit) ? true : false; +} + #define ufshcd_writel(hba, val, reg) \ writel((val), (hba)->mmio_base + (reg)) #define ufshcd_readl(hba, reg) \ -- cgit From 984eaac133e3d6d993ffd4de9e4bdc2c94de742b Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Fri, 7 Feb 2020 15:03:57 +0800 Subject: scsi: ufs: introduce common function to disable host TX LCC Many vendors would like to disable host TX LCC during initialization flow. Introduce a common function for all users to make drivers easier to read and maintained. This patch does not change any functionality. Link: https://lore.kernel.org/r/20200207070357.17169-3-stanley.chu@mediatek.com Reviewed-by: Can Guo Reviewed-by: Avri Altman Reviewed-by: Asutosh Das Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 81c71a3e3474..8f516b205c32 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -914,6 +914,11 @@ static inline bool ufshcd_is_hs_mode(struct ufs_pa_layer_attr *pwr_info) pwr_info->pwr_tx == FASTAUTO_MODE); } +static inline int ufshcd_disable_host_tx_lcc(struct ufs_hba *hba) +{ + return ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); +} + /* Expose Query-Request API */ int ufshcd_query_descriptor_retry(struct ufs_hba *hba, enum query_opcode opcode, -- cgit From 492001990f641b0d0df4dbd45c759785fda76f5b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 21 Feb 2020 06:08:11 -0800 Subject: scsi: ufshcd: remove unused quirks Remove various quirks that don't have users, as well as the dead code keyed off them. Link: https://lore.kernel.org/r/20200221140812.476338-2-hch@lst.de Reviewed-by: Bart Van Assche Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 8f516b205c32..6f22f466668f 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -613,28 +613,6 @@ struct ufs_hba { */ #define UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION 0x20 - /* - * This quirk needs to be enabled if the host contoller regards - * resolution of the values of PRDTO and PRDTL in UTRD as byte. - */ - #define UFSHCD_QUIRK_PRDT_BYTE_GRAN 0x80 - - /* - * Clear handling for transfer/task request list is just opposite. - */ - #define UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR 0x100 - - /* - * This quirk needs to be enabled if host controller doesn't allow - * that the interrupt aggregation timer and counter are reset by s/w. - */ - #define UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR 0x200 - - /* - * This quirks needs to be enabled if host controller cannot be - * enabled via HCE register. - */ - #define UFSHCI_QUIRK_BROKEN_HCE 0x400 unsigned int quirks; /* Deviations from standard UFSHCI spec. */ /* Device deviations from standard UFS device spec. */ -- cgit From c3f7d1fcb4a26a0f2a45e0e3bd8a1acc19481b8c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 21 Feb 2020 06:08:12 -0800 Subject: scsi: ufshcd: use an enum for quirks Use an enum to specify the various quirks instead of #defines inside the structure definition. [mkp: fix typo] Link: https://lore.kernel.org/r/20200221140812.476338-3-hch@lst.de Reviewed-by: Bart Van Assche Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 82 ++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 40 deletions(-) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 6f22f466668f..d45a04444191 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -470,6 +470,48 @@ struct ufs_stats { struct ufs_err_reg_hist task_abort; }; +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, +}; + /** * struct ufs_hba - per adapter private structure * @mmio_base: UFSHCI base register address @@ -573,46 +615,6 @@ struct ufs_hba { bool is_irq_enabled; enum ufs_ref_clk_freq dev_ref_clk_freq; - /* Interrupt aggregation support is broken */ - #define UFSHCD_QUIRK_BROKEN_INTR_AGGR 0x1 - - /* - * delay before each dme command is required as the unipro - * layer has shown instabilities - */ - #define UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS 0x2 - - /* - * 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 0x4 - - /* - * 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. - */ - #define UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP 0x8 - - /* - * This quirk needs to be enabled if the host contoller only allows - * accessing the peer dme attributes in AUTO mode (FAST AUTO or - * SLOW AUTO). - */ - #define UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE 0x10 - - /* - * This quirk needs to be enabled if the host contoller 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. - */ - #define UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION 0x20 - unsigned int quirks; /* Deviations from standard UFSHCI spec. */ /* Device deviations from standard UFS device spec. */ -- cgit From c2014682d03d80cfdf5eac440f8e96dce7dfe213 Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Wed, 18 Mar 2020 18:40:11 +0800 Subject: scsi: ufs: use an enum for host capabilities Use an enum to specify the host capabilities instead of #defines inside the structure definition. Link: https://lore.kernel.org/r/20200318104016.28049-3-stanley.chu@mediatek.com Reviewed-by: Avri Altman Reviewed-by: Can Guo Reviewed-by: Bean Huo Reviewed-by: Asutosh Das Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 65 +++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 28 deletions(-) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index d45a04444191..91a47ea61d9a 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -512,6 +512,43 @@ enum ufshcd_quirks { UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION = 1 << 5, }; +enum ufshcd_caps { + /* Allow dynamic clk gating */ + UFSHCD_CAP_CLK_GATING = 1 << 0, + + /* Allow hiberb8 with clk gating */ + UFSHCD_CAP_HIBERN8_WITH_CLK_GATING = 1 << 1, + + /* Allow dynamic clk scaling */ + UFSHCD_CAP_CLK_SCALING = 1 << 2, + + /* Allow auto bkops to enabled during runtime suspend */ + UFSHCD_CAP_AUTO_BKOPS_SUSPEND = 1 << 3, + + /* + * This capability allows host controller driver to use the UFS HCI's + * interrupt aggregation capability. + * CAUTION: Enabling this might reduce overall UFS throughput. + */ + UFSHCD_CAP_INTR_AGGR = 1 << 4, + + /* + * This capability allows the device auto-bkops to be always enabled + * except during suspend (both runtime and suspend). + * Enabling this capability means that device will always be allowed + * to do background operation when it's active but it might degrade + * the performance of ongoing read/write operations. + */ + UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND = 1 << 5, + + /* + * This capability allows host controller driver to automatically + * enable runtime power management by itself instead of waiting + * for userspace to control the power management. + */ + UFSHCD_CAP_RPM_AUTOSUSPEND = 1 << 6, +}; + /** * struct ufs_hba - per adapter private structure * @mmio_base: UFSHCI base register address @@ -669,34 +706,6 @@ struct ufs_hba { struct ufs_clk_gating clk_gating; /* Control to enable/disable host capabilities */ u32 caps; - /* Allow dynamic clk gating */ -#define UFSHCD_CAP_CLK_GATING (1 << 0) - /* Allow hiberb8 with clk gating */ -#define UFSHCD_CAP_HIBERN8_WITH_CLK_GATING (1 << 1) - /* Allow dynamic clk scaling */ -#define UFSHCD_CAP_CLK_SCALING (1 << 2) - /* Allow auto bkops to enabled during runtime suspend */ -#define UFSHCD_CAP_AUTO_BKOPS_SUSPEND (1 << 3) - /* - * This capability allows host controller driver to use the UFS HCI's - * interrupt aggregation capability. - * CAUTION: Enabling this might reduce overall UFS throughput. - */ -#define UFSHCD_CAP_INTR_AGGR (1 << 4) - /* - * This capability allows the device auto-bkops to be always enabled - * except during suspend (both runtime and suspend). - * Enabling this capability means that device will always be allowed - * to do background operation when it's active but it might degrade - * the performance of ongoing read/write operations. - */ -#define UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND (1 << 5) - /* - * This capability allows host controller driver to automatically - * enable runtime power management by itself instead of waiting - * for userspace to control the power management. - */ -#define UFSHCD_CAP_RPM_AUTOSUSPEND (1 << 6) struct devfreq *devfreq; struct ufs_clk_scaling clk_scaling; -- cgit From 5c955c10d0c26eb920f9cfad11adb58c93f666a0 Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Wed, 18 Mar 2020 18:40:12 +0800 Subject: scsi: ufs: introduce common and flexible delay function Introduce a common delay function to provide flexible way for users to take choices of udelay and usleep_range into consideration according to the required delay time. Link: https://lore.kernel.org/r/20200318104016.28049-4-stanley.chu@mediatek.com Reviewed-by: Avri Altman Reviewed-by: Can Guo Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 91a47ea61d9a..493674f99dcc 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -797,6 +797,7 @@ int ufshcd_init(struct ufs_hba * , void __iomem * , unsigned int); int ufshcd_make_hba_operational(struct ufs_hba *hba); void ufshcd_remove(struct ufs_hba *); int ufshcd_uic_hibern8_exit(struct ufs_hba *hba); +void ufshcd_delay_us(unsigned long us, unsigned long tolerance); int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask, u32 val, unsigned long interval_us, unsigned long timeout_ms, bool can_sleep); -- cgit From b9dc8aca2899fb494d66b6c5f50c25563d1636a7 Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Wed, 18 Mar 2020 18:40:14 +0800 Subject: scsi: ufs: allow custom delay prior to host enabling Currently a 1 ms delay is applied before polling CONTROLLER_ENABLE bit. This delay may not be required or can be changed in different controllers. Make the delay as a changeable value in struct ufs_hba to allow it customized by vendors. Link: https://lore.kernel.org/r/20200318104016.28049-6-stanley.chu@mediatek.com Reviewed-by: Avri Altman Reviewed-by: Can Guo Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 493674f99dcc..9f1576bbfc50 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -668,6 +668,7 @@ struct ufs_hba { u32 eh_flags; u32 intr_mask; u16 ee_ctrl_mask; + u16 hba_enable_delay_us; bool is_powered; struct ufs_init_prefetch init_prefetch_data; -- cgit From 2c75f9a5be53501a6e733cd72c1c46281eaa49a0 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Wed, 25 Mar 2020 11:29:01 -0700 Subject: scsi: ufshcd: Let vendor override devfreq parameters Vendor drivers may have a need to update the polling interval and thresholds. Provide a vops for vendor drivers to use. Link: https://lore.kernel.org/r/acd79e00396cff855256adad47f615ccdbde85ac.1585160616.git.asutoshd@codeaurora.org Acked-by: Avri Altman Signed-off-by: Asutosh Das Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 9f1576bbfc50..fce7606b2857 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -56,6 +56,7 @@ #include #include #include +#include #include "unipro.h" #include @@ -327,6 +328,9 @@ struct ufs_hba_variant_ops { void (*dbg_register_dump)(struct ufs_hba *hba); int (*phy_initialization)(struct ufs_hba *); void (*device_reset)(struct ufs_hba *hba); + void (*config_scaling_param)(struct ufs_hba *hba, + struct devfreq_dev_profile *profile, + void *data); }; /* clock gating state */ @@ -1094,6 +1098,14 @@ static inline void ufshcd_vops_device_reset(struct ufs_hba *hba) } } +static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba, + struct devfreq_dev_profile + *profile, void *data) +{ + if (hba->vops && hba->vops->config_scaling_param) + hba->vops->config_scaling_param(hba, profile, data); +} + extern struct ufs_pm_lvl_states ufs_pm_lvl_states[]; /* -- cgit From e89860f196fca353d1b93c95b6a5b4fd88178d3b Mon Sep 17 00:00:00 2001 From: Can Guo Date: Thu, 26 Mar 2020 02:25:41 -0700 Subject: scsi: ufs: Do not rely on prefetched data We were setting bActiveICCLevel attribute for UFS device only once but the type of this attribute has changed from persistent to volatile since UFS device specification v2.1. This attribute is set to the default value after power cycle or hardware reset event. It isn't safe to rely on prefetched data (only used for bActiveICCLevel attribute now). Hence this change removes the code related to data prefetching and set this parameter on every attempt to probe the UFS device. Tested-by: Stanley Chu Reviewed-by: Stanley Chu Reviewed-by: Avri Altman Signed-off-by: Can Guo Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers/scsi/ufs/ufshcd.h') diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index fce7606b2857..dd1ee277069a 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -408,15 +408,6 @@ struct ufs_clk_scaling { bool is_suspended; }; -/** - * struct ufs_init_prefetch - contains data that is pre-fetched once during - * initialization - * @icc_level: icc level which was read during initialization - */ -struct ufs_init_prefetch { - u32 icc_level; -}; - #define UFS_ERR_REG_HIST_LENGTH 8 /** * struct ufs_err_reg_hist - keeps history of errors @@ -585,7 +576,6 @@ enum ufshcd_caps { * @intr_mask: Interrupt Mask Bits * @ee_ctrl_mask: Exception event control mask * @is_powered: flag to check if HBA is powered - * @init_prefetch_data: data pre-fetched during initialization * @eh_work: Worker to handle UFS errors that require s/w attention * @eeh_work: Worker to handle exception events * @errors: HBA errors @@ -674,7 +664,6 @@ struct ufs_hba { u16 ee_ctrl_mask; u16 hba_enable_delay_us; bool is_powered; - struct ufs_init_prefetch init_prefetch_data; /* Work Queues */ struct work_struct eh_work; -- cgit