linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes
@ 2019-11-19  7:04 sheebab
  2019-11-19  7:04 ` [PATCH RESEND 1/2] scsi: ufs: Enable hibern8 interrupt only during manual hibern8 in Cadence UFS sheebab
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: sheebab @ 2019-11-19  7:04 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, pedrom.sousa, jejb, martin.petersen,
	stanley.chu, beanhuo, yuehaibing, linux-scsi, linux-kernel,
	vigneshr, linux-block
  Cc: rafalc, mparab, sheebab

Hi,

Resending this patch to include mailing list and miss out patches.

This patch set contains following patches
for Cadence UFS controller driver.

1. 0001-scsi-ufs-Enable-hibern8-interrupt-only-during-manual.patch
   This patch is to fix false interrupt assertion during auto hibernation.
   In this patch, hibern8 interrupt is Disabled during initialization
   and later the interrupt is Enabled/Disabled during manual hibern8
   Entry/Exit.
2. 0002-scsi-ufs-Update-L4-attributes-on-manual-hibern8-exit.patch
   This patch is to update L4 attributes during manual hibern8 exit.
   As per JESD220C spec, L4 attributes will be reset to their reset value 
   during DME_HIBERNATION_EXIT. This patch will take backup of the L4 
   parameters before DME_HIBERNATION_ENTER and restores the L4 parameters
   after DME_HIBERNATION_EXIT
   

Thanks,
Sheeba B

sheebab (2):
  scsi: ufs: Enable hibern8 interrupt only during manual hibern8 in
    Cadence UFS.
  scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.

 drivers/scsi/ufs/cdns-pltfrm.c | 172 +++++++++++++++++++++++++++++++++--
 1 file changed, 167 insertions(+), 5 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH RESEND 1/2] scsi: ufs: Enable hibern8 interrupt only during manual hibern8 in Cadence UFS.
  2019-11-19  7:04 [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes sheebab
@ 2019-11-19  7:04 ` sheebab
  2019-11-19  7:04 ` [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit " sheebab
  2019-11-22 11:44 ` [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes Vignesh Raghavendra
  2 siblings, 0 replies; 10+ messages in thread
From: sheebab @ 2019-11-19  7:04 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, pedrom.sousa, jejb, martin.petersen,
	stanley.chu, beanhuo, yuehaibing, linux-scsi, linux-kernel,
	vigneshr, linux-block
  Cc: rafalc, mparab, sheebab

Auto hibern8 causes false interrupt assertion.
To overcome this, disable hibern8 interrupt during initialization
and Enable/Disable hibern8 interrupt during manual hibern8 Entry/Exit.

Signed-off-by: sheebab <sheebab@cadence.com>
---
 drivers/scsi/ufs/cdns-pltfrm.c | 75 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c
index b2af04c..adbbd60 100644
--- a/drivers/scsi/ufs/cdns-pltfrm.c
+++ b/drivers/scsi/ufs/cdns-pltfrm.c
@@ -21,6 +21,32 @@
 #define CDNS_UFS_REG_PHY_XCFGD1	0x113C
 
 /**
+ * cdns_ufs_enable_intr - enable interrupts
+ * @hba: per adapter instance
+ * @intrs: interrupt bits
+ */
+static void cdns_ufs_enable_intr(struct ufs_hba *hba, u32 intrs)
+{
+	u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+	set = set | intrs;
+	ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
+}
+
+/**
+ * cdns_ufs_disable_intr - disable interrupts
+ * @hba: per adapter instance
+ * @intrs: interrupt bits
+ */
+static void cdns_ufs_disable_intr(struct ufs_hba *hba, u32 intrs)
+{
+	u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+	set = set & ~intrs;
+	ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
+}
+
+/**
  * Sets HCLKDIV register value based on the core_clk
  * @hba: host controller instance
  *
@@ -71,10 +97,51 @@ static int cdns_ufs_set_hclkdiv(struct ufs_hba *hba)
 static int cdns_ufs_hce_enable_notify(struct ufs_hba *hba,
 				      enum ufs_notify_change_status status)
 {
-	if (status != PRE_CHANGE)
-		return 0;
+	int err = 0;
+
+	switch (status) {
+	case PRE_CHANGE:
+		err = cdns_ufs_set_hclkdiv(hba);
+		break;
+	case POST_CHANGE:
+		/**
+		 * Hibern8 interrupts(UHESE, UHXSE) disabled
+		 * during initialization.
+		 */
+		cdns_ufs_disable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
+		break;
+	default:
+		dev_err(hba->dev, "%s: invalid status %d\n", __func__, status);
+		err = -EINVAL;
+		break;
+	}
+	return err;
+}
 
