Hi,
This patchset do some cleanups in ufs host driver and make the delay for host enabling customizable
by different controller or vendors.
Stanley Chu (4):
scsi: ufs: remove init_prefetch_data in struct ufs_hba
scsi: ufs: use an enum for host capabilities
scsi: ufs: allow customized delay for host enabling
scsi: ufs-mediatek: remove delay for host enabling
drivers/scsi/ufs/ufs-mediatek.c | 2 +
drivers/scsi/ufs/ufshcd.c | 21 +++++-----
drivers/scsi/ufs/ufshcd.h | 68 ++++++++++++++++++---------------
3 files changed, 51 insertions(+), 40 deletions(-)
--
2.18.0
Use an enum to specify the host capabilities instead of #defines inside the
structure definition.
Signed-off-by: Stanley Chu <[email protected]>
---
drivers/scsi/ufs/ufshcd.h | 65 ++++++++++++++++++++++-----------------
1 file changed, 37 insertions(+), 28 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 4e235cef99bc..49ade1bfd085 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -510,6 +510,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
@@ -662,34 +699,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;
--
2.18.0
MediaTek platform and UFS controller do not require the delay
for host enabling, thus remove it.
Signed-off-by: Stanley Chu <[email protected]>
---
drivers/scsi/ufs/ufs-mediatek.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 3b0e575d7460..ea3b5fd62492 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -258,6 +258,8 @@ static int ufs_mtk_init(struct ufs_hba *hba)
if (err)
goto out_variant_clear;
+ hba->hba_enable_delay_us = 0;
+
/* Enable runtime autosuspend */
hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
--
2.18.0
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.
Signed-off-by: Stanley Chu <[email protected]>
---
drivers/scsi/ufs/ufshcd.c | 6 +++++-
drivers/scsi/ufs/ufshcd.h | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index ed61ecb98b2d..39cae907abd0 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4282,7 +4282,10 @@ int ufshcd_hba_enable(struct ufs_hba *hba)
* instruction might be read back.
* This delay can be changed based on the controller.
*/
- usleep_range(1000, 1100);
+ if (hba->hba_enable_delay_us) {
+ usleep_range(hba->hba_enable_delay_us,
+ hba->hba_enable_delay_us + 100);
+ }
/* wait for the host controller to complete initialization */
retry = 10;
@@ -8402,6 +8405,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
hba->mmio_base = mmio_base;
hba->irq = irq;
+ hba->hba_enable_delay_us = 1000;
err = ufshcd_hba_init(hba);
if (err)
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 49ade1bfd085..baf1143d4839 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -662,6 +662,7 @@ struct ufs_hba {
u32 eh_flags;
u32 intr_mask;
u16 ee_ctrl_mask;
+ u16 hba_enable_delay_us;
bool is_powered;
/* Work Queues */
--
2.18.0
Hi Stanley,
On 2020-03-05 12:07, Stanley Chu wrote:
> Use an enum to specify the host capabilities instead of #defines inside
> the
> structure definition.
>
> Signed-off-by: Stanley Chu <[email protected]>
Reviewed-by: Can Guo <[email protected]>
> ---
> drivers/scsi/ufs/ufshcd.h | 65 ++++++++++++++++++++++-----------------
> 1 file changed, 37 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> index 4e235cef99bc..49ade1bfd085 100644
> --- a/drivers/scsi/ufs/ufshcd.h
> +++ b/drivers/scsi/ufs/ufshcd.h
> @@ -510,6 +510,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
> @@ -662,34 +699,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;
Hi Stanley,
On 2020-03-05 12:07, Stanley Chu wrote:
> 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.
>
> Signed-off-by: Stanley Chu <[email protected]>
Reviewed-by: Can Guo <[email protected]>
> ---
> drivers/scsi/ufs/ufshcd.c | 6 +++++-
> drivers/scsi/ufs/ufshcd.h | 1 +
> 2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index ed61ecb98b2d..39cae907abd0 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -4282,7 +4282,10 @@ int ufshcd_hba_enable(struct ufs_hba *hba)
> * instruction might be read back.
> * This delay can be changed based on the controller.
> */
> - usleep_range(1000, 1100);
> + if (hba->hba_enable_delay_us) {
> + usleep_range(hba->hba_enable_delay_us,
> + hba->hba_enable_delay_us + 100);
> + }
>
> /* wait for the host controller to complete initialization */
> retry = 10;
> @@ -8402,6 +8405,7 @@ int ufshcd_init(struct ufs_hba *hba, void
> __iomem *mmio_base, unsigned int irq)
>
> hba->mmio_base = mmio_base;
> hba->irq = irq;
> + hba->hba_enable_delay_us = 1000;
>
> err = ufshcd_hba_init(hba);
> if (err)
> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> index 49ade1bfd085..baf1143d4839 100644
> --- a/drivers/scsi/ufs/ufshcd.h
> +++ b/drivers/scsi/ufs/ufshcd.h
> @@ -662,6 +662,7 @@ struct ufs_hba {
> u32 eh_flags;
> u32 intr_mask;
> u16 ee_ctrl_mask;
> + u16 hba_enable_delay_us;
> bool is_powered;
>
> /* Work Queues */
Hi Stanley,
>
>
> MediaTek platform and UFS controller do not require the delay
> for host enabling, thus remove it.
>
> Signed-off-by: Stanley Chu <[email protected]>
> ---
> drivers/scsi/ufs/ufs-mediatek.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
> index 3b0e575d7460..ea3b5fd62492 100644
> --- a/drivers/scsi/ufs/ufs-mediatek.c
> +++ b/drivers/scsi/ufs/ufs-mediatek.c
> @@ -258,6 +258,8 @@ static int ufs_mtk_init(struct ufs_hba *hba)
I would expect to set whatever is needed for your host controller
In ufshcd_vops_hce_enable_notify(hba, PRE_CHANGE), and not here.
Thanks,
Avri
> if (err)
> goto out_variant_clear;
>
> + hba->hba_enable_delay_us = 0;
> +
> /* Enable runtime autosuspend */
> hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
>
> --
> 2.18.0
Hi Avri,
On Thu, 2020-03-05 at 13:14 +0000, Avri Altman wrote:
> Hi Stanley,
>
> >
> >
> > MediaTek platform and UFS controller do not require the delay
> > for host enabling, thus remove it.
> >
> > Signed-off-by: Stanley Chu <[email protected]>
> > ---
> > drivers/scsi/ufs/ufs-mediatek.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
> > index 3b0e575d7460..ea3b5fd62492 100644
> > --- a/drivers/scsi/ufs/ufs-mediatek.c
> > +++ b/drivers/scsi/ufs/ufs-mediatek.c
> > @@ -258,6 +258,8 @@ static int ufs_mtk_init(struct ufs_hba *hba)
> I would expect to set whatever is needed for your host controller
> In ufshcd_vops_hce_enable_notify(hba, PRE_CHANGE), and not here.
>
I think this is a good suggestion! And thus we could have more
flexibility to customize the value according to different scenarios.
I will consider this approach in next version.
Thanks!
Stanley Chu