All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Richardson <jonathar@broadcom.com>
To: Mark Brown <broonie@kernel.org>,
	Dmitry Torokhov <dtor@google.com>,
	Anatol Pomazau <anatol@google.com>
Cc: Jonathan Richardson <jonathar@broadcom.com>,
	Scott Branden <sbranden@broadcom.com>,
	Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Ian Campbell <ijc+devicetree@hellion.org.uk>,
	Kumar Gala <galak@codeaurora.org>, <linux-kernel@vger.kernel.org>,
	<linux-spi@vger.kernel.org>,
	bcm-kernel-feedback-list <bcm-kernel-feedback-list@broadcom.com>,
	<devicetree@vger.kernel.org>, Rafal Milecki <zajec5@gmail.com>
Subject: [PATCH v2 5/5] spi: bcm-mspi: Add support to set serial baud clock rate
Date: Wed, 8 Apr 2015 11:04:35 -0700	[thread overview]
Message-ID: <1428516275-12819-6-git-send-email-jonathar@broadcom.com> (raw)
In-Reply-To: <1428516275-12819-1-git-send-email-jonathar@broadcom.com>

The driver wasn't setting the SPBR (serial clock baud rate) which caused
it to run at the slowest speed possible. The driver now calculates the
SPBR based on the reference clock frequency resulting in much faster
SPI transfers.

Signed-off-by: Jonathan Richardson <jonathar@broadcom.com>
---
 drivers/spi/spi-bcm-mspi.c |   50 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/spi/spi-bcm-mspi.c b/drivers/spi/spi-bcm-mspi.c
index 32bb1f0..9320de9 100644
--- a/drivers/spi/spi-bcm-mspi.c
+++ b/drivers/spi/spi-bcm-mspi.c
@@ -18,10 +18,15 @@
 #include <linux/bcma/bcma.h>
 #include <linux/spi/spi.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "spi-bcm-mspi.h"
 
 #define BCM_MSPI_MAX_SPI_BAUD   13500000	/* 216 MHz? */
+#define SPBR_MIN                8U
+#define SPBR_MAX                255U
+#define MSPI_SPCR0_LSB_OFFSET   0x200
+#define MSPI_SPCR0_LSB_SHIFT    0
 
 /* The longest observed required wait was 19 ms */
 #define BCM_MSPI_SPE_TIMEOUT_MS 80
@@ -33,7 +38,9 @@ struct bcm_mspi {
 
 	void __iomem *base;
 	struct spi_master *master;
+	struct clk *clk;
 	size_t read_offset;
+	u32    spbr;
 
 	void (*mspi_write)(struct bcm_mspi *mspi, u16 offset, u32 value);
 	u32 (*mspi_read)(struct bcm_mspi *mspi, u16 offset);
@@ -45,6 +52,15 @@ static inline unsigned int bcm_mspi_calc_timeout(size_t len)
 	return (len * 9000 / BCM_MSPI_MAX_SPI_BAUD * 110 / 100) + 1;
 }
 