-	return cdns_ufs_set_hclkdiv(hba);
+/**
+ * Called around hibern8 enter/exit.
+ * @hba: host controller instance
+ * @cmd: UIC Command
+ * @status: notify stage (pre, post change)
+ *
+ */
+static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd,
+				    enum ufs_notify_change_status status)
+{
+	if (status == PRE_CHANGE && cmd == UIC_CMD_DME_HIBER_ENTER) {
+		/**
+		 * Hibern8 interrupts(UHESE, UHXSE) enabled
+		 * before manual hibernate entry.
+		 */
+		cdns_ufs_enable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
+	}
+	if (status == POST_CHANGE && cmd == UIC_CMD_DME_HIBER_EXIT) {
+		/**
+		 * Hibern8 interrupts(UHESE, UHXSE) disabled
+		 * after manual hibern8 exit.
+		 */
+		cdns_ufs_disable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
+	}
 }
 
 /**
@@ -140,6 +207,7 @@ static const struct ufs_hba_variant_ops cdns_ufs_pltfm_hba_vops = {
 	.name = "cdns-ufs-pltfm",
 	.hce_enable_notify = cdns_ufs_hce_enable_notify,
 	.link_startup_notify = cdns_ufs_link_startup_notify,
+	.hibern8_notify = cdns_ufs_hibern8_notify,
 };
 
 static const struct ufs_hba_variant_ops cdns_ufs_m31_16nm_pltfm_hba_vops = {
@@ -148,6 +216,7 @@ static const struct ufs_hba_variant_ops cdns_ufs_m31_16nm_pltfm_hba_vops = {
 	.hce_enable_notify = cdns_ufs_hce_enable_notify,
 	.link_startup_notify = cdns_ufs_link_startup_notify,
 	.phy_initialization = cdns_ufs_m31_16nm_phy_initialization,
+	.hibern8_notify = cdns_ufs_hibern8_notify,
 };
 
 static const struct of_device_id cdns_ufs_of_match[] = {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
  2019-11-19  7:04 [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes sheebab
  2019-11-19  7:04 ` [PATCH RESEND 1/2] scsi: ufs: Enable hibern8 interrupt only during manual hibern8 in Cadence UFS sheebab
@ 2019-11-19  7:04 ` sheebab
  2019-11-20 16:20   ` Alim Akhtar
  2019-11-28 13:59   ` Alim Akhtar
  2019-11-22 11:44 ` [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes Vignesh Raghavendra
  2 siblings, 2 replies; 10+ messages in thread
From: sheebab @ 2019-11-19  7:04 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, pedrom.sousa, jejb, martin.petersen,
	stanley.chu, beanhuo, yuehaibing, linux-scsi, linux-kernel,
	vigneshr, linux-block
  Cc: rafalc, mparab, sheebab

Backup L4 attributes duirng manual hibern8 entry
and restore the L4 attributes on manual hibern8 exit as per JESD220C.

Signed-off-by: sheebab <sheebab@cadence.com>
---
 drivers/scsi/ufs/cdns-pltfrm.c | 97 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c
index adbbd60..5510567 100644
--- a/drivers/scsi/ufs/cdns-pltfrm.c
+++ b/drivers/scsi/ufs/cdns-pltfrm.c
@@ -19,6 +19,14 @@
 
 #define CDNS_UFS_REG_HCLKDIV	0xFC
 #define CDNS_UFS_REG_PHY_XCFGD1	0x113C
+#define CDNS_UFS_MAX 12
+
+struct cdns_ufs_host {
+	/**
+	 * cdns_ufs_dme_attr_val - for storing L4 attributes
+	 */
+	u32 cdns_ufs_dme_attr_val[CDNS_UFS_MAX];
+};
 
 /**
  * cdns_ufs_enable_intr - enable interrupts
@@ -47,6 +55,77 @@ static void cdns_ufs_disable_intr(struct ufs_hba *hba, u32 intrs)
 }
 
 /**
+ * cdns_ufs_get_l4_attr - get L4 attributes on local side
+ * @hba: per adapter instance
+ *
+ */
+static void cdns_ufs_get_l4_attr(struct ufs_hba *hba)
+{
+	struct cdns_ufs_host *host = ufshcd_get_variant(hba);
+
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERDEVICEID),
+		       &host->cdns_ufs_dme_attr_val[0]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERCPORTID),
+		       &host->cdns_ufs_dme_attr_val[1]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
+		       &host->cdns_ufs_dme_attr_val[2]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_PROTOCOLID),
+		       &host->cdns_ufs_dme_attr_val[3]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTFLAGS),
+		       &host->cdns_ufs_dme_attr_val[4]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
+		       &host->cdns_ufs_dme_attr_val[5]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
+		       &host->cdns_ufs_dme_attr_val[6]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
+		       &host->cdns_ufs_dme_attr_val[7]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
+		       &host->cdns_ufs_dme_attr_val[8]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
+		       &host->cdns_ufs_dme_attr_val[9]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTMODE),
+		       &host->cdns_ufs_dme_attr_val[10]);
+	ufshcd_dme_get(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
+		       &host->cdns_ufs_dme_attr_val[11]);
+}
+
+/**
+ * cdns_ufs_set_l4_attr - set L4 attributes on local side
+ * @hba: per adapter instance
+ *
+ */
+static void cdns_ufs_set_l4_attr(struct ufs_hba *hba)
+{
+	struct cdns_ufs_host *host = ufshcd_get_variant(hba);
+
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 0);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID),
+		       host->cdns_ufs_dme_attr_val[0]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID),
+		       host->cdns_ufs_dme_attr_val[1]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
+		       host->cdns_ufs_dme_attr_val[2]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PROTOCOLID),
+		       host->cdns_ufs_dme_attr_val[3]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS),
+		       host->cdns_ufs_dme_attr_val[4]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
+		       host->cdns_ufs_dme_attr_val[5]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
+		       host->cdns_ufs_dme_attr_val[6]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
+		       host->cdns_ufs_dme_attr_val[7]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
+		       host->cdns_ufs_dme_attr_val[8]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
+		       host->cdns_ufs_dme_attr_val[9]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTMODE),
+		       host->cdns_ufs_dme_attr_val[10]);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
+		       host->cdns_ufs_dme_attr_val[11]);
+}
+
+/**
  * Sets HCLKDIV register value based on the core_clk
  * @hba: host controller instance
  *
@@ -134,6 +213,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd,
 		 * before manual hibernate entry.
 		 */
 		cdns_ufs_enable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
+		cdns_ufs_get_l4_attr(hba);
 	}
 	if (status == POST_CHANGE && cmd == UIC_CMD_DME_HIBER_EXIT) {
 		/**
@@ -141,6 +221,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd,
 		 * after manual hibern8 exit.
 		 */
 		cdns_ufs_disable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
+		cdns_ufs_set_l4_attr(hba);
 	}
 }
 
@@ -245,15 +326,27 @@ static int cdns_ufs_pltfrm_probe(struct platform_device *pdev)
 	const struct of_device_id *of_id;
 	struct ufs_hba_variant_ops *vops;
 	struct device *dev = &pdev->dev;
+	struct cdns_ufs_host *host;
+	struct ufs_hba *hba;
 
 	of_id = of_match_node(cdns_ufs_of_match, dev->of_node);
 	vops = (struct ufs_hba_variant_ops *)of_id->data;
 
 	/* Perform generic probe */
 	err = ufshcd_pltfrm_init(pdev, vops);
-	if (err)
+	if (err) {
 		dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
-
+		goto out;
+	}
+	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
+	if (!host) {
+		err = -ENOMEM;
+		dev_err(dev, "%s: no memory for cdns host\n", __func__);
+		goto out;
+	}
+	hba =  platform_get_drvdata(pdev);
+	ufshcd_set_variant(hba, host);
+out:
 	return err;
 }
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
  2019-11-19  7:04 ` [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit " sheebab
@ 2019-11-20 16:20   ` Alim Akhtar
  2019-11-21 10:56     ` Vignesh Raghavendra
  2019-11-28 13:59   ` Alim Akhtar
  1 sibling, 1 reply; 10+ messages in thread
