linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] ata: ahci_brcm: Recover from failures to identify devices
@ 2018-01-12  1:31 Florian Fainelli
  2018-01-12  1:31 ` [PATCH v2 1/2] phy: brcm-sata: Implement calibrate callback Florian Fainelli
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Florian Fainelli @ 2018-01-12  1:31 UTC (permalink / raw)
  To: bcm-kernel-feedback-list
  Cc: Florian Fainelli, Tejun Heo, Kishon Vijay Abraham I,
	Heiko Stuebner, Srinath Mannam, Krzysztof Kozlowski, Vivek Gautam,
	Dan Carpenter,
	open list:LIBATA SUBSYSTEM Serial and Parallel ATA drivers,
	open list

Hi Tejun, Kishon,

This patch series implement a recovery mechanism to work around a HW bug
on Broadcom AHCI SATA controller subject to noise triggering a failure to
identify hard drives.

I would like to make this this is okay with you as an approach on how to solve
this.

This should likely go through Tejun's tree to make sure the SATA controller
and PHY changes are bundled together.

Thanks!

Changes in v2:

- avoid introducing an unnecessary port_recovery callback and instead
  override read_id directly

Florian Fainelli (2):
  phy: brcm-sata: Implement calibrate callback
  ata: ahci_brcm: Recover from failures to identify devices

 drivers/ata/ahci_brcm.c              | 95 +++++++++++++++++++++++++++++++++---
 drivers/phy/broadcom/phy-brcm-sata.c | 32 ++++++++++++
 2 files changed, 119 insertions(+), 8 deletions(-)

-- 
2.7.4


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

* [PATCH v2 1/2] phy: brcm-sata: Implement calibrate callback
  2018-01-12  1:31 [PATCH v2 0/2] ata: ahci_brcm: Recover from failures to identify devices Florian Fainelli
@ 2018-01-12  1:31 ` Florian Fainelli
  2018-01-17  5:19   ` Kishon Vijay Abraham I
  2018-01-12  1:31 ` [PATCH v2 2/2] ata: ahci_brcm: Recover from failures to identify devices Florian Fainelli
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Florian Fainelli @ 2018-01-12  1:31 UTC (permalink / raw)
  To: bcm-kernel-feedback-list
  Cc: Florian Fainelli, Tejun Heo, Kishon Vijay Abraham I,
	Heiko Stuebner, Srinath Mannam, Krzysztof Kozlowski, Vivek Gautam,
	Dan Carpenter,
	open list:LIBATA SUBSYSTEM Serial and Parallel ATA drivers,
	open list

Implement the calibration callback to allow turning on the Clock-Data
Recovery module clamping when necessary, e.g: during failure to identify
a SATA hard drive from ahci_brcm.c::brcm_ahci_read_id.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/phy/broadcom/phy-brcm-sata.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c
index 3f953db70288..8000ce312d95 100644
--- a/drivers/phy/broadcom/phy-brcm-sata.c
+++ b/drivers/phy/broadcom/phy-brcm-sata.c
@@ -150,6 +150,9 @@ enum sata_phy_regs {
 	TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK	= 0x3ff,
 	TXPMD_TX_FREQ_CTRL_CONTROL3		= 0x84,
 	TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK	= 0x3ff,
+
+	RXPMD_REG_BANK				= 0x1c0,
+	RXPMD_RX_FREQ_MON_CONTROL1		= 0x87,
 };
 
 enum sata_phy_ctrl_regs {
@@ -505,8 +508,37 @@ static int brcm_sata_phy_init(struct phy *phy)
 	return rc;
 }
 
+static void brcm_stb_sata_calibrate(struct brcm_sata_port *port)
+{
+	void __iomem *base = brcm_sata_pcb_base(port);
+	struct brcm_sata_phy *priv = port->phy_priv;
+	u32 tmp = BIT(8);
+
+	brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
+			 ~tmp, tmp);
+}
+
+static int brcm_sata_phy_calibrate(struct phy *phy)
+{
+	struct brcm_sata_port *port = phy_get_drvdata(phy);
+	int rc = -EOPNOTSUPP;
+
+	switch (port->phy_priv->version) {
+	case BRCM_SATA_PHY_STB_28NM:
+	case BRCM_SATA_PHY_STB_40NM:
+		brcm_stb_sata_calibrate(port);
+		rc = 0;
+		break;
+	default:
+		break;
+	};
+
+	return rc;
+}
+
 static const struct phy_ops phy_ops = {
 	.init		= brcm_sata_phy_init,
+	.calibrate	= brcm_sata_phy_calibrate,
 	.owner		= THIS_MODULE,
 };
 
