From: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
To: linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Geert Uytterhoeven
<geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
Subject: [PATCH/PROTO 7/9 option 2] spi: sh-msiof: Configure MSIOF parent clock
Date: Fri, 12 Aug 2016 18:38:43 +0200 [thread overview]
Message-ID: <1471019925-29083-8-git-send-email-geert+renesas@glider.be> (raw)
In-Reply-To: <1471019925-29083-1-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
Change the clock rate in spi_master.setup() to accomodate the desired
maximum clock rate for the device being set up:
- Change the clock rate if the msiofX (and thus mso) clock rate is too
high. Failure to do so is considered an error.
- Try to change the clock rate if the msiofX (and thus mso) clock rate
is too low to achieve the desired performance. Failure to do so is
not considered an error, as the device will still work, but slower.
Results (sequential operations during probing):
1. msiof0 (and mso) set to 30.8 MHz, 15.4 MHz after internal
divider,
2. msiof2 kept at 30.8 MHz, 993 kHz after internal divider,
3. msiof3 (and mso) set to 20 MHz, 19.5 kHz after internal divider.
Observations:
- As the requested rate of 30 MHz is rounded to 30.8 MHz, which is
higher than 30 MHz, an mso internal divider of 2 is used, leading to
a much lower rate of 15.4 MHz, and thus lower performance than
expected.
- The parent clock frequency cannot be changed while the mso clock is
enabled. This is tricky, as the MSIOF modules are part of a Clock
Domain, hence their clocks (and its parent clock) are under control
of Runtime PM.
So the parent clock may still be enabled due to asynchronous
runtime-suspend not having disabled it yet, causing clk_set_rate()
to fail sometimes with -EBUSY.
Not-Signed-off-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
---
Not intended for upstream merge.
---
drivers/spi/spi-sh-msiof.c | 74 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 73 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index 656eaa4d03ed497b..0b69643936cdb941 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -584,7 +584,8 @@ static int sh_msiof_spi_setup(struct spi_device *spi)
struct device_node *np = spi->master->dev.of_node;
struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master);
u32 max_speed_hz, min_speed_hz;
- unsigned long rate;
+ unsigned long rate, req_rate;
+ int error;
rate = clk_get_rate(p->clk);
max_speed_hz = rate;
@@ -594,6 +595,77 @@ static int sh_msiof_spi_setup(struct spi_device *spi)
"%s: master speed min %u max %u, device speed max = %u\n",
__func__, min_speed_hz, max_speed_hz, spi->max_speed_hz);
+ if (spi->max_speed_hz < min_speed_hz) {
+ dev_err(&p->pdev->dev,
+ "Parent clock rate %lu too high for %u!\n", rate,
+ spi->max_speed_hz);
+
+ req_rate = spi->max_speed_hz * MAX_DIV;
+
+ error = clk_set_rate(p->clk, req_rate);
+ if (error) {
+ dev_err(&p->pdev->dev,
+ "Failed to set parent clock rate to %lu: %d\n",
+ req_rate, error);
+ return error;
+ }
+
+ rate = clk_get_rate(p->clk);
+ dev_info(&p->pdev->dev,
+ "Changed parent clock rate to %lu actual %lu\n",
+ req_rate, rate);
+
+ max_speed_hz = rate;
+ min_speed_hz = rate / MAX_DIV;
+
+ dev_info(&p->pdev->dev,
+ "%s: new master speed min %u max %u, device speed max = %u\n",
+ __func__, min_speed_hz, max_speed_hz,
+ spi->max_speed_hz);
+
+ if (spi->max_speed_hz < min_speed_hz) {
+ dev_err(&p->pdev->dev,
+ "New parent clock rate %lu too high for %u!\n",
+ rate, spi->max_speed_hz);
+ return -EINVAL;
+ }
+ } else if (spi->max_speed_hz * 4 > max_speed_hz * 5) {
+ /* More than 20% lower than desired */
+ dev_warn(&p->pdev->dev,
+ "Parent clock rate %lu too low for %u\n", rate,
+ spi->max_speed_hz);
+
+ req_rate = spi->max_speed_hz;
+
+ error = clk_set_rate(p->clk, req_rate);
+ if (error) {
+ dev_warn(&p->pdev->dev,
+ "Failed to set parent clock rate to %lu: %d, ignoring\n",
+ req_rate, error);
+ goto done;
+ }
+
+ rate = clk_get_rate(p->clk);
+ dev_info(&p->pdev->dev,
+ "Changed parent clock rate to %lu actual %lu\n",
+ req_rate, rate);
+
+ max_speed_hz = rate;
+ min_speed_hz = rate / MAX_DIV;
+
+ dev_info(&p->pdev->dev,
+ "%s: new master speed min %u max %u, device speed max = %u\n",
+ __func__, min_speed_hz, max_speed_hz,
+ spi->max_speed_hz);
+
+ if (spi->max_speed_hz * 4 > max_speed_hz * 5) {
+ dev_warn(&p->pdev->dev,
+ "New parent clock rate %lu too high for %u, ignoring\n",
+ rate, spi->max_speed_hz);
+ }
+ }
+
+done:
p->dev_max_speed_hz = spi->max_speed_hz;
pm_runtime_get_sync(&p->pdev->dev);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2016-08-12 16:38 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-12 16:38 [PATCH/PROTO 0/9] R-Car H3 MSIOF Parent Clock Control Prototype Geert Uytterhoeven
2016-08-12 16:38 ` [PATCH/PROTO 1/9 common] spi: sh-msiof: Add support for R-Car H3 Geert Uytterhoeven
2016-08-12 16:38 ` [PATCH/PROTO 2/9 common] spi: sh-msiof: Print max and transfer frequency Geert Uytterhoeven
2016-08-12 16:38 ` [PATCH/PROTO 3/9 common] arm64: dts: r8a7795: Add all MSIOF nodes Geert Uytterhoeven
[not found] ` <1471019925-29083-1-git-send-email-geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
2016-08-12 16:38 ` [PATCH/PROTO 4/9 common] arm64: dts: salvator-x: Add dummy MSIOF SPI slave devices Geert Uytterhoeven
2016-08-12 16:38 ` Geert Uytterhoeven [this message]
2016-08-12 16:38 ` [PATCH/PROTO 9/9 option 3] spi: sh-msiof: Configure MSIOF parent clock Geert Uytterhoeven
2016-08-12 16:38 ` [PATCH/PROTO 5/9 option 1] arm64: dts: salvator-x: " Geert Uytterhoeven
2016-08-12 16:38 ` [PATCH/PROTO 6/9 option 2/3] spi: sh-msiof: Add clock notifier to enforce valid " Geert Uytterhoeven
2016-08-12 16:38 ` [PATCH/PROTO 8/9 option 3] clk: divider: Add hack to support dummy clocks Geert Uytterhoeven
2016-08-25 5:34 ` [PATCH/PROTO 0/9] R-Car H3 MSIOF Parent Clock Control Prototype Magnus Damm
2016-08-29 12:38 ` Geert Uytterhoeven
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=1471019925-29083-8-git-send-email-geert+renesas@glider.be \
--to=geert+renesas-gxvu3+zwzmszqb+pc5nmwq@public.gmane.org \
--cc=linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.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).