From: Alim Akhtar @ 2019-11-20 16:20 UTC (permalink / raw)
  To: sheebab
  Cc: Alim Akhtar, Avri Altman, Pedro Sousa, James E.J. Bottomley,
	Martin K. Petersen, Stanley Chu, Bean Huo (beanhuo),
	yuehaibing, linux-scsi, open list, Vignesh Raghavendra,
	linux-block, rafalc, mparab

Hi Sheebab

On Tue, Nov 19, 2019 at 12:38 PM sheebab <sheebab@cadence.com> wrote:
>
> Backup L4 attributes duirng manual hibern8 entry
> and restore the L4 attributes on manual hibern8 exit as per JESD220C.
>
Can you point me to the relevant section on the spec?

> Signed-off-by: sheebab <sheebab@cadence.com>
> ---
>  drivers/scsi/ufs/cdns-pltfrm.c | 97 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 95 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c
> index adbbd60..5510567 100644
> --- a/drivers/scsi/ufs/cdns-pltfrm.c
> +++ b/drivers/scsi/ufs/cdns-pltfrm.c
> @@ -19,6 +19,14 @@
>
>  #define CDNS_UFS_REG_HCLKDIV   0xFC
>  #define CDNS_UFS_REG_PHY_XCFGD1        0x113C
> +#define CDNS_UFS_MAX 12
> +
> +struct cdns_ufs_host {
> +       /**
> +        * cdns_ufs_dme_attr_val - for storing L4 attributes
> +        */
> +       u32 cdns_ufs_dme_attr_val[CDNS_UFS_MAX];
> +};
>
>  /**
>   * cdns_ufs_enable_intr - enable interrupts
> @@ -47,6 +55,77 @@ static void cdns_ufs_disable_intr(struct ufs_hba *hba, u32 intrs)
>  }
>
>  /**
> + * cdns_ufs_get_l4_attr - get L4 attributes on local side
> + * @hba: per adapter instance
> + *
> + */
> +static void cdns_ufs_get_l4_attr(struct ufs_hba *hba)
> +{
> +       struct cdns_ufs_host *host = ufshcd_get_variant(hba);
> +
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERDEVICEID),
> +                      &host->cdns_ufs_dme_attr_val[0]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERCPORTID),
> +                      &host->cdns_ufs_dme_attr_val[1]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
> +                      &host->cdns_ufs_dme_attr_val[2]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PROTOCOLID),
> +                      &host->cdns_ufs_dme_attr_val[3]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTFLAGS),
> +                      &host->cdns_ufs_dme_attr_val[4]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
> +                      &host->cdns_ufs_dme_attr_val[5]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
> +                      &host->cdns_ufs_dme_attr_val[6]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
> +                      &host->cdns_ufs_dme_attr_val[7]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
> +                      &host->cdns_ufs_dme_attr_val[8]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
> +                      &host->cdns_ufs_dme_attr_val[9]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTMODE),
> +                      &host->cdns_ufs_dme_attr_val[10]);
> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
> +                      &host->cdns_ufs_dme_attr_val[11]);
> +}
> +
> +/**
> + * cdns_ufs_set_l4_attr - set L4 attributes on local side
> + * @hba: per adapter instance
> + *
> + */
> +static void cdns_ufs_set_l4_attr(struct ufs_hba *hba)
> +{
> +       struct cdns_ufs_host *host = ufshcd_get_variant(hba);
> +
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 0);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID),
> +                      host->cdns_ufs_dme_attr_val[0]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID),
> +                      host->cdns_ufs_dme_attr_val[1]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
> +                      host->cdns_ufs_dme_attr_val[2]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PROTOCOLID),
> +                      host->cdns_ufs_dme_attr_val[3]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS),
> +                      host->cdns_ufs_dme_attr_val[4]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
> +                      host->cdns_ufs_dme_attr_val[5]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
> +                      host->cdns_ufs_dme_attr_val[6]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
> +                      host->cdns_ufs_dme_attr_val[7]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
> +                      host->cdns_ufs_dme_attr_val[8]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
> +                      host->cdns_ufs_dme_attr_val[9]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTMODE),
> +                      host->cdns_ufs_dme_attr_val[10]);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
> +                      host->cdns_ufs_dme_attr_val[11]);
> +}
> +
> +/**
>   * Sets HCLKDIV register value based on the core_clk
>   * @hba: host controller instance
>   *
> @@ -134,6 +213,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd,
>                  * before manual hibernate entry.
>                  */
>                 cdns_ufs_enable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
> +               cdns_ufs_get_l4_attr(hba);
>         }
>         if (status == POST_CHANGE && cmd == UIC_CMD_DME_HIBER_EXIT) {
>                 /**
> @@ -141,6 +221,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd,
>                  * after manual hibern8 exit.
>                  */
>                 cdns_ufs_disable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
> +               cdns_ufs_set_l4_attr(hba);
>         }
>  }
>
> @@ -245,15 +326,27 @@ static int cdns_ufs_pltfrm_probe(struct platform_device *pdev)
>         const struct of_device_id *of_id;
>         struct ufs_hba_variant_ops *vops;
>         struct device *dev = &pdev->dev;
> +       struct cdns_ufs_host *host;
> +       struct ufs_hba *hba;
>
>         of_id = of_match_node(cdns_ufs_of_match, dev->of_node);
>         vops = (struct ufs_hba_variant_ops *)of_id->data;
>
>         /* Perform generic probe */
>         err = ufshcd_pltfrm_init(pdev, vops);
> -       if (err)
> +       if (err) {
>                 dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
> -
> +               goto out;
> +       }
> +       host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
> +       if (!host) {
> +               err = -ENOMEM;
> +               dev_err(dev, "%s: no memory for cdns host\n", __func__);
> +               goto out;
> +       }
> +       hba =  platform_get_drvdata(pdev);
> +       ufshcd_set_variant(hba, host);
> +out:
>         return err;
>  }
>
> --
> 2.7.4
>