-- 
2.7.4

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

* [PATCH v2 2/2] ata: ahci_brcm: Recover from failures to identify devices
  2018-01-12  1:31 [PATCH v2 0/2] ata: ahci_brcm: Recover from failures to identify devices Florian Fainelli
  2018-01-12  1:31 ` [PATCH v2 1/2] phy: brcm-sata: Implement calibrate callback Florian Fainelli
@ 2018-01-12  1:31 ` Florian Fainelli
  2018-01-16 16:09 ` [PATCH v2 0/2] " Tejun Heo
  2018-01-17 15:53 ` Tejun Heo
  3 siblings, 0 replies; 6+ messages in thread
From: Florian Fainelli @ 2018-01-12  1:31 UTC (permalink / raw)
  To: bcm-kernel-feedback-list
  Cc: Florian Fainelli, Tejun Heo, Kishon Vijay Abraham I,
	Heiko Stuebner, Srinath Mannam, Krzysztof Kozlowski, Vivek Gautam,
	Dan Carpenter,
	open list:LIBATA SUBSYSTEM Serial and Parallel ATA drivers,
	open list

When powering up, the SATA controller may fail to mount the HDD. The SATA
controller will lock up, preventing it from negotiating to a lower speed or
transmitting data. Root cause is power supply noise creating resonance at 6 Ghz
and 3 GHz frequencies, which causes instability in the Clock-Data Recovery
(CDR) frontend module, resulting in false acquisition of the clock at SATA
6G/3G speeds.

The SATA controller may fail to mount the HDD and lock up, requiring a power
cycle. Broadcom chips suspected of being susceptible to this issue include
BCM7445, BCM7439, and BCM7366.

The Kernel implements an error recovery mechanism that resets the SATA PHY and
digital controller when the controller locks up. During this error recovery
process, typically there is less activity on the board and Broadcom STB chip,
so that the power supply is less noisy, thus allowing the SATA controller to
lock correctly.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/ata/ahci_brcm.c | 95 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 87 insertions(+), 8 deletions(-)

diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c
index ad3b8826ec79..ea430819c80b 100644
--- a/drivers/ata/ahci_brcm.c
+++ b/drivers/ata/ahci_brcm.c
@@ -96,14 +96,6 @@ struct brcm_ahci_priv {
 	enum brcm_ahci_version version;
 };
 
