From: kernel@martin.sperl.org
To: Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@codeaurora.org>,
Stephen Warren <swarren@wwwdotorg.org>,
Lee Jones <lee@kernel.org>, Eric Anholt <eric@anholt.net>,
Remi Pommarel <repk@triplefau.lt>,
linux-clk@vger.kernel.org, linux-rpi-kernel@lists.infradead.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
Cc: Martin Sperl <kernel@martin.sperl.org>
Subject: [PATCH V2 2/4] clk: bcm2835: enable fractional and mash support
Date: Mon, 11 Jan 2016 19:55:54 +0000 [thread overview]
Message-ID: <1452542157-2387-3-git-send-email-kernel@martin.sperl.org> (raw)
In-Reply-To: <1452542157-2387-1-git-send-email-kernel@martin.sperl.org>
From: Martin Sperl <kernel@martin.sperl.org>
The clk-bcm2835 driver right now does the correct calculation
of the fractional clock divider, but it does not set the FRAC
bit to enable the fractual clock divider in HW
This patch enables FRAC for all clocks with frac_bits > 0
but allows to define the selection of a higher-order MASH
support instead of just FRAC.
Right now there are no limits imposed on maximum frequencies
when using MASH/FRAC is enabled.
There is a documented limit of 25MHz for MASH, but it is not
stated if this also applies to clock dividers that only support
FRAC and not MASH.
As for how higher order MASH works the following may give
some insight: http://www.aholme.co.uk/Frac2/Mash.htm
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
drivers/clk/bcm/clk-bcm2835.c | 50 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 759202a..7c782d3 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -115,6 +115,13 @@
# define CM_GATE BIT(CM_GATE_BIT)
# define CM_BUSY BIT(7)
# define CM_BUSYD BIT(8)
+# define CM_MASH_BITS 2
+# define CM_MASH_SHIFT 9
+# define CM_MASH_MASK GENMASK(10, 9)
+# define CM_MASH(v) ((v << CM_MASH_SHIFT) & CM_MASH_MASK)
+# define CM_MASH_FRAC CM_MASH(1)
+# define CM_MASH_2ND_ORDER CM_MASH(2)
+# define CM_MASH_3RD_ORDER CM_MASH(3)
# define CM_SRC_SHIFT 0
# define CM_SRC_BITS 4
# define CM_SRC_MASK 0xf
@@ -632,6 +639,8 @@ struct bcm2835_clock_data {
u32 int_bits;
/* Number of fractional bits in the divider */
u32 frac_bits;
+ /* the mash value to use - see CM_MASH and CM_MASH_FRAC/ORDER */
+ u32 mash;
bool is_vpu_clock;
};
@@ -1274,9 +1283,50 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
struct bcm2835_cprman *cprman = clock->cprman;
const struct bcm2835_clock_data *data = clock->data;
u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false);
+ u32 ctl, mash;
+ bool enabled;
+ spin_lock(&cprman->regs_lock);
+ /* check if divider is identical, then return */
+ if (div == cprman_read(cprman, data->div_reg))
+ goto unlock;
+
+ /* it is recommended to only set clock registers when disabled */
+ ctl = cprman_read(cprman, data->ctl_reg);
+ enabled = ctl & CM_ENABLE;
+ if (enabled) {
+ /* disable clock */
+ cprman_write(cprman, data->ctl_reg, ctl);
+
+ /* release lock while busy waiting */
+ spin_unlock(&cprman->regs_lock);
+ bcm2835_clock_wait_busy(clock);
+ spin_lock(&cprman->regs_lock);
+
+ /* read the register again */
+ ctl = cprman_read(cprman, data->ctl_reg);
+ }
+
+ /* set the divider */
cprman_write(cprman, data->div_reg, div);
+ /* set frac/mash if necessarry */
+ mash = 0;
+ if ((data->frac_bits) && (div & GENMASK(CM_DIV_FRAC_BITS, 0)))
+ mash = (data->mash) ? data->mash : CM_MASH_FRAC;
+
+ /* set mash to the selected value */
+ ctl &= ~CM_MASH_MASK;
+ ctl |= mash & CM_MASH_MASK;
+ cprman_write(cprman, data->ctl_reg, ctl);
+
+ /* re-enable the clock */
+ if (enabled)
+ cprman_write(cprman, data->ctl_reg, ctl | CM_ENABLE);
+
+unlock:
+ spin_unlock(&cprman->regs_lock);
+
return 0;
}
--
1.7.10.4
next prev parent reply other threads:[~2016-01-11 19:55 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-11 19:55 [PATCH V2 0/4] clk: bcm2835: add additinal clocks and add frac support kernel
2016-01-11 19:55 ` [PATCH V2 1/4] clk: bcm2835: avoid the use of BCM2835_CLOCK_COUNT in clk-bcm2835 kernel
2016-01-13 20:00 ` Michael Turquette
2016-01-14 0:13 ` Michael Turquette
2016-01-14 12:11 ` Martin Sperl
2016-01-14 20:23 ` Michael Turquette
2016-01-14 21:24 ` Martin Sperl
2016-01-11 19:55 ` kernel [this message]
2016-01-13 20:07 ` [PATCH V2 2/4] clk: bcm2835: enable fractional and mash support Michael Turquette
2016-01-11 19:55 ` [PATCH V2 3/4] clk: bcm2835: enable management of PCM clock kernel
[not found] ` <1452542157-2387-4-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-13 20:11 ` Michael Turquette
2016-01-11 19:55 ` [PATCH V2 4/4] clk: bcm2835: add missing 22 HW-clocks kernel
[not found] ` <1452542157-2387-1-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-11 21:01 ` [PATCH V2 0/4] clk: bcm2835: add additinal clocks and add frac support Arnd Bergmann
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=1452542157-2387-3-git-send-email-kernel@martin.sperl.org \
--to=kernel@martin.sperl.org \
--cc=devicetree@vger.kernel.org \
--cc=eric@anholt.net \
--cc=lee@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-rpi-kernel@lists.infradead.org \
--cc=mturquette@baylibre.com \
--cc=repk@triplefau.lt \
--cc=sboyd@codeaurora.org \
--cc=swarren@wwwdotorg.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).