-- 
Regards,
Alim

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
  2019-11-20 16:20   ` Alim Akhtar
@ 2019-11-21 10:56     ` Vignesh Raghavendra
  2019-11-27  3:42       ` Alim Akhtar
  0 siblings, 1 reply; 10+ messages in thread
From: Vignesh Raghavendra @ 2019-11-21 10:56 UTC (permalink / raw)
  To: Alim Akhtar, sheebab
  Cc: Alim Akhtar, Avri Altman, Pedro Sousa, James E.J. Bottomley,
	Martin K. Petersen, Stanley Chu, Bean Huo (beanhuo),
	yuehaibing, linux-scsi, open list, linux-block, rafalc, mparab



On 20/11/19 9:50 PM, Alim Akhtar wrote:
> Hi Sheebab
> 
> On Tue, Nov 19, 2019 at 12:38 PM sheebab <sheebab@cadence.com> wrote:
>>
>> Backup L4 attributes duirng manual hibern8 entry
>> and restore the L4 attributes on manual hibern8 exit as per JESD220C.
>>
> Can you point me to the relevant section on the spec?
> 

Per JESD 220C 9.4 UniPro/UFS Control Interface (Control Plane):

"NOTE After exit from Hibernate all UniPro Transport Layer attributes (including L4 T_PeerDeviceID, 

L4 T_PeerCPortID, L4 T_ConnectionState, etc.) will be reset to their reset values. All required attributes 

must be restored properly on both ends before communication can resume."

But its not clear whether SW needs to restore these attributes or hardware

Regards
Vignesh

>> Signed-off-by: sheebab <sheebab@cadence.com>
>> ---
>>  drivers/scsi/ufs/cdns-pltfrm.c | 97 +++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 95 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c
>> index adbbd60..5510567 100644
>> --- a/drivers/scsi/ufs/cdns-pltfrm.c
>> +++ b/drivers/scsi/ufs/cdns-pltfrm.c
>> @@ -19,6 +19,14 @@
>>
>>  #define CDNS_UFS_REG_HCLKDIV   0xFC
>>  #define CDNS_UFS_REG_PHY_XCFGD1        0x113C
>> +#define CDNS_UFS_MAX 12
>> +
>> +struct cdns_ufs_host {
>> +       /**
>> +        * cdns_ufs_dme_attr_val - for storing L4 attributes
>> +        */
>> +       u32 cdns_ufs_dme_attr_val[CDNS_UFS_MAX];
>> +};
>>
>>  /**
>>   * cdns_ufs_enable_intr - enable interrupts
>> @@ -47,6 +55,77 @@ static void cdns_ufs_disable_intr(struct ufs_hba *hba, u32 intrs)
>>  }
>>
>>  /**
>> + * cdns_ufs_get_l4_attr - get L4 attributes on local side
>> + * @hba: per adapter instance
>> + *
>> + */
>> +static void cdns_ufs_get_l4_attr(struct ufs_hba *hba)
>> +{
>> +       struct cdns_ufs_host *host = ufshcd_get_variant(hba);
>> +
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERDEVICEID),
>> +                      &host->cdns_ufs_dme_attr_val[0]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERCPORTID),
>> +                      &host->cdns_ufs_dme_attr_val[1]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
>> +                      &host->cdns_ufs_dme_attr_val[2]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PROTOCOLID),
>> +                      &host->cdns_ufs_dme_attr_val[3]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTFLAGS),
>> +                      &host->cdns_ufs_dme_attr_val[4]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
>> +                      &host->cdns_ufs_dme_attr_val[5]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
>> +                      &host->cdns_ufs_dme_attr_val[6]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
>> +                      &host->cdns_ufs_dme_attr_val[7]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
>> +                      &host->cdns_ufs_dme_attr_val[8]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
>> +                      &host->cdns_ufs_dme_attr_val[9]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTMODE),
>> +                      &host->cdns_ufs_dme_attr_val[10]);
>> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
>> +                      &host->cdns_ufs_dme_attr_val[11]);
>> +}
>> +
>> +/**
>> + * cdns_ufs_set_l4_attr - set L4 attributes on local side
>> + * @hba: per adapter instance
>> + *
>> + */
>> +static void cdns_ufs_set_l4_attr(struct ufs_hba *hba)
>> +{
>> +       struct cdns_ufs_host *host = ufshcd_get_variant(hba);
>> +
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 0);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID),
>> +                      host->cdns_ufs_dme_attr_val[0]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID),
>> +                      host->cdns_ufs_dme_attr_val[1]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
>> +                      host->cdns_ufs_dme_attr_val[2]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PROTOCOLID),
>> +                      host->cdns_ufs_dme_attr_val[3]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS),
>> +                      host->cdns_ufs_dme_attr_val[4]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
>> +                      host->cdns_ufs_dme_attr_val[5]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
>> +                      host->cdns_ufs_dme_attr_val[6]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
>> +                      host->cdns_ufs_dme_attr_val[7]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
>> +                      host->cdns_ufs_dme_attr_val[8]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
>> +                      host->cdns_ufs_dme_attr_val[9]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTMODE),
>> +                      host->cdns_ufs_dme_attr_val[10]);
>> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
>> +                      host->cdns_ufs_dme_attr_val[11]);
>> +}
>> +
>> +/**
>>   * Sets HCLKDIV register value based on the core_clk
>>   * @hba: host controller instance
>>   *
>> @@ -134,6 +213,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd,
>>                  * before manual hibernate entry.
>>                  */
>>                 cdns_ufs_enable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
>> +               cdns_ufs_get_l4_attr(hba);
>>         }
>>         if (status == POST_CHANGE && cmd == UIC_CMD_DME_HIBER_EXIT) {
>>                 /**
>> @@ -141,6 +221,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd,
>>                  * after manual hibern8 exit.
>>                  */
>>                 cdns_ufs_disable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
>> +               cdns_ufs_set_l4_attr(hba);
>>         }
>>  }
>>
>> @@ -245,15 +326,27 @@ static int cdns_ufs_pltfrm_probe(struct platform_device *pdev)
>>         const struct of_device_id *of_id;
>>         struct ufs_hba_variant_ops *vops;
>>         struct device *dev = &pdev->dev;
>> +       struct cdns_ufs_host *host;
>> +       struct ufs_hba *hba;
>>
>>         of_id = of_match_node(cdns_ufs_of_match, dev->of_node);
>>         vops = (struct ufs_hba_variant_ops *)of_id->data;
>>
>>         /* Perform generic probe */
>>         err = ufshcd_pltfrm_init(pdev, vops);
>> -       if (err)
>> +       if (err) {
>>                 dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
>> -
>> +               goto out;
>> +       }
>> +       host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
>> +       if (!host) {
>> +               err = -ENOMEM;
>> +               dev_err(dev, "%s: no memory for cdns host\n", __func__);
>> +               goto out;
>> +       }
>> +       hba =  platform_get_drvdata(pdev);
>> +       ufshcd_set_variant(hba, host);
>> +out:
>>         return err;
>>  }
>>
>> --
>> 2.7.4
>>
> 
> 

-- 
Regards
Vignesh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes
  2019-11-19  7:04 [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes sheebab
  2019-11-19  7:04 ` [PATCH RESEND 1/2] scsi: ufs: Enable hibern8 interrupt only during manual hibern8 in Cadence UFS sheebab
  2019-11-19  7:04 ` [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit " sheebab
@ 2019-11-22 11:44 ` Vignesh Raghavendra
  2 siblings, 0 replies; 10+ messages in thread