-static const struct ata_port_info ahci_brcm_port_info = {
-	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
-	.link_flags	= ATA_LFLAG_NO_DB_DELAY,
-	.pio_mask	= ATA_PIO4,
-	.udma_mask	= ATA_UDMA6,
-	.port_ops	= &ahci_platform_ops,
-};
-
 static inline u32 brcm_sata_readreg(void __iomem *addr)
 {
 	/*
@@ -269,6 +261,93 @@ static void brcm_sata_init(struct brcm_ahci_priv *priv)
 	brcm_sata_writereg(data, ctrl);
 }
 
+static unsigned int brcm_ahci_read_id(struct ata_device *dev,
+				      struct ata_taskfile *tf, u16 *id)
+{
+	struct ata_port *ap = dev->link->ap;
+	struct ata_host *host = ap->host;
+	struct ahci_host_priv *hpriv = host->private_data;
+	struct brcm_ahci_priv *priv = hpriv->plat_data;
+	void __iomem *mmio = hpriv->mmio;
+	unsigned int err_mask;
+	unsigned long flags;
+	int i, rc;
+	u32 ctl;
+
+	/* Try to read the device ID and, if this fails, proceed with the
+	 * recovery sequence below
+	 */
+	err_mask = ata_do_dev_read_id(dev, tf, id);
+	if (likely(!err_mask))
+		return err_mask;
+
+	/* Disable host interrupts */
+	spin_lock_irqsave(&host->lock, flags);
+	ctl = readl(mmio + HOST_CTL);
+	ctl &= ~HOST_IRQ_EN;
+	writel(ctl, mmio + HOST_CTL);
+	readl(mmio + HOST_CTL); /* flush */
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	/* Perform the SATA PHY reset sequence */
+	brcm_sata_phy_disable(priv, ap->port_no);
+
+	/* Bring the PHY back on */
+	brcm_sata_phy_enable(priv, ap->port_no);
+
+	/* Re-initialize and calibrate the PHY */
+	for (i = 0; i < hpriv->nports; i++) {
+		rc = phy_init(hpriv->phys[i]);
+		if (rc)
+			goto disable_phys;
+
+		rc = phy_calibrate(hpriv->phys[i]);
+		if (rc) {
+			phy_exit(hpriv->phys[i]);
+			goto disable_phys;
+		}
+	}
+
+	/* Re-enable host interrupts */
+	spin_lock_irqsave(&host->lock, flags);
+	ctl = readl(mmio + HOST_CTL);
+	ctl |= HOST_IRQ_EN;
+	writel(ctl, mmio + HOST_CTL);
+	readl(mmio + HOST_CTL); /* flush */
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	return ata_do_dev_read_id(dev, tf, id);
+
+disable_phys:
+	while (--i >= 0) {
+		phy_power_off(hpriv->phys[i]);
+		phy_exit(hpriv->phys[i]);
+	}
+
+	return AC_ERR_OTHER;
+}
+
+static void brcm_ahci_host_stop(struct ata_host *host)
+{
+	struct ahci_host_priv *hpriv = host->private_data;
+
+	ahci_platform_disable_resources(hpriv);
+}
+
+static struct ata_port_operations ahci_brcm_platform_ops = {
+	.inherits	= &ahci_ops,
+	.host_stop	= brcm_ahci_host_stop,
+	.read_id	= brcm_ahci_read_id,
+};
+
+static const struct ata_port_info ahci_brcm_port_info = {
+	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
+	.link_flags	= ATA_LFLAG_NO_DB_DELAY,
+	.pio_mask	= ATA_PIO4,
+	.udma_mask	= ATA_UDMA6,
+	.port_ops	= &ahci_brcm_platform_ops,
+};
+
 #ifdef CONFIG_PM_SLEEP
 static int brcm_ahci_suspend(struct device *dev)
 {
-- 
2.7.4

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

* Re: [PATCH v2 0/2] ata: ahci_brcm: Recover from failures to identify devices
  2018-01-12  1:31 [PATCH v2 0/2] ata: ahci_brcm: Recover from failures to identify devices Florian Fainelli
  2018-01-12  1:31 ` [PATCH v2 1/2] phy: brcm-sata: Implement calibrate callback Florian Fainelli
  2018-01-12  1:31 ` [PATCH v2 2/2] ata: ahci_brcm: Recover from failures to identify devices Florian Fainelli
@ 2018-01-16 16:09 ` Tejun Heo
  2018-01-17 15:53 ` Tejun Heo
  3 siblings, 0 replies; 6+ messages in thread
From: Tejun Heo @ 2018-01-16 16:09 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: bcm-kernel-feedback-list, Kishon Vijay Abraham I, Heiko Stuebner,
	Srinath Mannam, Krzysztof Kozlowski, Vivek Gautam, Dan Carpenter,
	open list:LIBATA SUBSYSTEM (Serial and Parallel ATA drivers),
	open list

On Thu, Jan 11, 2018 at 05:31:06PM -0800, Florian Fainelli wrote:
> Hi Tejun, Kishon,
> 
> This patch series implement a recovery mechanism to work around a HW bug
> on Broadcom AHCI SATA controller subject to noise triggering a failure to
> identify hard drives.
> 
> I would like to make this this is okay with you as an approach on how to solve
> this.
> 
> This should likely go through Tejun's tree to make sure the SATA controller
> and PHY changes are bundled together.

libata part looks good to me.  Once phy side gets acked, I'll route
both through libata.

Thanks.

-- 
tejun

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

* Re: [PATCH v2 1/2] phy: brcm-sata: Implement calibrate callback
  2018-01-12  1:31 ` [PATCH v2 1/2] phy: brcm-sata: Implement calibrate callback Florian Fainelli
@ 2018-01-17  5:19   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 6+ messages in thread
From: Kishon Vijay Abraham I @ 2018-01-17  5:19 UTC (permalink / raw)
  To: Florian Fainelli, bcm-kernel-feedback-list
  Cc: Tejun Heo, Heiko Stuebner, Srinath Mannam, Krzysztof Kozlowski,
	Vivek Gautam, Dan Carpenter,
	open list:LIBATA SUBSYSTEM (Serial and Parallel ATA drivers),
	open list



On Friday 12 January 2018 07:01 AM, Florian Fainelli wrote:
> Implement the calibration callback to allow turning on the Clock-Data
> Recovery module clamping when necessary, e.g: during failure to identify
> a SATA hard drive from ahci_brcm.c::brcm_ahci_read_id.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  drivers/phy/broadcom/phy-brcm-sata.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c
> index 3f953db70288..8000ce312d95 100644
> --- a/drivers/phy/broadcom/phy-brcm-sata.c
> +++ b/drivers/phy/broadcom/phy-brcm-sata.c
> @@ -150,6 +150,9 @@ enum sata_phy_regs {
>  	TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK	= 0x3ff,
>  	TXPMD_TX_FREQ_CTRL_CONTROL3		= 0x84,
>  	TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK	= 0x3ff,
> +
> +	RXPMD_REG_BANK				= 0x1c0,
> +	RXPMD_RX_FREQ_MON_CONTROL1		= 0x87,
>  };
>  
>  enum sata_phy_ctrl_regs {
> @@ -505,8 +508,37 @@ static int brcm_sata_phy_init(struct phy *phy)
>  	return rc;
>  }
>  
> +static void brcm_stb_sata_calibrate(struct brcm_sata_port *port)
> +{
> +	void __iomem *base = brcm_sata_pcb_base(port);
> +	struct brcm_sata_phy *priv = port->phy_priv;
> +	u32 tmp = BIT(8);
> +
> +	brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
> +			 ~tmp, tmp);
> +}
> +
> +static int brcm_sata_phy_calibrate(struct phy *phy)
> +{
> +	struct brcm_sata_port *port = phy_get_drvdata(phy);
> +	int rc = -EOPNOTSUPP;
> +
> +	switch (port->phy_priv->version) {
> +	case BRCM_SATA_PHY_STB_28NM:
> +	case BRCM_SATA_PHY_STB_40NM:
> +		brcm_stb_sata_calibrate(port);
> +		rc = 0;
> +		break;
> +	default:
> +		break;
> +	};
> +
> +	return rc;
> +}
> +
>  static const struct phy_ops phy_ops = {
>  	.init		= brcm_sata_phy_init,
> +	.calibrate	= brcm_sata_phy_calibrate,
>  	.owner		= THIS_MODULE,
>  };
>  
> 

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

* Re: [PATCH v2 0/2] ata: ahci_brcm: Recover from failures to identify devices
  2018-01-12  1:31 [PATCH v2 0/2] ata: ahci_brcm: Recover from failures to identify devices Florian Fainelli
                   ` (2 preceding siblings ...)
  2018-01-16 16:09 ` [PATCH v2 0/2] " Tejun Heo
@ 2018-01-17 15:53 ` Tejun Heo
  3 siblings, 0 replies; 6+ messages in thread
From: Tejun Heo @ 2018-01-17 15:53 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: bcm-kernel-feedback-list, Kishon Vijay Abraham I, Heiko Stuebner,
	Srinath Mannam, Krzysztof Kozlowski, Vivek Gautam, Dan Carpenter,
	open list:LIBATA SUBSYSTEM (Serial and Parallel ATA drivers),
	open list

On Thu, Jan 11, 2018 at 05:31:06PM -0800, Florian Fainelli wrote:
> Hi Tejun, Kishon,
> 
> This patch series implement a recovery mechanism to work around a HW bug
> on Broadcom AHCI SATA controller subject to noise triggering a failure to
> identify hard drives.

Applied 1-2 to libata/for-4.16.

Thanks.

-- 
tejun

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

end of thread, other threads:[~2018-01-17 15:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-12  1:31 [PATCH v2 0/2] ata: ahci_brcm: Recover from failures to identify devices Florian Fainelli
2018-01-12  1:31 ` [PATCH v2 1/2] phy: brcm-sata: Implement calibrate callback Florian Fainelli
2018-01-17  5:19   ` Kishon Vijay Abraham I
2018-01-12  1:31 ` [PATCH v2 2/2] ata: ahci_brcm: Recover from failures to identify devices Florian Fainelli
2018-01-16 16:09 ` [PATCH v2 0/2] " Tejun Heo
2018-01-17 15:53 ` 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).