linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
To: Kevin Hilman <khilman@kernel.org>, Sekhar Nori <nsekhar@ti.com>,
	Patrick Titiano <ptitiano@baylibre.com>,
	Michael Turquette <mturquette@baylibre.com>,
	Tejun Heo <tj@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Russell King <linux@armlinux.org.uk>,
	David Lechner <david@lechnology.com>
Cc: linux-ide@vger.kernel.org,
	Bartosz Golaszewski <bgolaszewski@baylibre.com>,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
Subject: [PATCH v6 11/14] sata: ahci-da850: un-hardcode the MPY bits
Date: Mon, 23 Jan 2017 18:00:53 +0100	[thread overview]
Message-ID: <1485190856-4711-12-git-send-email-bgolaszewski@baylibre.com> (raw)
In-Reply-To: <1485190856-4711-1-git-send-email-bgolaszewski@baylibre.com>

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 <bgolaszewski@baylibre.com>
Acked-by: Tejun Heo <tj@kernel.org>
---
 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);
-- 
2.9.3

  parent reply	other threads:[~2017-01-23 17:00 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-23 17:00 [PATCH v6 00/14] ARM: da850-lcdk: add SATA support Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 01/14] devicetree: bindings: add bindings for ahci-da850 Bartosz Golaszewski
2017-01-27 20:58   ` Rob Herring
2017-01-23 17:00 ` [PATCH v6 02/14] ARM: davinci_all_defconfig: enable SATA modules Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 03/14] ARM: davinci: add a clock lookup entry for the SATA clock Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 04/14] sata: ahci-da850: get the sata clock using a connection id Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 05/14] ARM: davinci: da850: add con_id for the SATA clock Bartosz Golaszewski
2017-01-26 16:56   ` Grygorii Strashko
2017-01-26 17:40     ` Sekhar Nori
     [not found]       ` <645778dd-6727-abd0-3dd9-a7e0d5aa4983-l0cyMroinI0@public.gmane.org>
2017-01-27  9:55         ` Bartosz Golaszewski
2017-01-27  9:58           ` Sekhar Nori
2017-01-23 17:00 ` [PATCH v6 06/14] ARM: davinci: da850: model the SATA refclk Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 07/14] sata: ahci-da850: add device tree match table Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 08/14] sata: ahci-da850: implement a workaround for the softreset quirk Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 09/14] sata: ahci: export ahci_do_hardreset() locally Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 10/14] sata: ahci-da850: add a workaround for controller instability Bartosz Golaszewski
2017-01-23 17:00 ` Bartosz Golaszewski [this message]
2017-01-23 17:00 ` [PATCH v6 12/14] ARM: davinci: remove BUG_ON() from da850_register_sata() Bartosz Golaszewski
2017-01-23 17:00 ` [PATCH v6 13/14] ARM: dts: da850: add the SATA node Bartosz Golaszewski
     [not found] ` <1485190856-4711-1-git-send-email-bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
2017-01-23 17:00   ` [PATCH v6 14/14] ARM: dts: da850-lcdk: enable " Bartosz Golaszewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1485190856-4711-12-git-send-email-bgolaszewski@baylibre.com \
    --to=bgolaszewski@baylibre.com \
    --cc=david@lechnology.com \
    --cc=devicetree@vger.kernel.org \
    --cc=khilman@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=mark.rutland@arm.com \
    --cc=mturquette@baylibre.com \
    --cc=nsekhar@ti.com \
    --cc=ptitiano@baylibre.com \
    --cc=robh+dt@kernel.org \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).