From: Vignesh Raghavendra @ 2019-11-22 11:44 UTC (permalink / raw)
  To: sheebab, alim.akhtar, avri.altman, pedrom.sousa, jejb,
	martin.petersen, stanley.chu, beanhuo, yuehaibing, linux-scsi,
	linux-kernel, linux-block
  Cc: rafalc, mparab

Hi,

On 19/11/19 12:34 PM, sheebab wrote:
> Hi,
> 
> Resending this patch to include mailing list and miss out patches.
> 
> This patch set contains following patches
> for Cadence UFS controller driver.
> 
> 1. 0001-scsi-ufs-Enable-hibern8-interrupt-only-during-manual.patch
>    This patch is to fix false interrupt assertion during auto hibernation.
>    In this patch, hibern8 interrupt is Disabled during initialization
>    and later the interrupt is Enabled/Disabled during manual hibern8
>    Entry/Exit.
> 2. 0002-scsi-ufs-Update-L4-attributes-on-manual-hibern8-exit.patch
>    This patch is to update L4 attributes during manual hibern8 exit.
>    As per JESD220C spec, L4 attributes will be reset to their reset value 
>    during DME_HIBERNATION_EXIT. This patch will take backup of the L4 
>    parameters before DME_HIBERNATION_ENTER and restores the L4 parameters
>    after DME_HIBERNATION_EXIT
>  

While I don't see flood of hibernate related interrupts anymore, I
occasionally see "Unhandled Interrupt dump"[1] when using rootfs out of
UFS. I haven't be able to find a way to trigger the issue. But seems to
happen randomly while trying to input and execute something from console.


[1]
j7-evm login: root
[   55.300495] cdns-ufshcd 4e84000.ufs: ufshcd_intr: Unhandled interrupt
0x00000000
[   55.307884] host_regs: 00000000: 1587031f 00000000 00000210 00000000
[   55.314217] host_regs: 00000010: 00000000 00000000 00000c96 00000000
[   55.320551] host_regs: 00000020: 00000014 00030e15 00000000 00000000
[   55.326884] host_regs: 00000030: 0000010f 00000001 00000000 80000002
[   55.333217] host_regs: 00000040: 00000000 00000000 00000000 00000000
[   55.339551] host_regs: 00000050: c1ee0000 00000008 00008000 00000000
[   55.345884] host_regs: 00000060: 00000001 ffffffff 00000000 00000000
[   55.352217] host_regs: 00000070: c1ef0000 00000008 00000000 00000000
[   55.358550] host_regs: 00000080: 00000001 00000000 00000000 00000000
[   55.364884] host_regs: 00000090: 00000002 15710000 00000000 00000000

More such occurrence: https://pastebin.ubuntu.com/p/Df4dykkTmB/



> 
> Thanks,
> Sheeba B
> 
> sheebab (2):
>   scsi: ufs: Enable hibern8 interrupt only during manual hibern8 in
>     Cadence UFS.
>   scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
> 
>  drivers/scsi/ufs/cdns-pltfrm.c | 172 +++++++++++++++++++++++++++++++++--
>  1 file changed, 167 insertions(+), 5 deletions(-)
> 

-- 
Regards
Vignesh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
  2019-11-21 10:56     ` Vignesh Raghavendra
@ 2019-11-27  3:42       ` Alim Akhtar
  2019-11-27  4:15         ` Vignesh Raghavendra
  2019-11-27 15:18         ` Avri Altman
  0 siblings, 2 replies; 10+ messages in thread
From: Alim Akhtar @ 2019-11-27  3:42 UTC (permalink / raw)
  To: 'Vignesh Raghavendra', 'Alim Akhtar', 'sheebab'
  Cc: 'Avri Altman', 'Pedro Sousa',
	'James E.J. Bottomley', 'Martin K. Petersen',
	'Stanley Chu', 'Bean Huo (beanhuo)',
	yuehaibing, linux-scsi, 'open list',
	linux-block, rafalc, mparab



> -----Original Message-----
> From: Vignesh Raghavendra <vigneshr@ti.com>
> Sent: 21 November 2019 16:26
> To: Alim Akhtar <alim.akhtar@gmail.com>; sheebab <sheebab@cadence.com>
> Cc: Alim Akhtar <alim.akhtar@samsung.com>; Avri Altman
> <avri.altman@wdc.com>; Pedro Sousa <pedrom.sousa@synopsys.com>; James
> E.J. Bottomley <jejb@linux.ibm.com>; Martin K. Petersen
> <martin.petersen@oracle.com>; Stanley Chu <stanley.chu@mediatek.com>;
> Bean Huo (beanhuo) <beanhuo@micron.com>; yuehaibing@huawei.com; linux-
> scsi@vger.kernel.org; open list <linux-kernel@vger.kernel.org>; linux-
> block@vger.kernel.org; rafalc@cadence.com; mparab@cadence.com
> Subject: Re: [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual
> hibern8 exit in Cadence UFS.
> 
> 
> 
> On 20/11/19 9:50 PM, Alim Akhtar wrote:
> > Hi Sheebab
> >
> > On Tue, Nov 19, 2019 at 12:38 PM sheebab <sheebab@cadence.com> wrote:
> >>
> >> Backup L4 attributes duirng manual hibern8 entry and restore the L4
> >> attributes on manual hibern8 exit as per JESD220C.
> >>
> > Can you point me to the relevant section on the spec?
> >
> 
> Per JESD 220C 9.4 UniPro/UFS Control Interface (Control Plane):
> 
> "NOTE After exit from Hibernate all UniPro Transport Layer attributes (including
> L4 T_PeerDeviceID,
> 
> L4 T_PeerCPortID, L4 T_ConnectionState, etc.) will be reset to their reset values.
> All required attributes
> 
> must be restored properly on both ends before communication can resume."
> 
> But its not clear whether SW needs to restore these attributes or hardware
> 
Thanks Vignesh for pointing out the spec section, yes it is not clear, one way to confirm this is just by read L4 attributes before 
And after hinern8 entry/exit.
(at least in the current platform it is not being done)
AFA this patch is concerns, this looks ok to me.
@ Avri , any thought on this?

