linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] ahci_xgene: Fix the xgene_ahci_restart_engine function to support Port Multiplier for APM X-Gene SoC AHCI SATA host controller driver.
       [not found] <1420453305-15986-1-git-send-email-stripathi@apm.com>
@ 2015-01-05 10:21 ` Suman Tripathi
  2015-01-05 14:50   ` Sergei Shtylyov
  2015-01-05 10:21 ` [PATCH 2/2] ahci_xgene: Implement the workaround to support PMP enumeration and discovery for APM X-Gene SoC AHCI SATA Host Controller driver Suman Tripathi
  1 sibling, 1 reply; 7+ messages in thread
From: Suman Tripathi @ 2015-01-05 10:21 UTC (permalink / raw)
  To: olof, tj, arnd
  Cc: linux-scsi, linux-ide, devicetree, linux-arm-kernel, mlangsdo,
	jcm, patches, Suman Tripathi

This patch implements the function xgene_ahci_poll_reg_val to poll
PxCI for multiple IDENTIFY DEVICE commands to finish before
restarting the DMA engine in case of Port Multiplier.

Signed-off-by: Suman Tripathi <stripathi@apm.com>
---
 drivers/ata/ahci_xgene.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index 0f8538f..2180223 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -105,17 +105,69 @@ static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx)
 }

 /**
+ * xgene_ahci_poll_reg_val- Poll a register on a specific value.
+ * @ap : ATA port of interest.
+ * @reg : Register of interest.
+ * @val : Value to be attained.
+ * @interval : waiting interval for polling.
+ * @timeout : timeout for achieving the value.
+ */
+static int xgene_ahci_poll_reg_val(struct ata_port *ap,
+				   void __iomem *reg, unsigned
+				   int val, unsigned long interval,
+				   unsigned long timeout)
+{
+	unsigned long deadline;
+	unsigned int tmp;
+
+	tmp = ioread32(reg);
+	deadline = ata_deadline(jiffies, timeout);
+
+	while ((tmp != val) && (time_before(jiffies, deadline))) {
+		ata_msleep(ap, interval);
+		tmp = ioread32(reg);
+	}
+
+	return tmp;
+}
+
+/**
  * xgene_ahci_restart_engine - Restart the dma engine.
  * @ap : ATA port of interest
  *
- * Restarts the dma engine inside the controller.
+ * Waits for completion of multiple commands and restarts
+ * the DMA engine inside the controller.
  */
 static int xgene_ahci_restart_engine(struct ata_port *ap)
 {
 	struct ahci_host_priv *hpriv = ap->host->private_data;
+	struct ahci_port_priv *pp = ap->private_data;
+	void __iomem *port_mmio = ahci_port_base(ap);
+	u32 fbs;
+
+	/*
+	 * In case of PMP multiple IDENTIFY DEVICE commands can be
+	 * issued inside PxCI. So need to poll PxCI for the
+	 * completion of outstanding IDENTIFY DEVICE commands before
+	 * we restart the DMA engine.
+	 */
+	if (xgene_ahci_poll_reg_val(ap, port_mmio +
+				    PORT_CMD_ISSUE, 0x0, 1, 100))
+		  return -EBUSY;

 	ahci_stop_engine(ap);
 	ahci_start_fis_rx(ap);
+
+	/*
+	 * Enable the PxFBS.FBS_EN bit as it
+	 * gets cleared due to stop engine.
+	 */
+	if (pp->fbs_supported) {
+		fbs = readl(port_mmio + PORT_FBS);
+		writel(fbs | PORT_FBS_EN, port_mmio + PORT_FBS);
+		fbs = readl(port_mmio + PORT_FBS);
+	}
+
 	hpriv->start_engine(ap);

 	return 0;
@@ -372,7 +424,7 @@ static struct ata_port_operations xgene_ahci_ops = {
 };

 static const struct ata_port_info xgene_ahci_port_info = {
-	.flags = AHCI_FLAG_COMMON,
+	.flags = AHCI_FLAG_COMMON | ATA_FLAG_PMP,
 	.pio_mask = ATA_PIO4,
 	.udma_mask = ATA_UDMA6,
 	.port_ops = &xgene_ahci_ops,
--
1.8.2.1


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

* [PATCH 2/2] ahci_xgene: Implement the workaround to support PMP enumeration and discovery for APM X-Gene SoC AHCI SATA Host Controller driver.
       [not found] <1420453305-15986-1-git-send-email-stripathi@apm.com>
  2015-01-05 10:21 ` [PATCH 1/2] ahci_xgene: Fix the xgene_ahci_restart_engine function to support Port Multiplier for APM X-Gene SoC AHCI SATA host controller driver Suman Tripathi
