From patchwork Fri Jan 12 01:31:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Fainelli X-Patchwork-Id: 859444 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ide-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="bPZ9nyhj"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zHlbV5Q6zz9sNr for ; Fri, 12 Jan 2018 12:32:06 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932446AbeALBbu (ORCPT ); Thu, 11 Jan 2018 20:31:50 -0500 Received: from mail-qt0-f195.google.com ([209.85.216.195]:44320 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932340AbeALBbd (ORCPT ); Thu, 11 Jan 2018 20:31:33 -0500 Received: by mail-qt0-f195.google.com with SMTP id m59so4290154qte.11; Thu, 11 Jan 2018 17:31:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Oa9ex4No4vgHi/TBpz3vR3KnxxiLt9Z/TcNT6gCZm9g=; b=bPZ9nyhj1auhWzmxatDmtO/j/17jM2/cmzmIvErsUGrDwWZww+0NYabE1Fl6tK9dfS ayz5FYiUMPhb8AJHBxubWvR3kpykV/Q2ag0yoYYPWXIZbDdPE1WnYAOtY/KYaEtAtsNq XZnP2C0+BD86wocGtM+vpLS78dfyVGWjz2XJXqY/8UGv/ZomxHSy69yZX2rnifcyzrv7 60pac/MzvoUYy2vTD3470hi9E8fstVzuUrw67X4mq49GRgZkPTZNo4np1bWGvX+uRa1/ 8T/q4tOJng8BvdGkdqLlCPDi2bdQGpKk0CX8jqOGqqzPCHRHapildcKbiFpFSwvkRoSS cD1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Oa9ex4No4vgHi/TBpz3vR3KnxxiLt9Z/TcNT6gCZm9g=; b=eoBo5/eg2A6cwTqbOsC40EOPcWS0gci/+4TeB75Mk5vDGz5jpHPykOtGhZ9wta3XMr QZ8w/vlU8vN4ivQqm/eFSzKflhuq22ehv0RLIJnSyu7gQ0JQ23jEnR2dFxSa6XNWmp8h AsCIoYeHFkwjeLxbYhmBi8s/lDYKKexthpBTZ02uG9oShgdG6SlbA5wLXFKg+ctIYJEL 99BAk/tS0oX7xvsXHfuGahY7Fs9+AsHaWD1l7vOxm5G05g8QGLAsGguZVnUBnEH6/b34 8LSDy53XttsO1qzwRBgcm6pm0uCk43qev6WYRPfj3FUrFaL1wEujXCRoWLg9cdhnx+38 QZrA== X-Gm-Message-State: AKwxytcWyZIf6i0opHtDrJqjaQPAhFGTPc0EkH9CwTW+AVncZAZ8SVvs tuiLB5vqxxgYTE7r+0Rg0KU= X-Google-Smtp-Source: ACJfBosIGei3mnXhXsNMvKtnZyLylHAsBEvA7Lz5aYYfs5xev/TRT5bY3Labjk+doW6m9DC0UddVEA== X-Received: by 10.200.112.75 with SMTP id y11mr17514316qtm.295.1515720692161; Thu, 11 Jan 2018 17:31:32 -0800 (PST) Received: from stbirv-lnx-3.igp.broadcom.net ([192.19.223.250]) by smtp.gmail.com with ESMTPSA id z85sm13311660qkb.51.2018.01.11.17.31.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 11 Jan 2018 17:31:31 -0800 (PST) From: Florian Fainelli To: bcm-kernel-feedback-list@broadcom.com Cc: Florian Fainelli , Tejun Heo , Kishon Vijay Abraham I , Heiko Stuebner , Srinath Mannam , Krzysztof Kozlowski , Vivek Gautam , Dan Carpenter , linux-ide@vger.kernel.org (open list:LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v2 2/2] ata: ahci_brcm: Recover from failures to identify devices Date: Thu, 11 Jan 2018 17:31:08 -0800 Message-Id: <1515720668-4860-3-git-send-email-f.fainelli@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515720668-4860-1-git-send-email-f.fainelli@gmail.com> References: <1515720668-4860-1-git-send-email-f.fainelli@gmail.com> Sender: linux-ide-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ide@vger.kernel.org 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 --- 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) {