> Regards
> Vignesh
> 
> >> Signed-off-by: sheebab <sheebab@cadence.com>
> >> ---
> >>  drivers/scsi/ufs/cdns-pltfrm.c | 97
> >> +++++++++++++++++++++++++++++++++++++++++-
> >>  1 file changed, 95 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/scsi/ufs/cdns-pltfrm.c
> >> b/drivers/scsi/ufs/cdns-pltfrm.c index adbbd60..5510567 100644
> >> --- a/drivers/scsi/ufs/cdns-pltfrm.c
> >> +++ b/drivers/scsi/ufs/cdns-pltfrm.c
> >> @@ -19,6 +19,14 @@
> >>
> >>  #define CDNS_UFS_REG_HCLKDIV   0xFC
> >>  #define CDNS_UFS_REG_PHY_XCFGD1        0x113C
> >> +#define CDNS_UFS_MAX 12
> >> +
> >> +struct cdns_ufs_host {
> >> +       /**
> >> +        * cdns_ufs_dme_attr_val - for storing L4 attributes
> >> +        */
> >> +       u32 cdns_ufs_dme_attr_val[CDNS_UFS_MAX];
> >> +};
> >>
> >>  /**
> >>   * cdns_ufs_enable_intr - enable interrupts @@ -47,6 +55,77 @@
> >> static void cdns_ufs_disable_intr(struct ufs_hba *hba, u32 intrs)  }
> >>
> >>  /**
> >> + * cdns_ufs_get_l4_attr - get L4 attributes on local side
> >> + * @hba: per adapter instance
> >> + *
> >> + */
> >> +static void cdns_ufs_get_l4_attr(struct ufs_hba *hba) {
> >> +       struct cdns_ufs_host *host = ufshcd_get_variant(hba);
> >> +
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERDEVICEID),
> >> +                      &host->cdns_ufs_dme_attr_val[0]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERCPORTID),
> >> +                      &host->cdns_ufs_dme_attr_val[1]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
> >> +                      &host->cdns_ufs_dme_attr_val[2]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PROTOCOLID),
> >> +                      &host->cdns_ufs_dme_attr_val[3]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTFLAGS),
> >> +                      &host->cdns_ufs_dme_attr_val[4]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
> >> +                      &host->cdns_ufs_dme_attr_val[5]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
> >> +                      &host->cdns_ufs_dme_attr_val[6]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
> >> +                      &host->cdns_ufs_dme_attr_val[7]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
> >> +                      &host->cdns_ufs_dme_attr_val[8]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
> >> +                      &host->cdns_ufs_dme_attr_val[9]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTMODE),
> >> +                      &host->cdns_ufs_dme_attr_val[10]);
> >> +       ufshcd_dme_get(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
> >> +                      &host->cdns_ufs_dme_attr_val[11]);
> >> +}
> >> +
> >> +/**
> >> + * cdns_ufs_set_l4_attr - set L4 attributes on local side
> >> + * @hba: per adapter instance
> >> + *
> >> + */
> >> +static void cdns_ufs_set_l4_attr(struct ufs_hba *hba) {
> >> +       struct cdns_ufs_host *host = ufshcd_get_variant(hba);
> >> +
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 0);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID),
> >> +                      host->cdns_ufs_dme_attr_val[0]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID),
> >> +                      host->cdns_ufs_dme_attr_val[1]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
> >> +                      host->cdns_ufs_dme_attr_val[2]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PROTOCOLID),
> >> +                      host->cdns_ufs_dme_attr_val[3]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS),
> >> +                      host->cdns_ufs_dme_attr_val[4]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
> >> +                      host->cdns_ufs_dme_attr_val[5]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
> >> +                      host->cdns_ufs_dme_attr_val[6]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
> >> +                      host->cdns_ufs_dme_attr_val[7]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
> >> +                      host->cdns_ufs_dme_attr_val[8]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
> >> +                      host->cdns_ufs_dme_attr_val[9]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTMODE),
> >> +                      host->cdns_ufs_dme_attr_val[10]);
> >> +       ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
> >> +                      host->cdns_ufs_dme_attr_val[11]); }
> >> +
> >> +/**
> >>   * Sets HCLKDIV register value based on the core_clk
> >>   * @hba: host controller instance
> >>   *
> >> @@ -134,6 +213,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba
> *hba, enum uic_cmd_dme cmd,
> >>                  * before manual hibernate entry.
> >>                  */
> >>                 cdns_ufs_enable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
> >> +               cdns_ufs_get_l4_attr(hba);
> >>         }
> >>         if (status == POST_CHANGE && cmd == UIC_CMD_DME_HIBER_EXIT) {
> >>                 /**
> >> @@ -141,6 +221,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba
> *hba, enum uic_cmd_dme cmd,
> >>                  * after manual hibern8 exit.
> >>                  */
> >>                 cdns_ufs_disable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
> >> +               cdns_ufs_set_l4_attr(hba);
> >>         }
> >>  }
> >>
> >> @@ -245,15 +326,27 @@ static int cdns_ufs_pltfrm_probe(struct
> platform_device *pdev)
> >>         const struct of_device_id *of_id;
> >>         struct ufs_hba_variant_ops *vops;
> >>         struct device *dev = &pdev->dev;
> >> +       struct cdns_ufs_host *host;
> >> +       struct ufs_hba *hba;
> >>
> >>         of_id = of_match_node(cdns_ufs_of_match, dev->of_node);
> >>         vops = (struct ufs_hba_variant_ops *)of_id->data;
> >>
> >>         /* Perform generic probe */
> >>         err = ufshcd_pltfrm_init(pdev, vops);
> >> -       if (err)
> >> +       if (err) {
> >>                 dev_err(dev, "ufshcd_pltfrm_init() failed %d\n",
> >> err);
> >> -
> >> +               goto out;
> >> +       }
> >> +       host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
> >> +       if (!host) {
> >> +               err = -ENOMEM;
> >> +               dev_err(dev, "%s: no memory for cdns host\n", __func__);
> >> +               goto out;
> >> +       }
> >> +       hba =  platform_get_drvdata(pdev);
> >> +       ufshcd_set_variant(hba, host);
> >> +out:
> >>         return err;
> >>  }
> >>
> >> --
> >> 2.7.4
> >>
> >
> >
> 
> --
> Regards
> Vignesh


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
  2019-11-27  3:42       ` Alim Akhtar
@ 2019-11-27  4:15         ` Vignesh Raghavendra
  2019-11-27 15:18         ` Avri Altman
  1 sibling, 0 replies; 10+ messages in thread
From: Vignesh Raghavendra @ 2019-11-27  4:15 UTC (permalink / raw)
  To: Alim Akhtar, 'Alim Akhtar', 'sheebab'
  Cc: 'Avri Altman', 'Pedro Sousa',
	'James E.J. Bottomley', 'Martin K. Petersen',
	'Stanley Chu', 'Bean Huo (beanhuo)',
	yuehaibing, linux-scsi, 'open list',
	linux-block, rafalc, mparab

Hi Alim,

On 27/11/19 9:12 AM, Alim Akhtar wrote:
> 
[...]
>>>> Backup L4 attributes duirng manual hibern8 entry and restore the L4
>>>> attributes on manual hibern8 exit as per JESD220C.
>>>>
>>> Can you point me to the relevant section on the spec?
>>>
>>
>> Per JESD 220C 9.4 UniPro/UFS Control Interface (Control Plane):
>>
>> "NOTE After exit from Hibernate all UniPro Transport Layer attributes (including
>> L4 T_PeerDeviceID,
>>
>> L4 T_PeerCPortID, L4 T_ConnectionState, etc.) will be reset to their reset values.
>> All required attributes
>>
>> must be restored properly on both ends before communication can resume."
>>
>> But its not clear whether SW needs to restore these attributes or hardware
>>
> Thanks Vignesh for pointing out the spec section, yes it is not clear, one way to confirm this is just by read L4 attributes before 
> And after hinern8 entry/exit.

I know that on Cadence UFS controller L4 attributes are definitely lost
on hibernation entry/exit and therefore needs to be restored. But not
sure of other controllers. If this issue is seen on other controllers as
well, then we should probably consider moving this code to core driver
so that there is code reuse.

> (at least in the current platform it is not being done)
> AFA this patch is concerns, this looks ok to me.
> @ Avri , any thought on this?
> 
>> Regards
>> Vignesh
>>

[...]
-- 
Regards
Vignesh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
  2019-11-27  3:42       ` Alim Akhtar
  2019-11-27  4:15         ` Vignesh Raghavendra
@ 2019-11-27 15:18         ` Avri Altman
  1 sibling, 0 replies; 10+ messages in thread