@ 2015-01-05 10:21 ` Suman Tripathi
  2015-01-05 13:30   ` Tejun Heo
  1 sibling, 1 reply; 7+ messages in thread
From: Suman Tripathi @ 2015-01-05 10:21 UTC (permalink / raw)
  To: olof, tj, arnd
  Cc: linux-scsi, linux-ide, devicetree, linux-arm-kernel, mlangsdo,
	jcm, patches, Suman Tripathi

Due to H/W errata, the controller is unable to save the PMP
field fetched from command header before sending the H2D FIS.
When the device returns the PMP port field in the D2H FIS, there is
a mismatch and results in command completion failure. The workaround
is to write the pmp value to PxFBS.DEV field before issuing any command
to PMP.

Signed-off-by: Suman Tripathi <stripathi@apm.com>
---
 drivers/ata/ahci_xgene.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index 2180223..a194ddd 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -85,6 +85,7 @@ struct xgene_ahci_context {
 	struct ahci_host_priv *hpriv;
 	struct device *dev;
 	u8 last_cmd[MAX_AHCI_CHN_PERCTR]; /* tracking the last command issued*/
+	u32 class[MAX_AHCI_CHN_PERCTR]; /* tracking the class of device */
 	void __iomem *csr_core;		/* Core CSR address of IP */
 	void __iomem *csr_diag;		/* Diag CSR address of IP */
 	void __iomem *csr_axi;		/* AXI CSR address of IP */
@@ -181,6 +182,13 @@ static int xgene_ahci_restart_engine(struct ata_port *ap)
  * clear the BSY bit after receiving the PIO setup FIS. This results in the dma
  * state machine goes into the CMFatalErrorUpdate state and locks up. By
  * restarting the dma engine, it removes the controller out of lock up state.
+ *
+ * Due to H/W errata, the controller is unable to save the PMP
+ * field fetched from command header before sending the H2D FIS.
+ * When the device returns the PMP port field in the D2H FIS, there is
+ * a mismatch and results in command completion failure. The
+ * workaround is to write the pmp value to PxFBS.DEV field before issuing
+ * any command to PMP.
  */
 static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
 {
@@ -188,6 +196,19 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
 	struct ahci_host_priv *hpriv = ap->host->private_data;
 	struct xgene_ahci_context *ctx = hpriv->plat_data;
 	int rc = 0;
+	u32 port_fbs;
+	void *port_mmio = ahci_port_base(ap);
+
+	/*
+	 * Write the pmp value to PxFBS.DEV
+	 * for case of Port Mulitplier.
+	 */
+	if (ctx->class[ap->port_no] == ATA_DEV_PMP) {
+		port_fbs = readl(port_mmio + PORT_FBS);
+		port_fbs &= ~PORT_FBS_DEV_MASK;
+		port_fbs |= qc->dev->link->pmp << PORT_FBS_DEV_OFFSET;
+		writel(port_fbs, port_mmio + PORT_FBS);
+	}

 	if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA))
 		xgene_ahci_restart_engine(ap);