+static void bcm_mspi_hw_init(struct bcm_mspi *mspi)
+{
+	/* Set SPBR (serial clock baud rate). */
+	if (mspi->spbr) {
+		mspi->mspi_write(mspi, MSPI_SPCR0_LSB_OFFSET,
+			mspi->spbr << MSPI_SPCR0_LSB_SHIFT);
+	}
+}
+
 static int bcm_mspi_wait(struct bcm_mspi *mspi, unsigned int timeout_ms)
 {
 	unsigned long deadline;
@@ -222,6 +238,7 @@ static struct bcm_mspi *bcm_mspi_init(struct device *dev)
 {
 	struct bcm_mspi *data;
 	struct spi_master *master;
+	u32 desired_rate;
 
 	master = spi_alloc_master(dev, sizeof(*data));
 	if (!master) {
@@ -236,6 +253,33 @@ static struct bcm_mspi *bcm_mspi_init(struct device *dev)
 	master->dev.of_node = dev->of_node;
 	master->transfer_one = bcm_mspi_transfer_one;
 
+	/*
+	 * Enable clock if provided. The frequency can be changed by setting
+	 * SPBR (serial clock baud rate) based on the desired 'clock-frequency'.
+	 *
+	 * Baud rate is calculated as: mspi_clk / (2 * SPBR) where SPBR is a
+	 * value between 1-255. If not set then it is left at the h/w default.
+	 */
+	data->clk = devm_clk_get(dev, "mspi_clk");
+	if (!IS_ERR(data->clk)) {
+		int ret = clk_prepare_enable(data->clk);
+
+		if (ret < 0) {
+			dev_err(dev, "failed to enable clock: %d\n", ret);
+			return 0;
+		}
+
+		/* Calculate SPBR if clock-frequency provided. */
+		if (of_property_read_u32(dev->of_node, "clock-frequency",
+			&desired_rate) >= 0) {
+			u32 spbr = clk_get_rate(data->clk) / (2 * desired_rate);
+
+			if (spbr > 0)
+				data->spbr = clamp_val(spbr, SPBR_MIN,
+					SPBR_MAX);
+		}
+	}
+
 	return data;
 }
 
@@ -287,6 +331,9 @@ static int bcm_mspi_probe(struct platform_device *pdev)
 	data->mspi_write = bcm_mspi_write;
 	platform_set_drvdata(pdev, data);
 
+	/* Initialize SPI controller. */
+	bcm_mspi_hw_init(data);
+
 	err = devm_spi_register_master(dev, data->master);
 	if (err)
 		goto out;
@@ -362,6 +409,9 @@ static int bcm_mspi_bcma_probe(struct bcma_device *core)
 
 	bcma_set_drvdata(core, data);
 
+	/* Initialize SPI controller. */
+	bcm_mspi_hw_init(data);
+
 	err = devm_spi_register_master(&core->dev, data->master);
 	if (err) {
 		spi_master_put(data->master);
-- 
1.7.9.5


WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Richardson <jonathar@broadcom.com>
To: Mark Brown <broonie@kernel.org>,
	Dmitry Torokhov <dtor@google.com>,
	Anatol Pomazau <anatol@google.com>
Cc: Jonathan Richardson <jonathar@broadcom.com>,
	Scott Branden <sbranden@broadcom.com>,
	Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Ian Campbell <ijc+devicetree@hellion.org.uk>,
	Kumar Gala <galak@codeaurora.org>,
	linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org,
	bcm-kernel-feedback-list <bcm-kernel-feedback-list@broadcom.com>,
	devicetree@vger.kernel.org, Rafal Milecki <zajec5@gmail.com>
Subject: [PATCH v2 5/5] spi: bcm-mspi: Add support to set serial baud clock rate
Date: Wed, 8 Apr 2015 11:04:35 -0700	[thread overview]
Message-ID: <1428516275-12819-6-git-send-email-jonathar@broadcom.com> (raw)
In-Reply-To: <1428516275-12819-1-git-send-email-jonathar@broadcom.com>

The driver wasn't setting the SPBR (serial clock baud rate) which caused
it to run at the slowest speed possible. The driver now calculates the
SPBR based on the reference clock frequency resulting in much faster
SPI transfers.

Signed-off-by: Jonathan Richardson <jonathar@broadcom.com>
---
 drivers/spi/spi-bcm-mspi.c |   50 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/spi/spi-bcm-mspi.c b/drivers/spi/spi-bcm-mspi.c
index 32bb1f0..9320de9 100644
--- a/drivers/spi/spi-bcm-mspi.c
+++ b/drivers/spi/spi-bcm-mspi.c
@@ -18,10 +18,15 @@
 #include <linux/bcma/bcma.h>
 #include <linux/spi/spi.h>
 #include <linux/of.h>
+#include <linux/clk.h>
 
 #include "spi-bcm-mspi.h"
 
 #define BCM_MSPI_MAX_SPI_BAUD   13500000	/* 216 MHz? */
+#define SPBR_MIN                8U
+#define SPBR_MAX                255U
+#define MSPI_SPCR0_LSB_OFFSET   0x200
+#define MSPI_SPCR0_LSB_SHIFT    0
 
 /* The longest observed required wait was 19 ms */
 #define BCM_MSPI_SPE_TIMEOUT_MS 80
@@ -33,7 +38,9 @@ struct bcm_mspi {
 
 	void __iomem *base;
 	struct spi_master *master;
+	struct clk *clk;
 	size_t read_offset;
+	u32    spbr;
 
 	void (*mspi_write)(struct bcm_mspi *mspi, u16 offset, u32 value);
 	u32 (*mspi_read)(struct bcm_mspi *mspi, u16 offset);
@@ -45,6 +52,15 @@ static inline unsigned int bcm_mspi_calc_timeout(size_t len)
 	return (len * 9000 / BCM_MSPI_MAX_SPI_BAUD * 110 / 100) + 1;
 }
 
+static void bcm_mspi_hw_init(struct bcm_mspi *mspi)
+{
+	/* Set SPBR (serial clock baud rate). */
+	if (mspi->spbr) {
+		mspi->mspi_write(mspi, MSPI_SPCR0_LSB_OFFSET,
+			mspi->spbr << MSPI_SPCR0_LSB_SHIFT);
+	}
+}
+
 static int bcm_mspi_wait(struct bcm_mspi *mspi, unsigned int timeout_ms)
 {
 	unsigned long deadline;
@@ -222,6 +238,7 @@ static struct bcm_mspi *bcm_mspi_init(struct device *dev)
 {
 	struct bcm_mspi *data;
 	struct spi_master *master;
+	u32 desired_rate;
 
 	master = spi_alloc_master(dev, sizeof(*data));
 	if (!master) {
@@ -236,6 +253,33 @@ static struct bcm_mspi *bcm_mspi_init(struct device *dev)
 	master->dev.of_node = dev->of_node;
 	master->transfer_one = bcm_mspi_transfer_one;
 
+	/*
+	 * Enable clock if provided. The frequency can be changed by setting
+	 * SPBR (serial clock baud rate) based on the desired 'clock-frequency'.
+	 *
+	 * Baud rate is calculated as: mspi_clk / (2 * SPBR) where SPBR is a
+	 * value between 1-255. If not set then it is left at the h/w default.
+	 */
+	data->clk = devm_clk_get(dev, "mspi_clk");
+	if (!IS_ERR(data->clk)) {
+		int ret = clk_prepare_enable(data->clk);
+
+		if (ret < 0) {
+			dev_err(dev, "failed to enable clock: %d\n", ret);
+			return 0;
+		}
+
+		/* Calculate SPBR if clock-frequency provided. */
+		if (of_property_read_u32(dev->of_node, "clock-frequency",
+			&desired_rate) >= 0) {
+			u32 spbr = clk_get_rate(data->clk) / (2 * desired_rate);
+
+			if (spbr > 0)
+				data->spbr = clamp_val(spbr, SPBR_MIN,
+					SPBR_MAX);
+		}
+	}
+
 	return data;
 }
 
@@ -287,6 +331,9 @@ static int bcm_mspi_probe(struct platform_device *pdev)
 	data->mspi_write = bcm_mspi_write;
 	platform_set_drvdata(pdev, data);
 
+	/* Initialize SPI controller. */
+	bcm_mspi_hw_init(data);
+
 	err = devm_spi_register_master(dev, data->master);
 	if (err)
 		goto out;
@@ -362,6 +409,9 @@ static int bcm_mspi_bcma_probe(struct bcma_device *core)
 
 	bcma_set_drvdata(core, data);
 
+	/* Initialize SPI controller. */
+	bcm_mspi_hw_init(data);
+
 	err = devm_spi_register_master(&core->dev, data->master);
 	if (err) {
 		spi_master_put(data->master);
-- 
1.7.9.5

  parent reply	other threads:[~2015-04-08 18:03 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-08 18:04 [PATCH v2 0/5] Add MSPI support for Cygnus Jonathan Richardson
2015-04-08 18:04 ` Jonathan Richardson
2015-04-08 18:04 ` Jonathan Richardson
2015-04-08 18:04 ` [PATCH v2 1/5] ARM: dts: Add binding for Broadcom MSPI driver Jonathan Richardson
2015-04-08 18:04   ` Jonathan Richardson
2015-04-08 18:04   ` Jonathan Richardson
2015-04-08 18:04 ` [PATCH v2 2/5] spi: bcm53xx: Refactor driver to make nonspecific to 53xx SoCs Jonathan Richardson
2015-04-08 18:04   ` Jonathan Richardson
2015-04-08 19:49   ` Mark Brown
2015-04-08 19:49     ` Mark Brown
2015-04-08 18:04 ` [PATCH v2 3/5] spi: bcm-mspi: Refactor to make driver " Jonathan Richardson
2015-04-08 18:04   ` Jonathan Richardson
2015-04-08 18:04   ` Jonathan Richardson
2015-04-08 18:04 ` [PATCH v2 4/5] spi: bcm-mspi: Make BCMA optional to support non-BCMA chips Jonathan Richardson
2015-04-08 18:04   ` Jonathan Richardson
2015-04-08 18:04   ` Jonathan Richardson
2015-04-08 19:27   ` Jonas Gorski
2015-04-08 19:27     ` Jonas Gorski
2015-04-08 22:26     ` Jonathan Richardson
2015-04-08 22:26       ` Jonathan Richardson
2015-04-08 22:26       ` Jonathan Richardson
2015-04-08 20:03   ` Mark Brown
2015-04-08 20:03     ` Mark Brown
2015-04-09 22:26     ` Jonathan Richardson
2015-04-09 22:26       ` Jonathan Richardson
2015-04-09 22:26       ` Jonathan Richardson
2015-04-08 18:04 ` Jonathan Richardson [this message]
2015-04-08 18:04   ` [PATCH v2 5/5] spi: bcm-mspi: Add support to set serial baud clock rate Jonathan Richardson
2015-04-08 19:32   ` Jonas Gorski
2015-04-08 19:32     ` Jonas Gorski
2015-04-08 19:53   ` Mark Brown
2015-04-08 19:53     ` Mark Brown

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=1428516275-12819-6-git-send-email-jonathar@broadcom.com \
    --to=jonathar@broadcom.com \
    --cc=anatol@google.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dtor@google.com \
    --cc=galak@codeaurora.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=pawel.moll@arm.com \
    --cc=robh+dt@kernel.org \
    --cc=sbranden@broadcom.com \
    --cc=zajec5@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.