From: Avri Altman @ 2019-11-27 15:18 UTC (permalink / raw)
  To: Alim Akhtar, 'Vignesh Raghavendra', 'Alim Akhtar',
	'sheebab'
  Cc: 'Pedro Sousa', 'James E.J. Bottomley',
	'Martin K. Petersen', 'Stanley Chu',
	'Bean Huo (beanhuo)',
	yuehaibing, linux-scsi, 'open list',
	linux-block, rafalc, mparab

 

> >
> >
> > On 20/11/19 9:50 PM, Alim Akhtar wrote:
> > > Hi Sheebab
> > >
> > > On Tue, Nov 19, 2019 at 12:38 PM sheebab <sheebab@cadence.com>
> wrote:
> > >>
> > >> Backup L4 attributes duirng manual hibern8 entry and restore the L4
> > >> attributes on manual hibern8 exit as per JESD220C.
> > >>
> > > Can you point me to the relevant section on the spec?
> > >
> >
> > Per JESD 220C 9.4 UniPro/UFS Control Interface (Control Plane):
> >
> > "NOTE After exit from Hibernate all UniPro Transport Layer attributes
> > (including
> > L4 T_PeerDeviceID,
> >
> > L4 T_PeerCPortID, L4 T_ConnectionState, etc.) will be reset to their reset
> values.
> > All required attributes
> >
> > must be restored properly on both ends before communication can resume."
> >
> > But its not clear whether SW needs to restore these attributes or
> > hardware
> >
> Thanks Vignesh for pointing out the spec section, yes it is not clear, one way to
> confirm this is just by read L4 attributes before And after hinern8 entry/exit.
> (at least in the current platform it is not being done) AFA this patch is concerns,
> this looks ok to me.
> @ Avri , any thought on this?
Yes, it looks fine.

Thanks,
Avri



^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit in Cadence UFS.
  2019-11-19  7:04 ` [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit " sheebab
  2019-11-20 16:20   ` Alim Akhtar