@@ -415,12 +436,115 @@ static void xgene_ahci_host_stop(struct ata_host *host)
 	ahci_platform_disable_resources(hpriv);
 }

+/**
+ * xgene_ahci_pmp_softreset - Issue the softreset to the drives connected
+ *                            to Port Multiplier.
+ * @link: link to reset
+ * @class: Return value to indicate class of device
+ * @deadline: deadline jiffies for the operation
+ *
+ * Due to H/W errata, the controller is unable to save the PMP
+ * field fetched from command header before sending the H2D FIS.
+ * When the device returns the PMP port field in the D2H FIS, there is
+ * a mismatch and results in command completion failure. The workaround
+ * is to write the pmp value to PxFBS.DEV field before issuing any command
+ * to PMP.
+ */
+static int xgene_ahci_pmp_softreset(struct ata_link *link, unsigned int *class,
+			  unsigned long deadline)
+{
+	int pmp = sata_srst_pmp(link);
+	struct ata_port *ap = link->ap;
+	u32 rc;
+	void *port_mmio = ahci_port_base(ap);
+	u32 port_fbs;
+
+	/*
+	 * Set PxFBS.DEV field with pmp
+	 * value.
+	 */
+	port_fbs = readl(port_mmio + PORT_FBS);
+	port_fbs &= ~PORT_FBS_DEV_MASK;
+	port_fbs |= pmp << PORT_FBS_DEV_OFFSET;
+	writel(port_fbs, port_mmio + PORT_FBS);
+
+	rc = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
+
+	return rc;
+}
+
+/**
+ * xgene_ahci_softreset - Issue the softreset to the drive.
+ * @link: link to reset
+ * @class: Return value to indicate class of device
+ * @deadline: deadline jiffies for the operation
+ *
+ * Due to H/W errata, the controller is unable to save the PMP
+ * field fetched from command header before sending the H2D FIS.
+ * When the device returns the PMP port field in the D2H FIS, there is
+ * a mismatch and results in command completion failure. The workaround
+ * is to write the pmp value to PxFBS.DEV field before issuing any command
+ * to PMP. Here is the algorithm to detect PMP :
+ *
+ * 1. Save the PxFBS value
+ * 2. Program PxFBS.DEV with pmp value send by framework. Framework sends
+ *    0xF for both PMP/NON-PMP initially
+ * 3. Issue softreset
+ * 4. If signature class is PMP goto 6
+ * 5. restore the original PxFBS and goto 3
+ * 6. return
+ */
+static int xgene_ahci_softreset(struct ata_link *link, unsigned int *class,
+			  unsigned long deadline)
+{
+	int pmp = sata_srst_pmp(link);
+	struct ata_port *ap = link->ap;
+	struct ahci_host_priv *hpriv = ap->host->private_data;
+	struct xgene_ahci_context *ctx = hpriv->plat_data;
+	void *port_mmio = ahci_port_base(ap);
+	u32 port_fbs;
+	u32 port_fbs_save;
+	u32 retry = 1;
+	u32 rc;
+
+	port_fbs_save = readl(port_mmio + PORT_FBS);
+
+	/*
+	 * Set PxFBS.DEV field with pmp
+	 * value.
+	 */
+	port_fbs = readl(port_mmio + PORT_FBS);
+	port_fbs &= ~PORT_FBS_DEV_MASK;
+	port_fbs |= pmp << PORT_FBS_DEV_OFFSET;
+	writel(port_fbs, port_mmio + PORT_FBS);
+
+softreset_retry:
+	rc = ahci_do_softreset(link, class, pmp,
+			       deadline, ahci_check_ready);
+
+	ctx->class[ap->port_no] = *class;
+	if (*class != ATA_DEV_PMP) {
+		/*
+		 * Retry for normal drives without
+		 * setting PxFBS.DEV field with pmp value.
+		 */
+		if (retry--) {
+			writel(port_fbs_save, port_mmio + PORT_FBS);
+			goto softreset_retry;
+		}
+	}
+
+	return rc;
+}
+
 static struct ata_port_operations xgene_ahci_ops = {
 	.inherits = &ahci_ops,
 	.host_stop = xgene_ahci_host_stop,
 	.hardreset = xgene_ahci_hardreset,
 	.read_id = xgene_ahci_read_id,
 	.qc_issue = xgene_ahci_qc_issue,
+	.softreset = xgene_ahci_softreset,
+	.pmp_softreset = xgene_ahci_pmp_softreset
 };

 static const struct ata_port_info xgene_ahci_port_info = {
--
1.8.2.1


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

* Re: [PATCH 2/2] ahci_xgene: Implement the workaround to support PMP enumeration and discovery for APM X-Gene SoC AHCI SATA Host Controller driver.
  2015-01-05 10:21 ` [PATCH 2/2] ahci_xgene: Implement the workaround to support PMP enumeration and discovery for APM X-Gene SoC AHCI SATA Host Controller driver Suman Tripathi
@ 2015-01-05 13:30   ` Tejun Heo
  2015-01-05 13:59     ` Tejun Heo
  0 siblings, 1 reply; 7+ messages in thread
From: Tejun Heo @ 2015-01-05 13:30 UTC (permalink / raw)
  To: Suman Tripathi
  Cc: olof, arnd, linux-scsi, linux-ide, devicetree, linux-arm-kernel,
	mlangsdo, jcm, patches

On Mon, Jan 05, 2015 at 03:51:45PM +0530, Suman Tripathi wrote:
> Due to H/W errata, the controller is unable to save the PMP
> field fetched from command header before sending the H2D FIS.
> When the device returns the PMP port field in the D2H FIS, there is
> a mismatch and results in command completion failure. The workaround
> is to write the pmp value to PxFBS.DEV field before issuing any command
> to PMP.
> 
> Signed-off-by: Suman Tripathi <stripathi@apm.com>

Applied 1-2 to libata/for-3.20.

Thanks.

-- 
tejun

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

* Re: [PATCH 2/2] ahci_xgene: Implement the workaround to support PMP enumeration and discovery for APM X-Gene SoC AHCI SATA Host Controller driver.
  2015-01-05 13:30   ` Tejun Heo
@ 2015-01-05 13:59     ` Tejun Heo
  2015-01-05 14:03       ` Suman Tripathi
  0 siblings, 1 reply; 7+ messages in thread
From: Tejun Heo @ 2015-01-05 13:59 UTC (permalink / raw)
  To: Suman Tripathi
  Cc: olof, arnd, linux-scsi, linux-ide, devicetree, linux-arm-kernel,
	mlangsdo, jcm, patches

On Mon, Jan 05, 2015 at 08:30:05AM -0500, Tejun Heo wrote:
> On Mon, Jan 05, 2015 at 03:51:45PM +0530, Suman Tripathi wrote:
> > Due to H/W errata, the controller is unable to save the PMP
> > field fetched from command header before sending the H2D FIS.
> > When the device returns the PMP port field in the D2H FIS, there is
> > a mismatch and results in command completion failure. The workaround
> > is to write the pmp value to PxFBS.DEV field before issuing any command
> > to PMP.
> > 
> > Signed-off-by: Suman Tripathi <stripathi@apm.com>
> 
> Applied 1-2 to libata/for-3.20.

Reverted due to conflicts with the endian fix patches.  Please rebase
these two on top of them.

Thanks.

-- 
tejun

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

* Re: [PATCH 2/2] ahci_xgene: Implement the workaround to support PMP enumeration and discovery for APM X-Gene SoC AHCI SATA Host Controller driver.
  2015-01-05 13:59     ` Tejun Heo
@ 2015-01-05 14:03       ` Suman Tripathi
  2015-01-05 14:05         ` Tejun Heo
  0 siblings, 1 reply; 7+ messages in thread
From: Suman Tripathi @ 2015-01-05 14:03 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Olof Johansson, Arnd Bergmann, Linux SCSI List,
	linux-ide@vger.kernel.org, devicetree@vger.kernel.org,
	linux-arm-kernel, Mark Langsdorf, Jon Masters, patches

Reverted due to conflicts with the endian fix patches.  Please rebase
these two on top of them.

Will do that .. I should have wait for the endian patch getting
accepted. Sorry for that.

On Mon, Jan 5, 2015 at 7:29 PM, Tejun Heo <tj@kernel.org> wrote:
> On Mon, Jan 05, 2015 at 08:30:05AM -0500, Tejun Heo wrote:
>> On Mon, Jan 05, 2015 at 03:51:45PM +0530, Suman Tripathi wrote:
>> > Due to H/W errata, the controller is unable to save the PMP
>> > field fetched from command header before sending the H2D FIS.
>> > When the device returns the PMP port field in the D2H FIS, there is
>> > a mismatch and results in command completion failure. The workaround
>> > is to write the pmp value to PxFBS.DEV field before issuing any command
>> > to PMP.
>> >
>> > Signed-off-by: Suman Tripathi <stripathi@apm.com>
>>
>> Applied 1-2 to libata/for-3.20.
>
> Reverted due to conflicts with the endian fix patches.  Please rebase
> these two on top of them.
>
> Thanks.
>
> --
> tejun



-- 
Thanks,
with regards,
Suman Tripathi
CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, 
is for the sole use of the intended recipient(s) and contains information
that is confidential and proprietary to Applied Micro Circuits Corporation or its subsidiaries. 
It is to be used solely for the purpose of furthering the parties' business relationship. 
All unauthorized review, use, disclosure or distribution is prohibited. 
If you are not the intended recipient, please contact the sender by reply e-mail 
and destroy all copies of the original message.


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

* Re: [PATCH 2/2] ahci_xgene: Implement the workaround to support PMP enumeration and discovery for APM X-Gene SoC AHCI SATA Host Controller driver.
  2015-01-05 14:03       ` Suman Tripathi
@ 2015-01-05 14:05         ` Tejun Heo
  0 siblings, 0 replies; 7+ messages in thread
From: Tejun Heo @ 2015-01-05 14:05 UTC (permalink / raw)
  To: Suman Tripathi
  Cc: Olof Johansson, Arnd Bergmann, Linux SCSI List,
	linux-ide@vger.kernel.org, devicetree@vger.kernel.org,
	linux-arm-kernel, Mark Langsdorf, Jon Masters, patches

On Mon, Jan 05, 2015 at 07:33:06PM +0530, Suman Tripathi wrote:
> Reverted due to conflicts with the endian fix patches.  Please rebase
> these two on top of them.
> 
> Will do that .. I should have wait for the endian patch getting
> accepted. Sorry for that.

Ooh, please don't be sorry.  It's completely fine.  These things
happen.

Thanks.

-- 
tejun

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

* Re: [PATCH 1/2] ahci_xgene: Fix the xgene_ahci_restart_engine function to support Port Multiplier for APM X-Gene SoC AHCI SATA host controller driver.
  2015-01-05 10:21 ` [PATCH 1/2] ahci_xgene: Fix the xgene_ahci_restart_engine function to support Port Multiplier for APM X-Gene SoC AHCI SATA host controller driver Suman Tripathi
@ 2015-01-05 14:50   ` Sergei Shtylyov
  0 siblings, 0 replies; 7+ messages in thread
From: Sergei Shtylyov @ 2015-01-05 14:50 UTC (permalink / raw)
  To: Suman Tripathi, olof, tj, arnd
  Cc: linux-scsi, linux-ide, devicetree, linux-arm-kernel, mlangsdo,
	jcm, patches

Hello.

On 1/5/2015 1:21 PM, Suman Tripathi wrote:

    Your patch summary seems too long.

> This patch implements the function xgene_ahci_poll_reg_val to poll
> PxCI for multiple IDENTIFY DEVICE commands to finish before
> restarting the DMA engine in case of Port Multiplier.

> Signed-off-by: Suman Tripathi <stripathi@apm.com>
> ---
>   drivers/ata/ahci_xgene.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 54 insertions(+), 2 deletions(-)

> diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
> index 0f8538f..2180223 100644
> --- a/drivers/ata/ahci_xgene.c
> +++ b/drivers/ata/ahci_xgene.c
> @@ -105,17 +105,69 @@ static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx)
>   }
>
>   /**
> + * xgene_ahci_poll_reg_val- Poll a register on a specific value.
> + * @ap : ATA port of interest.
> + * @reg : Register of interest.
> + * @val : Value to be attained.
> + * @interval : waiting interval for polling.
> + * @timeout : timeout for achieving the value.
> + */
> +static int xgene_ahci_poll_reg_val(struct ata_port *ap,
> +				   void __iomem *reg, unsigned
> +				   int val, unsigned long interval,
> +				   unsigned long timeout)
> +{
> +	unsigned long deadline;
> +	unsigned int tmp;
> +
> +	tmp = ioread32(reg);
> +	deadline = ata_deadline(jiffies, timeout);
> +
> +	while ((tmp != val) && (time_before(jiffies, deadline))) {

    Parens around the operands of && are not needed, especially around the 
right one.

> +		ata_msleep(ap, interval);
> +		tmp = ioread32(reg);
> +	}
> +
> +	return tmp;
> +}
> +
> +/**
>    * xgene_ahci_restart_engine - Restart the dma engine.
>    * @ap : ATA port of interest
>    *
> - * Restarts the dma engine inside the controller.
> + * Waits for completion of multiple commands and restarts
> + * the DMA engine inside the controller.
>    */
>   static int xgene_ahci_restart_engine(struct ata_port *ap)
>   {
>   	struct ahci_host_priv *hpriv = ap->host->private_data;
> +	struct ahci_port_priv *pp = ap->private_data;
> +	void __iomem *port_mmio = ahci_port_base(ap);
> +	u32 fbs;
> +
> +	/*
> +	 * In case of PMP multiple IDENTIFY DEVICE commands can be
> +	 * issued inside PxCI. So need to poll PxCI for the
> +	 * completion of outstanding IDENTIFY DEVICE commands before
> +	 * we restart the DMA engine.
> +	 */
> +	if (xgene_ahci_poll_reg_val(ap, port_mmio +
> +				    PORT_CMD_ISSUE, 0x0, 1, 100))
> +		  return -EBUSY;
>
>   	ahci_stop_engine(ap);
>   	ahci_start_fis_rx(ap);
> +
> +	/*
> +	 * Enable the PxFBS.FBS_EN bit as it
> +	 * gets cleared due to stop engine.

    s/stop/stopping the/.

[...]

MBR, Sergei


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

end of thread, other threads:[~2015-01-05 14:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1420453305-15986-1-git-send-email-stripathi@apm.com>
2015-01-05 10:21 ` [PATCH 1/2] ahci_xgene: Fix the xgene_ahci_restart_engine function to support Port Multiplier for APM X-Gene SoC AHCI SATA host controller driver Suman Tripathi
2015-01-05 14:50   ` Sergei Shtylyov
2015-01-05 10:21 ` [PATCH 2/2] ahci_xgene: Implement the workaround to support PMP enumeration and discovery for APM X-Gene SoC AHCI SATA Host Controller driver Suman Tripathi
2015-01-05 13:30   ` Tejun Heo
2015-01-05 13:59     ` Tejun Heo
2015-01-05 14:03       ` Suman Tripathi
2015-01-05 14:05         ` Tejun Heo

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).