From patchwork Wed Jan 18 13:19:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 9523775 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5704A6020A for ; Wed, 18 Jan 2017 13:25:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4447120246 for ; Wed, 18 Jan 2017 13:25:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3794C285EC; Wed, 18 Jan 2017 13:25:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CA45420246 for ; Wed, 18 Jan 2017 13:25:24 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cTqEt-00051g-Uz; Wed, 18 Jan 2017 13:25:23 +0000 Received: from mail-wm0-x235.google.com ([2a00:1450:400c:c09::235]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cTqAY-0006lx-Ar for linux-arm-kernel@lists.infradead.org; Wed, 18 Jan 2017 13:20:56 +0000 Received: by mail-wm0-x235.google.com with SMTP id c85so243938631wmi.1 for ; Wed, 18 Jan 2017 05:20:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=R5PNJOuUNZ0TgS4mS+ALb4UY8CbowzkiyfRTK/S7H2U=; b=Z16T4glbvCM16rCAAQnv2rYSryyrl7QNF7+vvnHXZQhcUvrSazFH79fSsdJMIwKoJo 7BSeBgz5wxwQTusGVxk+pxVrSYptS1vuqo6ECox6vDXy8ighoou/h1ZOkV9XGruwl0WO p/xL1fAJezDlR8M7UnXKSo5Zzn9wILTO8k5W07AUuPvDvbXTYnKFXlynzpMM1j3mMISS tRX6Zs1OBxKfILoOVhzu6+Jgg90BhpzUd9IlaCvBsiQLb4bjFHmsS2hgcOiLWj3Ma/zm JHSnvpfsV0BBnQDEfvzuC70PNWHZ27MspDqwmcmZSpQgg5czHkFuEeguW9uoP7z44mUf Qt8Q== 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=R5PNJOuUNZ0TgS4mS+ALb4UY8CbowzkiyfRTK/S7H2U=; b=gCRVZgPEWaCkg9I8SseV6kxLTEbDKZR0my/mUxeyNj6xR1yFTGNoGA3EBmhcwjvlQQ WbnsiaLclpqMc1hMjVcm5+UvKdwTqBMOdtQUH+loJPWMWlU88SKXMJU5YVvMcTM8TWSk SXRxRzHyDqxJJ1E+3SUf4giNCYgKGKJQdf0vaLiwDAisbHhEWeB72szW3hkziMruu7yN PeFvahmEdX84i3URz5tYtDnWv8hbLTZQVfdTl6sNI19qYIvKB00TgoN5l3yLy49NYLB1 Rt+imNAAgs4XHoOHKxicid7ZIfwDlRy/UXovKbihFKAi0f9jUOqv4Lb5/R5L8tWt4AUs xi/g== X-Gm-Message-State: AIkVDXIgupIUEjCRnGUU1SL556s9kIpekXnFFhhbATSzSOLLwHwa5k7KTAL+boHR8DvbLE5/ X-Received: by 10.28.98.66 with SMTP id w63mr22302962wmb.142.1484745632385; Wed, 18 Jan 2017 05:20:32 -0800 (PST) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id w79sm4899569wmw.0.2017.01.18.05.20.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 18 Jan 2017 05:20:31 -0800 (PST) From: Bartosz Golaszewski To: Kevin Hilman , Sekhar Nori , Patrick Titiano , Michael Turquette , Tejun Heo , Rob Herring , Mark Rutland , Russell King , David Lechner Subject: [PATCH v3 11/13] sata: ahci-da850: un-hardcode the MPY bits Date: Wed, 18 Jan 2017 14:19:59 +0100 Message-Id: <1484745601-4769-12-git-send-email-bgolaszewski@baylibre.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1484745601-4769-1-git-send-email-bgolaszewski@baylibre.com> References: <1484745601-4769-1-git-send-email-bgolaszewski@baylibre.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170118_052054_552156_81023A35 X-CRM114-Status: GOOD ( 19.78 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-ide@vger.kernel.org, Bartosz Golaszewski , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP All platforms using this driver now register the SATA refclk. Remove the hardcoded default value from the driver and instead read the rate of the external clock and calculate the required MPY value from it. Signed-off-by: Bartosz Golaszewski --- drivers/ata/ahci_da850.c | 91 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 15 deletions(-) diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c index 0b2b1a4..9ed404d 100644 --- a/drivers/ata/ahci_da850.c +++ b/drivers/ata/ahci_da850.c @@ -29,17 +29,8 @@ #define SATA_PHY_TXSWING(x) ((x) << 19) #define SATA_PHY_ENPLL(x) ((x) << 31) -/* - * The multiplier needed for 1.5GHz PLL output. - * - * NOTE: This is currently hardcoded to be suitable for 100MHz crystal - * frequency (which is used by DA850 EVM board) and may need to be changed - * if you would like to use this driver on some other board. - */ -#define DA850_SATA_CLK_MULTIPLIER 7 - static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, - void __iomem *ahci_base) + void __iomem *ahci_base, u32 mpy) { unsigned int val; @@ -48,13 +39,61 @@ static void da850_sata_init(struct device *dev, void __iomem *pwrdn_reg, val &= ~BIT(0); writel(val, pwrdn_reg); - val = SATA_PHY_MPY(DA850_SATA_CLK_MULTIPLIER + 1) | SATA_PHY_LOS(1) | - SATA_PHY_RXCDR(4) | SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) | - SATA_PHY_ENPLL(1); + val = SATA_PHY_MPY(mpy) | SATA_PHY_LOS(1) | SATA_PHY_RXCDR(4) | + SATA_PHY_RXEQ(1) | SATA_PHY_TXSWING(3) | SATA_PHY_ENPLL(1); writel(val, ahci_base + SATA_P0PHYCR_REG); } +static u32 ahci_da850_calculate_mpy(unsigned long refclk_rate) +{ + u32 pll_output = 1500000000, needed; + + /* + * We need to determine the value of the multiplier (MPY) bits. + * In order to include the 12.5 multiplier we need to first divide + * the refclk rate by ten. + * + * __div64_32() turned out to be unreliable, sometimes returning + * false results. + */ + WARN((refclk_rate % 10) != 0, "refclk must be divisible by 10"); + needed = pll_output / (refclk_rate / 10); + + /* + * What we have now is (multiplier * 10). + * + * Let's determine the actual register value we need to write. + */ + + switch (needed) { + case 50: + return 0x1; + case 60: + return 0x2; + case 80: + return 0x4; + case 100: + return 0x5; + case 120: + return 0x6; + case 125: + return 0x7; + case 150: + return 0x8; + case 200: + return 0x9; + case 250: + return 0xa; + default: + /* + * We should have divided evenly - if not, return an invalid + * value. + */ + return 0; + } +} + static int ahci_da850_softreset(struct ata_link *link, unsigned int *class, unsigned long deadline) { @@ -126,9 +165,10 @@ static int ahci_da850_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ahci_host_priv *hpriv; - struct resource *res; void __iomem *pwrdn_reg; + struct resource *res; struct clk *clk; + u32 mpy; int rc; hpriv = ahci_platform_get_resources(pdev); @@ -150,6 +190,27 @@ static int ahci_da850_probe(struct platform_device *pdev) hpriv->clks[0] = clk; } + /* + * The second clock used by ahci-da850 is the external REFCLK. If we + * didn't get it from ahci_platform_get_resources(), let's try to + * specify the con_id in clk_get(). + */ + if (!hpriv->clks[1]) { + clk = clk_get(dev, "refclk"); + if (IS_ERR(clk)) { + dev_err(dev, "unable to obtain the reference clock"); + return -ENODEV; + } else { + hpriv->clks[1] = clk; + } + } + + mpy = ahci_da850_calculate_mpy(clk_get_rate(hpriv->clks[1])); + if (mpy == 0) { + dev_err(dev, "invalid REFCLK multiplier value: 0x%x", mpy); + return -EINVAL; + } + rc = ahci_platform_enable_resources(hpriv); if (rc) return rc; @@ -162,7 +223,7 @@ static int ahci_da850_probe(struct platform_device *pdev) if (!pwrdn_reg) goto disable_resources; - da850_sata_init(dev, pwrdn_reg, hpriv->mmio); + da850_sata_init(dev, pwrdn_reg, hpriv->mmio, mpy); rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info, &ahci_platform_sht);