@ 2019-11-28 13:59   ` Alim Akhtar
  1 sibling, 0 replies; 10+ messages in thread
From: Alim Akhtar @ 2019-11-28 13:59 UTC (permalink / raw)
  To: 'sheebab',
	avri.altman, pedrom.sousa, jejb, martin.petersen, stanley.chu,
	beanhuo, yuehaibing, linux-scsi, linux-kernel, vigneshr,
	linux-block
  Cc: rafalc, mparab



> -----Original Message-----
> From: sheebab <sheebab@cadence.com>
> Sent: 19 November 2019 12:35
> To: alim.akhtar@samsung.com; avri.altman@wdc.com;
> pedrom.sousa@synopsys.com; jejb@linux.ibm.com;
> martin.petersen@oracle.com; stanley.chu@mediatek.com;
> beanhuo@micron.com; yuehaibing@huawei.com; linux-scsi@vger.kernel.org;
> linux-kernel@vger.kernel.org; vigneshr@ti.com; linux-block@vger.kernel.org
> Cc: rafalc@cadence.com; mparab@cadence.com; sheebab
> <sheebab@cadence.com>
> Subject: [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual
hibern8
> exit in Cadence UFS.
> 
> Backup L4 attributes duirng manual hibern8 entry and restore the L4
attributes
> on manual hibern8 exit as per JESD220C.
> 
> Signed-off-by: sheebab <sheebab@cadence.com>
> ---
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>

>  drivers/scsi/ufs/cdns-pltfrm.c | 97
> +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 95 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/ufs/cdns-pltfrm.c
b/drivers/scsi/ufs/cdns-pltfrm.c index
> adbbd60..5510567 100644
> --- a/drivers/scsi/ufs/cdns-pltfrm.c
> +++ b/drivers/scsi/ufs/cdns-pltfrm.c
> @@ -19,6 +19,14 @@
> 
>  #define CDNS_UFS_REG_HCLKDIV	0xFC
>  #define CDNS_UFS_REG_PHY_XCFGD1	0x113C
> +#define CDNS_UFS_MAX 12
> +
> +struct cdns_ufs_host {
> +	/**
> +	 * cdns_ufs_dme_attr_val - for storing L4 attributes
> +	 */
> +	u32 cdns_ufs_dme_attr_val[CDNS_UFS_MAX];
> +};
> 
>  /**
>   * cdns_ufs_enable_intr - enable interrupts @@ -47,6 +55,77 @@ static
void
> cdns_ufs_disable_intr(struct ufs_hba *hba, u32 intrs)  }
> 
>  /**
> + * cdns_ufs_get_l4_attr - get L4 attributes on local side
> + * @hba: per adapter instance
> + *
> + */
> +static void cdns_ufs_get_l4_attr(struct ufs_hba *hba) {
> +	struct cdns_ufs_host *host = ufshcd_get_variant(hba);
> +
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERDEVICEID),
> +		       &host->cdns_ufs_dme_attr_val[0]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERCPORTID),
> +		       &host->cdns_ufs_dme_attr_val[1]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
> +		       &host->cdns_ufs_dme_attr_val[2]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_PROTOCOLID),
> +		       &host->cdns_ufs_dme_attr_val[3]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTFLAGS),
> +		       &host->cdns_ufs_dme_attr_val[4]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
> +		       &host->cdns_ufs_dme_attr_val[5]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
> +		       &host->cdns_ufs_dme_attr_val[6]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
> +		       &host->cdns_ufs_dme_attr_val[7]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
> +		       &host->cdns_ufs_dme_attr_val[8]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
> +		       &host->cdns_ufs_dme_attr_val[9]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_CPORTMODE),
> +		       &host->cdns_ufs_dme_attr_val[10]);
> +	ufshcd_dme_get(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
> +		       &host->cdns_ufs_dme_attr_val[11]);
> +}
> +
> +/**
> + * cdns_ufs_set_l4_attr - set L4 attributes on local side
> + * @hba: per adapter instance
> + *
> + */
> +static void cdns_ufs_set_l4_attr(struct ufs_hba *hba) {
> +	struct cdns_ufs_host *host = ufshcd_get_variant(hba);
> +
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 0);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID),
> +		       host->cdns_ufs_dme_attr_val[0]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID),
> +		       host->cdns_ufs_dme_attr_val[1]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS),
> +		       host->cdns_ufs_dme_attr_val[2]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PROTOCOLID),
> +		       host->cdns_ufs_dme_attr_val[3]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS),
> +		       host->cdns_ufs_dme_attr_val[4]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_TXTOKENVALUE),
> +		       host->cdns_ufs_dme_attr_val[5]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_RXTOKENVALUE),
> +		       host->cdns_ufs_dme_attr_val[6]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_LOCALBUFFERSPACE),
> +		       host->cdns_ufs_dme_attr_val[7]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERBUFFERSPACE),
> +		       host->cdns_ufs_dme_attr_val[8]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CREDITSTOSEND),
> +		       host->cdns_ufs_dme_attr_val[9]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTMODE),
> +		       host->cdns_ufs_dme_attr_val[10]);
> +	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE),
> +		       host->cdns_ufs_dme_attr_val[11]); }
> +
> +/**
>   * Sets HCLKDIV register value based on the core_clk
>   * @hba: host controller instance
>   *
> @@ -134,6 +213,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba
> *hba, enum uic_cmd_dme cmd,
>  		 * before manual hibernate entry.
>  		 */
>  		cdns_ufs_enable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
> +		cdns_ufs_get_l4_attr(hba);
>  	}
>  	if (status == POST_CHANGE && cmd == UIC_CMD_DME_HIBER_EXIT) {
>  		/**
> @@ -141,6 +221,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba
> *hba, enum uic_cmd_dme cmd,
>  		 * after manual hibern8 exit.
>  		 */
>  		cdns_ufs_disable_intr(hba, UFSHCD_UIC_HIBERN8_MASK);
> +		cdns_ufs_set_l4_attr(hba);
>  	}
>  }
> 
> @@ -245,15 +326,27 @@ static int cdns_ufs_pltfrm_probe(struct
> platform_device *pdev)
>  	const struct of_device_id *of_id;
>  	struct ufs_hba_variant_ops *vops;
>  	struct device *dev = &pdev->dev;
> +	struct cdns_ufs_host *host;
> +	struct ufs_hba *hba;
> 
>  	of_id = of_match_node(cdns_ufs_of_match, dev->of_node);
>  	vops = (struct ufs_hba_variant_ops *)of_id->data;
> 
>  	/* Perform generic probe */
>  	err = ufshcd_pltfrm_init(pdev, vops);
> -	if (err)
> +	if (err) {
>  		dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
> -
> +		goto out;
> +	}
> +	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
> +	if (!host) {
> +		err = -ENOMEM;
> +		dev_err(dev, "%s: no memory for cdns host\n", __func__);
> +		goto out;
> +	}
> +	hba =  platform_get_drvdata(pdev);
> +	ufshcd_set_variant(hba, host);
> +out:
>  	return err;
>  }
> 
> --
> 2.7.4



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-11-28 13:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-19  7:04 [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes sheebab
2019-11-19  7:04 ` [PATCH RESEND 1/2] scsi: ufs: Enable hibern8 interrupt only during manual hibern8 in Cadence UFS sheebab
2019-11-19  7:04 ` [PATCH RESEND 2/2] scsi: ufs: Update L4 attributes on manual hibern8 exit " sheebab
2019-11-20 16:20   ` Alim Akhtar
2019-11-21 10:56     ` Vignesh Raghavendra
2019-11-27  3:42       ` Alim Akhtar
2019-11-27  4:15         ` Vignesh Raghavendra
2019-11-27 15:18         ` Avri Altman
2019-11-28 13:59   ` Alim Akhtar
2019-11-22 11:44 ` [PATCH RESEND 0/2] scsi: ufs: hibern8 fixes Vignesh Raghavendra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).