linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 00/20] add additional clocks and frac/mash support
@ 2016-02-28 15:36 kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 01/20] clk: bcm2835: pll_off should only set CM_PLL_ANARST kernel at martin.sperl.org
                   ` (19 more replies)
  0 siblings, 20 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Fix issues found with current driver with regards to:
* coding style
* locking
* setting register instead of bits in register
* the use of BCM2835_CLOCK_COUNT in the device tree bindings

adds:
* frac/mash support (with correct limits)
* exposing of additional clock parameters in debugfs
  (registers, divider and parent)
* added all the missing pll dividers
* almost all so far undefined clocks

Clocks still missing:
* gnric - Eric says that this is not really a clock
          (but it has corresponding registers set)
* tcnt - this seems to be more of a counter clock gate
         used for some other purpose - there are 4 CNT registers
* pllt - totally unidentified clock with a strange mux size of
         8 clocks (3 bit, not the typical 4 or 16 bit)

Lots of information here has been gathered from the broadcom
provided header files for the VC4 and some information has
been inferred.

I also hope that all the feedback so far has been included
in this patch-set.

Complete mash clock divider support has been left out for now.
We now only support the basic fractional divider option (MASH=1)
but with the corresponding divider limits that apply to mash clocks.

Some measurements on I2S-DACs show unexpected noise levels using
different mash levels, so that an automatic "best" selection does
not seem wise - this exercise is left for a later patch-set.

Changelog:
        V1 -> V2: split the asoc/sound patches from the clock patches
                  enable frac/mash support
        V2 -> V3: clamp clock divider to be >= 2
                  clamp max clock divider to be integer (not fractional)
                  added additional limit checks for divider selection
                    allowing fallback to lower mash levels.
                  use a newer probing mechanism based on a single array
        V3 -> V4: fixed bad NULL pointer check in init
                  fixed (mash) limit checks
                  separated basic mash support from limits checks
                  really tested with I2S device (unfortunately V3 was
                  not well tested in this respect)
        V4 -> V5: major reorganisation of patchset
	      	  including fixes for newly discovered bugs
		  split up clock commits into several chunks
		  separate clamping for mash enabled clocks
		  made better use of static assignment reducing
		    efforts to add a new clock - see specifically patch 7

Martin Sperl (20):
  clk: bcm2835: pll_off should only set CM_PLL_ANARST
  clk: bcm2835: clean up coding style issues
  clk: bcm2835: add locking to pll*_on/off methods
  clk: bcm2835: remove uart0/1_pclk fixed clocks
  clk: bcm2835: enable clocks that have been enabled by firmware
  clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in driver
  clk: bcm2835: reorganize bcm2835_clock_array assignment
  clk: bcm2835: add fractional support
  clk: bcm2835: enable management of PCM clock
  clk: bcm2835: implement correct clamping for mash clocks
  clk: bcm2835: divider value has to be 1 or more
  clk: bcm2835: expose raw clock-registers via debugfs
  clk: bcm2835: expose current divider, parent and mash via debugfs
  clk: bcm2835: added missing PLL clock divider
  clk: bcm2835: add additional clocks
  clk: bcm2835: add the camera related clocks cam0, cam1 and ccp2
  clk: bcm2835: add the dsi clocks
  clk: bcm2835: add arm clock
  clk: bcm2835: add gates that require PM_DEBUG to be set
  clk: bcm2835: add the testdebug clock generators

 drivers/clk/bcm/clk-bcm2835.c       | 1536 +++++++++++++++++++++++------------
 include/dt-bindings/clock/bcm2835.h |   31 +-
 2 files changed, 1061 insertions(+), 506 deletions(-)

--
1.7.10.4

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 01/20] clk: bcm2835: pll_off should only set CM_PLL_ANARST
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
@ 2016-02-28 15:36 ` kernel at martin.sperl.org
  2016-02-28 17:58   ` Stefan Wahren
  2016-02-28 15:36 ` [PATCH v5 02/20] clk: bcm2835: clean up coding style issues kernel at martin.sperl.org
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

bcm2835_pll_off is currently assigning CM_PLL_ANARST
to the control register.

This patch only sets the CM_PLL_ANARST bit
not resetting any of the other bits, which allows
restoring the register to its original value
via bcm2834_pll_on.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 5747a9d..d3009a6 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -913,8 +913,12 @@ static void bcm2835_pll_off(struct clk_hw *hw)
 	struct bcm2835_cprman *cprman = pll->cprman;
 	const struct bcm2835_pll_data *data = pll->data;
 
-	cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
-	cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
+	cprman_write(cprman, data->cm_ctrl_reg,
+		     cprman_read(cprman, data->cm_ctrl_reg) |
+		     CM_PLL_ANARST);
+	cprman_write(cprman, data->a2w_ctrl_reg,
+		     cprman_read(cprman, data->a2w_ctrl_reg) |
+		     A2W_PLL_CTRL_PWRDN);
 }
 
 static int bcm2835_pll_on(struct clk_hw *hw)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 02/20] clk: bcm2835: clean up coding style issues
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 01/20] clk: bcm2835: pll_off should only set CM_PLL_ANARST kernel at martin.sperl.org
@ 2016-02-28 15:36 ` kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 03/20] clk: bcm2835: add locking to pll*_on/off methods kernel at martin.sperl.org
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Fix all the checkpatch complaints for clk-bcm2835.c.
Specifically:
* indention
* missing spin lock comments
* multiple empty lines

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index d3009a6..3aa3e7a 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -12,9 +12,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */

 /**
@@ -297,7 +294,7 @@
 struct bcm2835_cprman {
 	struct device *dev;
 	void __iomem *regs;
-	spinlock_t regs_lock;
+	spinlock_t regs_lock; /* spinlock for all clocks */
 	const char *osc_name;

 	struct clk_onecell_data onecell;
@@ -325,12 +322,12 @@ void __init bcm2835_init_clocks(void)
 	int ret;

 	clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
-					126000000);
+				      126000000);
 	if (IS_ERR(clk))
 		pr_err("apb_pclk not registered\n");

 	clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
-					3000000);
+				      3000000);
 	if (IS_ERR(clk))
 		pr_err("uart0_pclk not registered\n");
 	ret = clk_register_clkdev(clk, NULL, "20201000.uart");
@@ -338,7 +335,7 @@ void __init bcm2835_init_clocks(void)
 		pr_err("uart0_pclk alias not registered\n");

 	clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
-					125000000);
+				      125000000);
 	if (IS_ERR(clk))
 		pr_err("uart1_pclk not registered\n");
 	ret = clk_register_clkdev(clk, NULL, "20215000.uart");
@@ -1291,7 +1288,7 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
 }

 static int bcm2835_clock_determine_rate(struct clk_hw *hw,
-		struct clk_rate_request *req)
+					struct clk_rate_request *req)
 {
 	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
 	struct clk_hw *parent, *best_parent = NULL;
@@ -1349,7 +1346,6 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw)
 	return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
 }

-
 static const struct clk_ops bcm2835_clock_clk_ops = {
 	.is_prepared = bcm2835_clock_is_on,
 	.prepare = bcm2835_clock_on,
--
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 03/20] clk: bcm2835: add locking to pll*_on/off methods
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 01/20] clk: bcm2835: pll_off should only set CM_PLL_ANARST kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 02/20] clk: bcm2835: clean up coding style issues kernel at martin.sperl.org
@ 2016-02-28 15:36 ` kernel at martin.sperl.org
  2016-02-28 18:04   ` Stefan Wahren
  2016-02-28 15:36 ` [PATCH v5 04/20] clk: bcm2835: remove uart0/1_pclk fixed clocks kernel at martin.sperl.org
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Add missing locking to:
* bcm2835_pll_on
* bcm2835_pll_off
* bcm2835_pll_divider_on

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 3aa3e7a..d999a13 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -910,12 +910,14 @@ static void bcm2835_pll_off(struct clk_hw *hw)
 	struct bcm2835_cprman *cprman = pll->cprman;
 	const struct bcm2835_pll_data *data = pll->data;

+	spin_lock(&cprman->regs_lock);
 	cprman_write(cprman, data->cm_ctrl_reg,
 		     cprman_read(cprman, data->cm_ctrl_reg) |
 		     CM_PLL_ANARST);
 	cprman_write(cprman, data->a2w_ctrl_reg,
 		     cprman_read(cprman, data->a2w_ctrl_reg) |
 		     A2W_PLL_CTRL_PWRDN);
+	spin_unlock(&cprman->regs_lock);
 }

 static int bcm2835_pll_on(struct clk_hw *hw)
@@ -1083,10 +1085,12 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw)
 	struct bcm2835_cprman *cprman = divider->cprman;
 	const struct bcm2835_pll_divider_data *data = divider->data;

+	spin_lock(&cprman->regs_lock);
 	cprman_write(cprman, data->cm_reg,
 		     (cprman_read(cprman, data->cm_reg) &
 		      ~data->load_mask) | data->hold_mask);
 	cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE);
+	spin_unlock(&cprman->regs_lock);
 }

 static int bcm2835_pll_divider_on(struct clk_hw *hw)
@@ -1095,12 +1099,14 @@ static int bcm2835_pll_divider_on(struct clk_hw *hw)
 	struct bcm2835_cprman *cprman = divider->cprman;
 	const struct bcm2835_pll_divider_data *data = divider->data;

+	spin_lock(&cprman->regs_lock);
 	cprman_write(cprman, data->a2w_reg,
 		     cprman_read(cprman, data->a2w_reg) &
 		     ~A2W_PLL_CHANNEL_DISABLE);

 	cprman_write(cprman, data->cm_reg,
 		     cprman_read(cprman, data->cm_reg) & ~data->hold_mask);
+	spin_unlock(&cprman->regs_lock);

 	return 0;
 }
--
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 04/20] clk: bcm2835: remove uart0/1_pclk fixed clocks
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (2 preceding siblings ...)
  2016-02-28 15:36 ` [PATCH v5 03/20] clk: bcm2835: add locking to pll*_on/off methods kernel at martin.sperl.org
@ 2016-02-28 15:36 ` kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 05/20] clk: bcm2835: enable clocks that have been enabled by firmware kernel at martin.sperl.org
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Remove the fixed clocks uart0_pclk and uart1_pclk.
These are not referred to anywhere and the corresponding
uart clock is created by default.

The uart1 clock is created by clk-bcm2835-aux.

Note that the use of apb_pclk is questionable and
not referred to anywhere.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |   17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index d999a13..c277ecb 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -319,28 +319,11 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg)
 void __init bcm2835_init_clocks(void)
 {
 	struct clk *clk;
-	int ret;
 
 	clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
 				      126000000);
 	if (IS_ERR(clk))
 		pr_err("apb_pclk not registered\n");
-
-	clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT,
-				      3000000);
-	if (IS_ERR(clk))
-		pr_err("uart0_pclk not registered\n");
-	ret = clk_register_clkdev(clk, NULL, "20201000.uart");
-	if (ret)
-		pr_err("uart0_pclk alias not registered\n");
-
-	clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT,
-				      125000000);
-	if (IS_ERR(clk))
-		pr_err("uart1_pclk not registered\n");
-	ret = clk_register_clkdev(clk, NULL, "20215000.uart");
-	if (ret)
-		pr_err("uart1_pclk alias not registered\n");
 }
 
 struct bcm2835_pll_data {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 05/20] clk: bcm2835: enable clocks that have been enabled by firmware
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (3 preceding siblings ...)
  2016-02-28 15:36 ` [PATCH v5 04/20] clk: bcm2835: remove uart0/1_pclk fixed clocks kernel at martin.sperl.org
@ 2016-02-28 15:36 ` kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 06/20] clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in driver kernel at martin.sperl.org
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

If a clock that has been enabled by the firmware gets disabled
by a driver this may right now result in a crash of the system
as then also the corresponding PLL_dividers as well as PLLs
get disabled (if not used) - some of which are used by the
VideoCore GPU (which also runs the firmware)

This patch prepares/enables those clocks that have been
configured by the firmware.

Whenever the clock framework implements either
CLK_IS_CRITICAL or HAND_OFF this can get changed to use this
new mechanism.

For this to be completely successful it is recommended to
add all the known clock so that this can get applied to all clocks.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index c277ecb..14ff81e 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -34,6 +34,7 @@
  * generator).
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clk/bcm2835.h>
@@ -1457,6 +1458,7 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
 	struct clk_init_data init;
 	const char *parents[1 << CM_SRC_BITS];
 	size_t i;
+	struct clk *clk;
 
 	/*
 	 * Replace our "xosc" references with the oscillator's
@@ -1490,7 +1492,18 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
 	clock->data = data;
 	clock->hw.init = &init;
 
-	return devm_clk_register(cprman->dev, &clock->hw);
+	clk = devm_clk_register(cprman->dev, &clock->hw);
+	if (IS_ERR_OR_NULL(clk))
+		return clk;
+
+	/* enable/prepare if the clock is enabled by the firmware */
+	if (cprman_read(cprman, data->ctl_reg) & CM_ENABLE) {
+		dev_info(cprman->dev,
+			 "found firmware enabled clock %pC\n", clk);
+		clk_prepare_enable(clk);
+	}
+
+	return clk;
 }
 
 static int bcm2835_clk_probe(struct platform_device *pdev)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 06/20] clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in driver
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (4 preceding siblings ...)
  2016-02-28 15:36 ` [PATCH v5 05/20] clk: bcm2835: enable clocks that have been enabled by firmware kernel at martin.sperl.org
@ 2016-02-28 15:36 ` kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 07/20] clk: bcm2835: reorganize bcm2835_clock_array assignment kernel at martin.sperl.org
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

As the use of BCM2835_CLOCK_COUNT in
include/dt-bindings/clock/bcm2835.h is frowned upon as
it needs to get modified every time a new clock gets introduced
this patch changes the clk-bcm2835 driver to use a different
scheme for registration of clocks and pll, so that there
is no more need for BCM2835_CLOCK_COUNT to be defined.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c       |  167 ++++++++++++++++++++---------------
 include/dt-bindings/clock/bcm2835.h |    2 -
 2 files changed, 94 insertions(+), 75 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 14ff81e..59219f9 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -299,7 +299,7 @@ struct bcm2835_cprman {
 	const char *osc_name;
 
 	struct clk_onecell_data onecell;
-	struct clk *clks[BCM2835_CLOCK_COUNT];
+	struct clk *clks[];
 };
 
 static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
@@ -811,6 +811,25 @@ static const struct bcm2835_clock_data bcm2835_clock_pwm_data = {
 	.frac_bits = 12,
 };
 
+struct bcm2835_gate_data {
+	const char *name;
+	const char *parent;
+
+	u32 ctl_reg;
+};
+
+/*
+ * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
+ * you have the debug bit set in the power manager, which we
+ * don't bother exposing) are individual gates off of the
+ * non-stop vpu clock.
+ */
+static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = {
+	.name = "peri_image",
+	.parent = "vpu",
+	.ctl_reg = CM_PERIICTL,
+};
+
 struct bcm2835_pll {
 	struct clk_hw hw;
 	struct bcm2835_cprman *cprman;
@@ -1506,14 +1525,81 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
 	return clk;
 }
 
+static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
+					 const struct bcm2835_gate_data *data)
+{
+	return clk_register_gate(cprman->dev, data->name, data->parent,
+				 CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
+				 cprman->regs + data->ctl_reg,
+				 CM_GATE_BIT, 0, &cprman->regs_lock);
+}
+
+typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
+					    const void *data);
+struct bcm2835_clk_desc {
+	bcm2835_clk_register clk_register;
+	const void *data;
+};
+
+#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \
+			  .data = d }
+#define REGISTER_PLL(d)		_REGISTER(&bcm2835_register_pll, d)
+#define REGISTER_PLL_DIV(d)	_REGISTER(&bcm2835_register_pll_divider, d)
+#define REGISTER_CLK(d)		_REGISTER(&bcm2835_register_clock, d)
+#define REGISTER_GATE(d)	_REGISTER(&bcm2835_register_gate, d)
+
+static const struct bcm2835_clk_desc clk_desc_array[] = {
+	/* register PLL */
+	[BCM2835_PLLA]		= REGISTER_PLL(&bcm2835_plla_data),
+	[BCM2835_PLLB]		= REGISTER_PLL(&bcm2835_pllb_data),
+	[BCM2835_PLLC]		= REGISTER_PLL(&bcm2835_pllc_data),
+	[BCM2835_PLLD]		= REGISTER_PLL(&bcm2835_plld_data),
+	[BCM2835_PLLH]		= REGISTER_PLL(&bcm2835_pllh_data),
+	/* the PLL dividers */
+	[BCM2835_PLLA_CORE]	= REGISTER_PLL_DIV(&bcm2835_plla_core_data),
+	[BCM2835_PLLA_PER]	= REGISTER_PLL_DIV(&bcm2835_plla_per_data),
+	[BCM2835_PLLC_CORE0]	= REGISTER_PLL_DIV(&bcm2835_pllc_core0_data),
+	[BCM2835_PLLC_CORE1]	= REGISTER_PLL_DIV(&bcm2835_pllc_core1_data),
+	[BCM2835_PLLC_CORE2]	= REGISTER_PLL_DIV(&bcm2835_pllc_core2_data),
+	[BCM2835_PLLC_PER]	= REGISTER_PLL_DIV(&bcm2835_pllc_per_data),
+	[BCM2835_PLLD_CORE]	= REGISTER_PLL_DIV(&bcm2835_plld_core_data),
+	[BCM2835_PLLD_PER]	= REGISTER_PLL_DIV(&bcm2835_plld_per_data),
+	[BCM2835_PLLH_RCAL]	= REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data),
+	[BCM2835_PLLH_AUX]	= REGISTER_PLL_DIV(&bcm2835_pllh_aux_data),
+	[BCM2835_PLLH_PIX]	= REGISTER_PLL_DIV(&bcm2835_pllh_pix_data),
+	/* the clocks */
+	[BCM2835_CLOCK_TIMER]	= REGISTER_CLK(&bcm2835_clock_timer_data),
+	[BCM2835_CLOCK_OTP]	= REGISTER_CLK(&bcm2835_clock_otp_data),
+	[BCM2835_CLOCK_TSENS]	= REGISTER_CLK(&bcm2835_clock_tsens_data),
+	[BCM2835_CLOCK_VPU]	= REGISTER_CLK(&bcm2835_clock_vpu_data),
+	[BCM2835_CLOCK_V3D]	= REGISTER_CLK(&bcm2835_clock_v3d_data),
+	[BCM2835_CLOCK_ISP]	= REGISTER_CLK(&bcm2835_clock_isp_data),
+	[BCM2835_CLOCK_H264]	= REGISTER_CLK(&bcm2835_clock_h264_data),
+	[BCM2835_CLOCK_V3D]	= REGISTER_CLK(&bcm2835_clock_v3d_data),
+	[BCM2835_CLOCK_SDRAM]	= REGISTER_CLK(&bcm2835_clock_sdram_data),
+	[BCM2835_CLOCK_UART]	= REGISTER_CLK(&bcm2835_clock_uart_data),
+	[BCM2835_CLOCK_VEC]	= REGISTER_CLK(&bcm2835_clock_vec_data),
+	[BCM2835_CLOCK_HSM]	= REGISTER_CLK(&bcm2835_clock_hsm_data),
+	[BCM2835_CLOCK_EMMC]	= REGISTER_CLK(&bcm2835_clock_emmc_data),
+	[BCM2835_CLOCK_PWM]	= REGISTER_CLK(&bcm2835_clock_pwm_data),
+	/* the gates */
+	[BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
+		&bcm2835_clock_peri_image_data),
+};
+
 static int bcm2835_clk_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct clk **clks;
 	struct bcm2835_cprman *cprman;
 	struct resource *res;
+	const struct bcm2835_clk_desc *desc;
+	const size_t asize = ARRAY_SIZE(clk_desc_array);
+	size_t i;
 
-	cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL);
+	cprman = devm_kzalloc(dev,
+			      sizeof(*cprman) + asize * sizeof(*clks),
+			      GFP_KERNEL);
 	if (!cprman)
 		return -ENOMEM;
 
@@ -1530,80 +1616,15 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, cprman);
 
-	cprman->onecell.clk_num = BCM2835_CLOCK_COUNT;
+	cprman->onecell.clk_num = asize;
 	cprman->onecell.clks = cprman->clks;
 	clks = cprman->clks;
 
-	clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data);
-	clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data);
-	clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data);
-	clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data);
-	clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data);
-
-	clks[BCM2835_PLLA_CORE] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data);
-	clks[BCM2835_PLLA_PER] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data);
-	clks[BCM2835_PLLC_CORE0] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data);
-	clks[BCM2835_PLLC_CORE1] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data);
-	clks[BCM2835_PLLC_CORE2] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data);
-	clks[BCM2835_PLLC_PER] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data);
-	clks[BCM2835_PLLD_CORE] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data);
-	clks[BCM2835_PLLD_PER] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data);
-	clks[BCM2835_PLLH_RCAL] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data);
-	clks[BCM2835_PLLH_AUX] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data);
-	clks[BCM2835_PLLH_PIX] =
-		bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data);
-
-	clks[BCM2835_CLOCK_TIMER] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_timer_data);
-	clks[BCM2835_CLOCK_OTP] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_otp_data);
-	clks[BCM2835_CLOCK_TSENS] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data);
-	clks[BCM2835_CLOCK_VPU] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data);
-	clks[BCM2835_CLOCK_V3D] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
-	clks[BCM2835_CLOCK_ISP] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_isp_data);
-	clks[BCM2835_CLOCK_H264] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_h264_data);
-	clks[BCM2835_CLOCK_V3D] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
-	clks[BCM2835_CLOCK_SDRAM] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data);
-	clks[BCM2835_CLOCK_UART] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_uart_data);
-	clks[BCM2835_CLOCK_VEC] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_vec_data);
-	clks[BCM2835_CLOCK_HSM] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data);
-	clks[BCM2835_CLOCK_EMMC] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data);
-
-	/*
-	 * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
-	 * you have the debug bit set in the power manager, which we
-	 * don't bother exposing) are individual gates off of the
-	 * non-stop vpu clock.
-	 */
-	clks[BCM2835_CLOCK_PERI_IMAGE] =
-		clk_register_gate(dev, "peri_image", "vpu",
-				  CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
-				  cprman->regs + CM_PERIICTL, CM_GATE_BIT,
-				  0, &cprman->regs_lock);
-
-	clks[BCM2835_CLOCK_PWM] =
-		bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data);
+	for (i = 0; i < asize; i++) {
+		desc = &clk_desc_array[i];
+		if (desc->clk_register && desc->data)
+			clks[i] = desc->clk_register(cprman, desc->data);
+	}
 
 	return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
 				   &cprman->onecell);
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 61f1d20..87235ac 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -44,5 +44,3 @@
 #define BCM2835_CLOCK_EMMC		28
 #define BCM2835_CLOCK_PERI_IMAGE	29
 #define BCM2835_CLOCK_PWM		30
-
-#define BCM2835_CLOCK_COUNT		31
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 07/20] clk: bcm2835: reorganize bcm2835_clock_array assignment
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (5 preceding siblings ...)
  2016-02-28 15:36 ` [PATCH v5 06/20] clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in driver kernel at martin.sperl.org
@ 2016-02-28 15:36 ` kernel at martin.sperl.org
  2016-02-28 15:36 ` [PATCH v5 08/20] clk: bcm2835: add fractional support kernel at martin.sperl.org
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Reorganize bcm2835_clock_array so that there is no more
need for separate bcm2835_*_data structures to be defined.
Instead the required structures are generated inline via
helper macros.

To allow this to also work for pll alone it was required that
the parent_pll was changed from a pointer to bcm2835_pll_data
to the name of the pll instead.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |  849 +++++++++++++++++++----------------------
 1 file changed, 392 insertions(+), 457 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 59219f9..144d5d5 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -378,115 +378,10 @@ static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = {
 	.fb_prediv_mask = BIT(11),
 };
 
-/*
- * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera
- * Port 2) transmitter clock.
- *
- * It is in the PX LDO power domain, which is on when the AUDIO domain
- * is on.
- */
-static const struct bcm2835_pll_data bcm2835_plla_data = {
-	.name = "plla",
-	.cm_ctrl_reg = CM_PLLA,
-	.a2w_ctrl_reg = A2W_PLLA_CTRL,
-	.frac_reg = A2W_PLLA_FRAC,
-	.ana_reg_base = A2W_PLLA_ANA0,
-	.reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
-	.lock_mask = CM_LOCK_FLOCKA,
-
-	.ana = &bcm2835_ana_default,
-
-	.min_rate = 600000000u,
-	.max_rate = 2400000000u,
-	.max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
-/* PLLB is used for the ARM's clock. */
-static const struct bcm2835_pll_data bcm2835_pllb_data = {
-	.name = "pllb",
-	.cm_ctrl_reg = CM_PLLB,
-	.a2w_ctrl_reg = A2W_PLLB_CTRL,
-	.frac_reg = A2W_PLLB_FRAC,
-	.ana_reg_base = A2W_PLLB_ANA0,
-	.reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
-	.lock_mask = CM_LOCK_FLOCKB,
-
-	.ana = &bcm2835_ana_default,
-
-	.min_rate = 600000000u,
-	.max_rate = 3000000000u,
-	.max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
-/*
- * PLLC is the core PLL, used to drive the core VPU clock.
- *
- * It is in the PX LDO power domain, which is on when the AUDIO domain
- * is on.
-*/
-static const struct bcm2835_pll_data bcm2835_pllc_data = {
-	.name = "pllc",
-	.cm_ctrl_reg = CM_PLLC,
-	.a2w_ctrl_reg = A2W_PLLC_CTRL,
-	.frac_reg = A2W_PLLC_FRAC,
-	.ana_reg_base = A2W_PLLC_ANA0,
-	.reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
-	.lock_mask = CM_LOCK_FLOCKC,
-
-	.ana = &bcm2835_ana_default,
-
-	.min_rate = 600000000u,
-	.max_rate = 3000000000u,
-	.max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
-/*
- * PLLD is the display PLL, used to drive DSI display panels.
- *
- * It is in the PX LDO power domain, which is on when the AUDIO domain
- * is on.
- */
-static const struct bcm2835_pll_data bcm2835_plld_data = {
-	.name = "plld",
-	.cm_ctrl_reg = CM_PLLD,
-	.a2w_ctrl_reg = A2W_PLLD_CTRL,
-	.frac_reg = A2W_PLLD_FRAC,
-	.ana_reg_base = A2W_PLLD_ANA0,
-	.reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
-	.lock_mask = CM_LOCK_FLOCKD,
-
-	.ana = &bcm2835_ana_default,
-
-	.min_rate = 600000000u,
-	.max_rate = 2400000000u,
-	.max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
-/*
- * PLLH is used to supply the pixel clock or the AUX clock for the TV
- * encoder.
- *
- * It is in the HDMI power domain.
- */
-static const struct bcm2835_pll_data bcm2835_pllh_data = {
-	"pllh",
-	.cm_ctrl_reg = CM_PLLH,
-	.a2w_ctrl_reg = A2W_PLLH_CTRL,
-	.frac_reg = A2W_PLLH_FRAC,
-	.ana_reg_base = A2W_PLLH_ANA0,
-	.reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
-	.lock_mask = CM_LOCK_FLOCKH,
-
-	.ana = &bcm2835_ana_pllh,
-
-	.min_rate = 600000000u,
-	.max_rate = 3000000000u,
-	.max_fb_rate = BCM2835_MAX_FB_RATE,
-};
-
 struct bcm2835_pll_divider_data {
 	const char *name;
-	const struct bcm2835_pll_data *source_pll;
+	const char *source_pll;
+
 	u32 cm_reg;
 	u32 a2w_reg;
 
@@ -495,123 +390,6 @@ struct bcm2835_pll_divider_data {
 	u32 fixed_divider;
 };
 
-static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = {
-	.name = "plla_core",
-	.source_pll = &bcm2835_plla_data,
-	.cm_reg = CM_PLLA,
-	.a2w_reg = A2W_PLLA_CORE,
-	.load_mask = CM_PLLA_LOADCORE,
-	.hold_mask = CM_PLLA_HOLDCORE,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = {
-	.name = "plla_per",
-	.source_pll = &bcm2835_plla_data,
-	.cm_reg = CM_PLLA,
-	.a2w_reg = A2W_PLLA_PER,
-	.load_mask = CM_PLLA_LOADPER,
-	.hold_mask = CM_PLLA_HOLDPER,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = {
-	.name = "pllb_arm",
-	.source_pll = &bcm2835_pllb_data,
-	.cm_reg = CM_PLLB,
-	.a2w_reg = A2W_PLLB_ARM,
-	.load_mask = CM_PLLB_LOADARM,
-	.hold_mask = CM_PLLB_HOLDARM,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = {
-	.name = "pllc_core0",
-	.source_pll = &bcm2835_pllc_data,
-	.cm_reg = CM_PLLC,
-	.a2w_reg = A2W_PLLC_CORE0,
-	.load_mask = CM_PLLC_LOADCORE0,
-	.hold_mask = CM_PLLC_HOLDCORE0,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = {
-	.name = "pllc_core1", .source_pll = &bcm2835_pllc_data,
-	.cm_reg = CM_PLLC, A2W_PLLC_CORE1,
-	.load_mask = CM_PLLC_LOADCORE1,
-	.hold_mask = CM_PLLC_HOLDCORE1,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = {
-	.name = "pllc_core2",
-	.source_pll = &bcm2835_pllc_data,
-	.cm_reg = CM_PLLC,
-	.a2w_reg = A2W_PLLC_CORE2,
-	.load_mask = CM_PLLC_LOADCORE2,
-	.hold_mask = CM_PLLC_HOLDCORE2,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = {
-	.name = "pllc_per",
-	.source_pll = &bcm2835_pllc_data,
-	.cm_reg = CM_PLLC,
-	.a2w_reg = A2W_PLLC_PER,
-	.load_mask = CM_PLLC_LOADPER,
-	.hold_mask = CM_PLLC_HOLDPER,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = {
-	.name = "plld_core",
-	.source_pll = &bcm2835_plld_data,
-	.cm_reg = CM_PLLD,
-	.a2w_reg = A2W_PLLD_CORE,
-	.load_mask = CM_PLLD_LOADCORE,
-	.hold_mask = CM_PLLD_HOLDCORE,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = {
-	.name = "plld_per",
-	.source_pll = &bcm2835_plld_data,
-	.cm_reg = CM_PLLD,
-	.a2w_reg = A2W_PLLD_PER,
-	.load_mask = CM_PLLD_LOADPER,
-	.hold_mask = CM_PLLD_HOLDPER,
-	.fixed_divider = 1,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = {
-	.name = "pllh_rcal",
-	.source_pll = &bcm2835_pllh_data,
-	.cm_reg = CM_PLLH,
-	.a2w_reg = A2W_PLLH_RCAL,
-	.load_mask = CM_PLLH_LOADRCAL,
-	.hold_mask = 0,
-	.fixed_divider = 10,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = {
-	.name = "pllh_aux",
-	.source_pll = &bcm2835_pllh_data,
-	.cm_reg = CM_PLLH,
-	.a2w_reg = A2W_PLLH_AUX,
-	.load_mask = CM_PLLH_LOADAUX,
-	.hold_mask = 0,
-	.fixed_divider = 10,
-};
-
-static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = {
-	.name = "pllh_pix",
-	.source_pll = &bcm2835_pllh_data,
-	.cm_reg = CM_PLLH,
-	.a2w_reg = A2W_PLLH_PIX,
-	.load_mask = CM_PLLH_LOADPIX,
-	.hold_mask = 0,
-	.fixed_divider = 10,
-};
 
 struct bcm2835_clock_data {
 	const char *name;
@@ -630,187 +408,6 @@ struct bcm2835_clock_data {
 	bool is_vpu_clock;
 };
 
-static const char *const bcm2835_clock_per_parents[] = {
-	"gnd",
-	"xosc",
-	"testdebug0",
-	"testdebug1",
-	"plla_per",
-	"pllc_per",
-	"plld_per",
-	"pllh_aux",
-};
-
-static const char *const bcm2835_clock_vpu_parents[] = {
-	"gnd",
-	"xosc",
-	"testdebug0",
-	"testdebug1",
-	"plla_core",
-	"pllc_core0",
-	"plld_core",
-	"pllh_aux",
-	"pllc_core1",
-	"pllc_core2",
-};
-
-static const char *const bcm2835_clock_osc_parents[] = {
-	"gnd",
-	"xosc",
-	"testdebug0",
-	"testdebug1"
-};
-
-/*
- * Used for a 1Mhz clock for the system clocksource, and also used by
- * the watchdog timer and the camera pulse generator.
- */
-static const struct bcm2835_clock_data bcm2835_clock_timer_data = {
-	.name = "timer",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
-	.parents = bcm2835_clock_osc_parents,
-	.ctl_reg = CM_TIMERCTL,
-	.div_reg = CM_TIMERDIV,
-	.int_bits = 6,
-	.frac_bits = 12,
-};
-
-/* One Time Programmable Memory clock.  Maximum 10Mhz. */
-static const struct bcm2835_clock_data bcm2835_clock_otp_data = {
-	.name = "otp",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
-	.parents = bcm2835_clock_osc_parents,
-	.ctl_reg = CM_OTPCTL,
-	.div_reg = CM_OTPDIV,
-	.int_bits = 4,
-	.frac_bits = 0,
-};
-
-/*
- * VPU clock.  This doesn't have an enable bit, since it drives the
- * bus for everything else, and is special so it doesn't need to be
- * gated for rate changes.  It is also known as "clk_audio" in various
- * hardware documentation.
- */
-static const struct bcm2835_clock_data bcm2835_clock_vpu_data = {
-	.name = "vpu",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-	.parents = bcm2835_clock_vpu_parents,
-	.ctl_reg = CM_VPUCTL,
-	.div_reg = CM_VPUDIV,
-	.int_bits = 12,
-	.frac_bits = 8,
-	.is_vpu_clock = true,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_v3d_data = {
-	.name = "v3d",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-	.parents = bcm2835_clock_vpu_parents,
-	.ctl_reg = CM_V3DCTL,
-	.div_reg = CM_V3DDIV,
-	.int_bits = 4,
-	.frac_bits = 8,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_isp_data = {
-	.name = "isp",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-	.parents = bcm2835_clock_vpu_parents,
-	.ctl_reg = CM_ISPCTL,
-	.div_reg = CM_ISPDIV,
-	.int_bits = 4,
-	.frac_bits = 8,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_h264_data = {
-	.name = "h264",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-	.parents = bcm2835_clock_vpu_parents,
-	.ctl_reg = CM_H264CTL,
-	.div_reg = CM_H264DIV,
-	.int_bits = 4,
-	.frac_bits = 8,
-};
-
-/* TV encoder clock.  Only operating frequency is 108Mhz.  */
-static const struct bcm2835_clock_data bcm2835_clock_vec_data = {
-	.name = "vec",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-	.parents = bcm2835_clock_per_parents,
-	.ctl_reg = CM_VECCTL,
-	.div_reg = CM_VECDIV,
-	.int_bits = 4,
-	.frac_bits = 0,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_uart_data = {
-	.name = "uart",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-	.parents = bcm2835_clock_per_parents,
-	.ctl_reg = CM_UARTCTL,
-	.div_reg = CM_UARTDIV,
-	.int_bits = 10,
-	.frac_bits = 12,
-};
-
-/* HDMI state machine */
-static const struct bcm2835_clock_data bcm2835_clock_hsm_data = {
-	.name = "hsm",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-	.parents = bcm2835_clock_per_parents,
-	.ctl_reg = CM_HSMCTL,
-	.div_reg = CM_HSMDIV,
-	.int_bits = 4,
-	.frac_bits = 8,
-};
-
-/*
- * Secondary SDRAM clock.  Used for low-voltage modes when the PLL in
- * the SDRAM controller can't be used.
- */
-static const struct bcm2835_clock_data bcm2835_clock_sdram_data = {
-	.name = "sdram",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),
-	.parents = bcm2835_clock_vpu_parents,
-	.ctl_reg = CM_SDCCTL,
-	.div_reg = CM_SDCDIV,
-	.int_bits = 6,
-	.frac_bits = 0,
-};
-
-/* Clock for the temperature sensor.  Generally run at 2Mhz, max 5Mhz. */
-static const struct bcm2835_clock_data bcm2835_clock_tsens_data = {
-	.name = "tsens",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),
-	.parents = bcm2835_clock_osc_parents,
-	.ctl_reg = CM_TSENSCTL,
-	.div_reg = CM_TSENSDIV,
-	.int_bits = 5,
-	.frac_bits = 0,
-};
-
-/* Arasan EMMC clock */
-static const struct bcm2835_clock_data bcm2835_clock_emmc_data = {
-	.name = "emmc",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-	.parents = bcm2835_clock_per_parents,
-	.ctl_reg = CM_EMMCCTL,
-	.div_reg = CM_EMMCDIV,
-	.int_bits = 4,
-	.frac_bits = 8,
-};
-
-static const struct bcm2835_clock_data bcm2835_clock_pwm_data = {
-	.name = "pwm",
-	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),
-	.parents = bcm2835_clock_per_parents,
-	.ctl_reg = CM_PWMCTL,
-	.div_reg = CM_PWMDIV,
-	.int_bits = 12,
-	.frac_bits = 12,
-};
-
 struct bcm2835_gate_data {
 	const char *name;
 	const char *parent;
@@ -818,18 +415,6 @@ struct bcm2835_gate_data {
 	u32 ctl_reg;
 };
 
-/*
- * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
- * you have the debug bit set in the power manager, which we
- * don't bother exposing) are individual gates off of the
- * non-stop vpu clock.
- */
-static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = {
-	.name = "peri_image",
-	.parent = "vpu",
-	.ctl_reg = CM_PERIICTL,
-};
-
 struct bcm2835_pll {
 	struct clk_hw hw;
 	struct bcm2835_cprman *cprman;
@@ -1430,7 +1015,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
 
 	memset(&init, 0, sizeof(init));
 
-	init.parent_names = &data->source_pll->name;
+	init.parent_names = &data->source_pll;
 	init.num_parents = 1;
 	init.name = divider_name;
 	init.ops = &bcm2835_pll_divider_clk_ops;
@@ -1541,50 +1126,400 @@ struct bcm2835_clk_desc {
 	const void *data;
 };
 
-#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \
-			  .data = d }
-#define REGISTER_PLL(d)		_REGISTER(&bcm2835_register_pll, d)
-#define REGISTER_PLL_DIV(d)	_REGISTER(&bcm2835_register_pll_divider, d)
-#define REGISTER_CLK(d)		_REGISTER(&bcm2835_register_clock, d)
-#define REGISTER_GATE(d)	_REGISTER(&bcm2835_register_gate, d)
+/* assignment helper macros for different clock types */
+#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \
+			    .data = __VA_ARGS__ }
+#define REGISTER_PLL(...)	_REGISTER(&bcm2835_register_pll,	\
+					  &(struct bcm2835_pll_data)	\
+					  {__VA_ARGS__})
+#define REGISTER_PLL_DIV(...)	_REGISTER(&bcm2835_register_pll_divider, \
+					  &(struct bcm2835_pll_divider_data) \
+					  {__VA_ARGS__})
+#define REGISTER_CLK(...)	_REGISTER(&bcm2835_register_clock,	\
+					  &(struct bcm2835_clock_data)	\
+					  {__VA_ARGS__})
+#define REGISTER_GATE(...)	_REGISTER(&bcm2835_register_gate,	\
+					  &(struct bcm2835_gate_data)	\
+					  {__VA_ARGS__})
+
+/* parent mux arrays plus helper macros */
+
+/* main oscillator parent mux */
+static const char *const bcm2835_clock_osc_parents[] = {
+	"gnd",
+	"xosc",
+	"testdebug0",
+	"testdebug1"
+};
+
+#define REGISTER_OSC_CLK(...)	REGISTER_CLK(				\
+	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),	\
+	.parents = bcm2835_clock_osc_parents,				\
+	__VA_ARGS__)
+
+/* main peripherial parent mux */
+static const char *const bcm2835_clock_per_parents[] = {
+	"gnd",
+	"xosc",
+	"testdebug0",
+	"testdebug1",
+	"plla_per",
+	"pllc_per",
+	"plld_per",
+	"pllh_aux",
+};
+
+#define REGISTER_PER_CLK(...)	REGISTER_CLK(				\
+	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),	\
+	.parents = bcm2835_clock_per_parents,				\
+	__VA_ARGS__)
 
+/* main vpu parent mux */
+static const char *const bcm2835_clock_vpu_parents[] = {
+	"gnd",
+	"xosc",
+	"testdebug0",
+	"testdebug1",
+	"plla_core",
+	"pllc_core0",
+	"plld_core",
+	"pllh_aux",
+	"pllc_core1",
+	"pllc_core2",
+};
+
+#define REGISTER_VPU_CLK(...)	REGISTER_CLK(				\
+	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),	\
+	.parents = bcm2835_clock_vpu_parents,				\
+	__VA_ARGS__)
+
+/*
+ * the real definition of all the pll, pll_dividers and clocks
+ * these make use of the above REGISTER_* macros
+ */
 static const struct bcm2835_clk_desc clk_desc_array[] = {
-	/* register PLL */
-	[BCM2835_PLLA]		= REGISTER_PLL(&bcm2835_plla_data),
-	[BCM2835_PLLB]		= REGISTER_PLL(&bcm2835_pllb_data),
-	[BCM2835_PLLC]		= REGISTER_PLL(&bcm2835_pllc_data),
-	[BCM2835_PLLD]		= REGISTER_PLL(&bcm2835_plld_data),
-	[BCM2835_PLLH]		= REGISTER_PLL(&bcm2835_pllh_data),
-	/* the PLL dividers */
-	[BCM2835_PLLA_CORE]	= REGISTER_PLL_DIV(&bcm2835_plla_core_data),
-	[BCM2835_PLLA_PER]	= REGISTER_PLL_DIV(&bcm2835_plla_per_data),
-	[BCM2835_PLLC_CORE0]	= REGISTER_PLL_DIV(&bcm2835_pllc_core0_data),
-	[BCM2835_PLLC_CORE1]	= REGISTER_PLL_DIV(&bcm2835_pllc_core1_data),
-	[BCM2835_PLLC_CORE2]	= REGISTER_PLL_DIV(&bcm2835_pllc_core2_data),
-	[BCM2835_PLLC_PER]	= REGISTER_PLL_DIV(&bcm2835_pllc_per_data),
-	[BCM2835_PLLD_CORE]	= REGISTER_PLL_DIV(&bcm2835_plld_core_data),
-	[BCM2835_PLLD_PER]	= REGISTER_PLL_DIV(&bcm2835_plld_per_data),
-	[BCM2835_PLLH_RCAL]	= REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data),
-	[BCM2835_PLLH_AUX]	= REGISTER_PLL_DIV(&bcm2835_pllh_aux_data),
-	[BCM2835_PLLH_PIX]	= REGISTER_PLL_DIV(&bcm2835_pllh_pix_data),
+	/* the PLL + PLL dividers */
+
+	/*
+	 * PLLA is the auxiliary PLL, used to drive the CCP2
+	 * (Compact Camera Port 2) transmitter clock.
+	 *
+	 * It is in the PX LDO power domain, which is on when the
+	 * AUDIO domain is on.
+	 */
+	[BCM2835_PLLA]		= REGISTER_PLL(
+		.name = "plla",
+		.cm_ctrl_reg = CM_PLLA,
+		.a2w_ctrl_reg = A2W_PLLA_CTRL,
+		.frac_reg = A2W_PLLA_FRAC,
+		.ana_reg_base = A2W_PLLA_ANA0,
+		.reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE,
+		.lock_mask = CM_LOCK_FLOCKA,
+
+		.ana = &bcm2835_ana_default,
+
+		.min_rate = 600000000u,
+		.max_rate = 2400000000u,
+		.max_fb_rate = BCM2835_MAX_FB_RATE),
+	[BCM2835_PLLA_CORE]	= REGISTER_PLL_DIV(
+		.name = "plla_core",
+		.source_pll = "plla",
+		.cm_reg = CM_PLLA,
+		.a2w_reg = A2W_PLLA_CORE,
+		.load_mask = CM_PLLA_LOADCORE,
+		.hold_mask = CM_PLLA_HOLDCORE,
+		.fixed_divider = 1),
+	[BCM2835_PLLA_PER]	= REGISTER_PLL_DIV(
+		.name = "plla_per",
+		.source_pll = "plla",
+		.cm_reg = CM_PLLA,
+		.a2w_reg = A2W_PLLA_PER,
+		.load_mask = CM_PLLA_LOADPER,
+		.hold_mask = CM_PLLA_HOLDPER,
+		.fixed_divider = 1),
+
+	/* PLLB is used for the ARM's clock. */
+	[BCM2835_PLLB]		= REGISTER_PLL(
+		.name = "pllb",
+		.cm_ctrl_reg = CM_PLLB,
+		.a2w_ctrl_reg = A2W_PLLB_CTRL,
+		.frac_reg = A2W_PLLB_FRAC,
+		.ana_reg_base = A2W_PLLB_ANA0,
+		.reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE,
+		.lock_mask = CM_LOCK_FLOCKB,
+
+		.ana = &bcm2835_ana_default,
+
+		.min_rate = 600000000u,
+		.max_rate = 3000000000u,
+		.max_fb_rate = BCM2835_MAX_FB_RATE),
+	[BCM2835_PLLB_ARM]	= REGISTER_PLL_DIV(
+		.name = "pllb_arm",
+		.source_pll = "pllb",
+		.cm_reg = CM_PLLB,
+		.a2w_reg = A2W_PLLB_ARM,
+		.load_mask = CM_PLLB_LOADARM,
+		.hold_mask = CM_PLLB_HOLDARM,
+		.fixed_divider = 1),
+
+	/*
+	 * PLLC is the core PLL, used to drive the core VPU clock.
+	 *
+	 * It is in the PX LDO power domain, which is on when the
+	 * AUDIO domain is on.
+	 */
+	[BCM2835_PLLC]		= REGISTER_PLL(
+		.name = "pllc",
+		.cm_ctrl_reg = CM_PLLC,
+		.a2w_ctrl_reg = A2W_PLLC_CTRL,
+		.frac_reg = A2W_PLLC_FRAC,
+		.ana_reg_base = A2W_PLLC_ANA0,
+		.reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+		.lock_mask = CM_LOCK_FLOCKC,
+
+		.ana = &bcm2835_ana_default,
+
+		.min_rate = 600000000u,
+		.max_rate = 3000000000u,
+		.max_fb_rate = BCM2835_MAX_FB_RATE),
+	[BCM2835_PLLC_CORE0]	= REGISTER_PLL_DIV(
+		.name = "pllc_core0",
+		.source_pll = "pllc",
+		.cm_reg = CM_PLLC,
+		.a2w_reg = A2W_PLLC_CORE0,
+		.load_mask = CM_PLLC_LOADCORE0,
+		.hold_mask = CM_PLLC_HOLDCORE0,
+		.fixed_divider = 1),
+	[BCM2835_PLLC_CORE1]	= REGISTER_PLL_DIV(
+		.name = "pllc_core1",
+		.source_pll = "pllc",
+		.cm_reg = CM_PLLC,
+		.a2w_reg = A2W_PLLC_CORE1,
+		.load_mask = CM_PLLC_LOADCORE1,
+		.hold_mask = CM_PLLC_HOLDCORE1,
+		.fixed_divider = 1),
+	[BCM2835_PLLC_CORE2]	= REGISTER_PLL_DIV(
+		.name = "pllc_core2",
+		.source_pll = "pllc",
+		.cm_reg = CM_PLLC,
+		.a2w_reg = A2W_PLLC_CORE2,
+		.load_mask = CM_PLLC_LOADCORE2,
+		.hold_mask = CM_PLLC_HOLDCORE2,
+		.fixed_divider = 1),
+	[BCM2835_PLLC_PER]	= REGISTER_PLL_DIV(
+		.name = "pllc_per",
+		.source_pll = "pllc",
+		.cm_reg = CM_PLLC,
+		.a2w_reg = A2W_PLLC_PER,
+		.load_mask = CM_PLLC_LOADPER,
+		.hold_mask = CM_PLLC_HOLDPER,
+		.fixed_divider = 1),
+
+	/*
+	 * PLLD is the display PLL, used to drive DSI display panels.
+	 *
+	 * It is in the PX LDO power domain, which is on when the
+	 * AUDIO domain is on.
+	 */
+	[BCM2835_PLLD]		= REGISTER_PLL(
+		.name = "plld",
+		.cm_ctrl_reg = CM_PLLD,
+		.a2w_ctrl_reg = A2W_PLLD_CTRL,
+		.frac_reg = A2W_PLLD_FRAC,
+		.ana_reg_base = A2W_PLLD_ANA0,
+		.reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE,
+		.lock_mask = CM_LOCK_FLOCKD,
+
+		.ana = &bcm2835_ana_default,
+
+		.min_rate = 600000000u,
+		.max_rate = 2400000000u,
+		.max_fb_rate = BCM2835_MAX_FB_RATE),
+	[BCM2835_PLLD_CORE]	= REGISTER_PLL_DIV(
+		.name = "plld_core",
+		.source_pll = "plld",
+		.cm_reg = CM_PLLD,
+		.a2w_reg = A2W_PLLD_CORE,
+		.load_mask = CM_PLLD_LOADCORE,
+		.hold_mask = CM_PLLD_HOLDCORE,
+		.fixed_divider = 1),
+	[BCM2835_PLLD_PER]	= REGISTER_PLL_DIV(
+		.name = "plld_per",
+		.source_pll = "plld",
+		.cm_reg = CM_PLLD,
+		.a2w_reg = A2W_PLLD_PER,
+		.load_mask = CM_PLLD_LOADPER,
+		.hold_mask = CM_PLLD_HOLDPER,
+		.fixed_divider = 1),
+
+	/*
+	 * PLLH is used to supply the pixel clock or the AUX clock for the
+	 * TV encoder.
+	 *
+	 * It is in the HDMI power domain.
+	 */
+	[BCM2835_PLLH]		= REGISTER_PLL(
+		"pllh",
+		.cm_ctrl_reg = CM_PLLH,
+		.a2w_ctrl_reg = A2W_PLLH_CTRL,
+		.frac_reg = A2W_PLLH_FRAC,
+		.ana_reg_base = A2W_PLLH_ANA0,
+		.reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE,
+		.lock_mask = CM_LOCK_FLOCKH,
+
+		.ana = &bcm2835_ana_pllh,
+
+		.min_rate = 600000000u,
+		.max_rate = 3000000000u,
+		.max_fb_rate = BCM2835_MAX_FB_RATE),
+	[BCM2835_PLLH_RCAL]	= REGISTER_PLL_DIV(
+		.name = "pllh_rcal",
+		.source_pll = "pllh",
+		.cm_reg = CM_PLLH,
+		.a2w_reg = A2W_PLLH_RCAL,
+		.load_mask = CM_PLLH_LOADRCAL,
+		.hold_mask = 0,
+		.fixed_divider = 10),
+	[BCM2835_PLLH_AUX]	= REGISTER_PLL_DIV(
+		.name = "pllh_aux",
+		.source_pll = "pllh",
+		.cm_reg = CM_PLLH,
+		.a2w_reg = A2W_PLLH_AUX,
+		.load_mask = CM_PLLH_LOADAUX,
+		.hold_mask = 0,
+		.fixed_divider = 10),
+	[BCM2835_PLLH_PIX]	= REGISTER_PLL_DIV(
+		.name = "pllh_pix",
+		.source_pll = "pllh",
+		.cm_reg = CM_PLLH,
+		.a2w_reg = A2W_PLLH_PIX,
+		.load_mask = CM_PLLH_LOADPIX,
+		.hold_mask = 0,
+		.fixed_divider = 10),
+
 	/* the clocks */
-	[BCM2835_CLOCK_TIMER]	= REGISTER_CLK(&bcm2835_clock_timer_data),
-	[BCM2835_CLOCK_OTP]	= REGISTER_CLK(&bcm2835_clock_otp_data),
-	[BCM2835_CLOCK_TSENS]	= REGISTER_CLK(&bcm2835_clock_tsens_data),
-	[BCM2835_CLOCK_VPU]	= REGISTER_CLK(&bcm2835_clock_vpu_data),
-	[BCM2835_CLOCK_V3D]	= REGISTER_CLK(&bcm2835_clock_v3d_data),
-	[BCM2835_CLOCK_ISP]	= REGISTER_CLK(&bcm2835_clock_isp_data),
-	[BCM2835_CLOCK_H264]	= REGISTER_CLK(&bcm2835_clock_h264_data),
-	[BCM2835_CLOCK_V3D]	= REGISTER_CLK(&bcm2835_clock_v3d_data),
-	[BCM2835_CLOCK_SDRAM]	= REGISTER_CLK(&bcm2835_clock_sdram_data),
-	[BCM2835_CLOCK_UART]	= REGISTER_CLK(&bcm2835_clock_uart_data),
-	[BCM2835_CLOCK_VEC]	= REGISTER_CLK(&bcm2835_clock_vec_data),
-	[BCM2835_CLOCK_HSM]	= REGISTER_CLK(&bcm2835_clock_hsm_data),
-	[BCM2835_CLOCK_EMMC]	= REGISTER_CLK(&bcm2835_clock_emmc_data),
-	[BCM2835_CLOCK_PWM]	= REGISTER_CLK(&bcm2835_clock_pwm_data),
+
+	/* clocks with oscillator parent mux */
+
+	/* One Time Programmable Memory clock.  Maximum 10Mhz. */
+	[BCM2835_CLOCK_OTP]	= REGISTER_OSC_CLK(
+		.name = "otp",
+		.ctl_reg = CM_OTPCTL,
+		.div_reg = CM_OTPDIV,
+		.int_bits = 4,
+		.frac_bits = 0),
+	/*
+	 * Used for a 1Mhz clock for the system clocksource, and also used
+	 * bythe watchdog timer and the camera pulse generator.
+	 */
+	[BCM2835_CLOCK_TIMER]	= REGISTER_OSC_CLK(
+		.name = "timer",
+		.ctl_reg = CM_TIMERCTL,
+		.div_reg = CM_TIMERDIV,
+		.int_bits = 6,
+		.frac_bits = 12),
+	/*
+	 * Clock for the temperature sensor.
+	 * Generally run at 2Mhz, max 5Mhz.
+	 */
+	[BCM2835_CLOCK_TSENS]	= REGISTER_OSC_CLK(
+		.name = "tsens",
+		.ctl_reg = CM_TSENSCTL,
+		.div_reg = CM_TSENSDIV,
+		.int_bits = 5,
+		.frac_bits = 0),
+
+	/* clocks with vpu parent mux */
+	[BCM2835_CLOCK_H264]	= REGISTER_VPU_CLK(
+		.name = "h264",
+		.ctl_reg = CM_H264CTL,
+		.div_reg = CM_H264DIV,
+		.int_bits = 4,
+		.frac_bits = 8),
+	[BCM2835_CLOCK_ISP]	= REGISTER_VPU_CLK(
+		.name = "isp",
+		.ctl_reg = CM_ISPCTL,
+		.div_reg = CM_ISPDIV,
+		.int_bits = 4,
+		.frac_bits = 8),
+	/*
+	 * Secondary SDRAM clock.  Used for low-voltage modes when the PLL
+	 * in the SDRAM controller can't be used.
+	 */
+	[BCM2835_CLOCK_SDRAM]	= REGISTER_VPU_CLK(
+		.name = "sdram",
+		.ctl_reg = CM_SDCCTL,
+		.div_reg = CM_SDCDIV,
+		.int_bits = 6,
+		.frac_bits = 0),
+	[BCM2835_CLOCK_V3D]	= REGISTER_VPU_CLK(
+		.name = "v3d",
+		.ctl_reg = CM_V3DCTL,
+		.div_reg = CM_V3DDIV,
+		.int_bits = 4,
+		.frac_bits = 8),
+	/*
+	 * VPU clock.  This doesn't have an enable bit, since it drives
+	 * the bus for everything else, and is special so it doesn't need
+	 * to be gated for rate changes.  It is also known as "clk_audio"
+	 * in various hardware documentation.
+	 */
+	[BCM2835_CLOCK_VPU]	= REGISTER_VPU_CLK(
+		.name = "vpu",
+		.ctl_reg = CM_VPUCTL,
+		.div_reg = CM_VPUDIV,
+		.int_bits = 12,
+		.frac_bits = 8,
+		.is_vpu_clock = true),
+
+	/* clocks with per parent mux */
+
+	/* Arasan EMMC clock */
+	[BCM2835_CLOCK_EMMC]	= REGISTER_PER_CLK(
+		.name = "emmc",
+		.ctl_reg = CM_EMMCCTL,
+		.div_reg = CM_EMMCDIV,
+		.int_bits = 4,
+		.frac_bits = 8),
+	/* HDMI state machine */
+	[BCM2835_CLOCK_HSM]	= REGISTER_PER_CLK(
+		.name = "hsm",
+		.ctl_reg = CM_HSMCTL,
+		.div_reg = CM_HSMDIV,
+		.int_bits = 4,
+		.frac_bits = 8),
+	[BCM2835_CLOCK_PWM]	= REGISTER_PER_CLK(
+		.name = "pwm",
+		.ctl_reg = CM_PWMCTL,
+		.div_reg = CM_PWMDIV,
+		.int_bits = 12,
+		.frac_bits = 12),
+	[BCM2835_CLOCK_UART]	= REGISTER_PER_CLK(
+		.name = "uart",
+		.ctl_reg = CM_UARTCTL,
+		.div_reg = CM_UARTDIV,
+		.int_bits = 10,
+		.frac_bits = 12),
+	/* TV encoder clock.  Only operating frequency is 108Mhz.  */
+	[BCM2835_CLOCK_VEC]	= REGISTER_PER_CLK(
+		.name = "vec",
+		.ctl_reg = CM_VECCTL,
+		.div_reg = CM_VECDIV,
+		.int_bits = 4,
+		.frac_bits = 0),
+
 	/* the gates */
+
+	/*
+	 * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
+	 * you have the debug bit set in the power manager, which we
+	 * don't bother exposing) are individual gates off of the
+	 * non-stop vpu clock.
+	 */
 	[BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
-		&bcm2835_clock_peri_image_data),
+		.name = "peri_image",
+		.parent = "vpu",
+		.ctl_reg = CM_PERIICTL),
 };
 
 static int bcm2835_clk_probe(struct platform_device *pdev)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 08/20] clk: bcm2835: add fractional support
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (6 preceding siblings ...)
  2016-02-28 15:36 ` [PATCH v5 07/20] clk: bcm2835: reorganize bcm2835_clock_array assignment kernel at martin.sperl.org
@ 2016-02-28 15:36 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 09/20] clk: bcm2835: enable management of PCM clock kernel at martin.sperl.org
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

The current driver calculates the clock divider with
fractional support enabled.
But it does not enable fractional support in the control register.

This patch enables fractional support in the control register
whenever there is a fractional bit set in the requested clock divider.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 144d5d5..ffc5b3c 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -49,6 +49,7 @@
 #define CM_GNRICCTL		0x000
 #define CM_GNRICDIV		0x004
 # define CM_DIV_FRAC_BITS	12
+# define CM_DIV_FRAC_MASK	GENMASK(CM_DIV_FRAC_BITS - 1, 0)
 
 #define CM_VPUCTL		0x008
 #define CM_VPUDIV		0x00c
@@ -126,6 +127,7 @@
 # define CM_GATE			BIT(CM_GATE_BIT)
 # define CM_BUSY			BIT(7)
 # define CM_BUSYD			BIT(8)
+# define CM_FRAC			BIT(9)
 # define CM_SRC_SHIFT			0
 # define CM_SRC_BITS			4
 # define CM_SRC_MASK			0xf
@@ -875,9 +877,26 @@ 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;
+
+	spin_lock(&cprman->regs_lock);
+
+	/*
+	 * Setting up frac support
+	 *
+	 * In principle it is recommended to stop/start the clock first,
+	 * but as we set CLK_SET_RATE_GATE during registration of the
+	 * clock this requirement should be take care of by the
+	 * clk-framework.
+	 */
+	ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC;
+	ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
+	cprman_write(cprman, data->ctl_reg, ctl);
 
 	cprman_write(cprman, data->div_reg, div);
 
+	spin_unlock(&cprman->regs_lock);
+
 	return 0;
 }
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 09/20] clk: bcm2835: enable management of PCM clock
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (7 preceding siblings ...)
  2016-02-28 15:36 ` [PATCH v5 08/20] clk: bcm2835: add fractional support kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 10/20] clk: bcm2835: implement correct clamping for mash clocks kernel at martin.sperl.org
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Enable the PCM clock in the SOC, which is used by the
bcm2835-i2s driver.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c       |    6 ++++++
 include/dt-bindings/clock/bcm2835.h |    1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index ffc5b3c..3df17a5 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -1507,6 +1507,12 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.div_reg = CM_HSMDIV,
 		.int_bits = 4,
 		.frac_bits = 8),
+	[BCM2835_CLOCK_PCM]	= REGISTER_PER_CLK(
+		.name = "pcm",
+		.ctl_reg = CM_PCMCTL,
+		.div_reg = CM_PCMDIV,
+		.int_bits = 12,
+		.frac_bits = 12),
 	[BCM2835_CLOCK_PWM]	= REGISTER_PER_CLK(
 		.name = "pwm",
 		.ctl_reg = CM_PWMCTL,
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 87235ac..9a7b4a5 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -44,3 +44,4 @@
 #define BCM2835_CLOCK_EMMC		28
 #define BCM2835_CLOCK_PERI_IMAGE	29
 #define BCM2835_CLOCK_PWM		30
+#define BCM2835_CLOCK_PCM		31
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 10/20] clk: bcm2835: implement correct clamping for mash clocks
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (8 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 09/20] clk: bcm2835: enable management of PCM clock kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 11/20] clk: bcm2835: divider value has to be 1 or more kernel at martin.sperl.org
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

The bcm2835-soc has 2 kindes of clocks:
* normal clocks
* mash-enabled clocks that can spread frequency noise better
  into non-audiable frequency ranges

The mash clocks have distinct clock-divider requirements
and if the requested divider is not in range, then there will
no clock output.

This patch implements the clamping limits for first order
fractual mash dividers.

Only dividers that are impacted by this patch are: pcm and pwm

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |   24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 3df17a5..2fb9923 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -407,6 +407,7 @@ struct bcm2835_clock_data {
 	/* Number of fractional bits in the divider */
 	u32 frac_bits;
 
+	bool is_mash_clock;
 	bool is_vpu_clock;
 };
 
@@ -780,10 +781,19 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
 		div += unused_frac_mask + 1;
 	div &= ~unused_frac_mask;
 
-	/* Clamp to the limits. */
-	div = max(div, unused_frac_mask + 1);
-	div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
-				      CM_DIV_FRAC_BITS - data->frac_bits));
+	/* Clamp to the limits for the clock type */
+	if (data->is_mash_clock) {
+		/* clamp to min divider 2 */
+		div = max_t(u32, div, 2 << CM_DIV_FRAC_BITS);
+		/* clamp to max int divider */
+		div = min_t(u32, div,
+			    (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS);
+	} else {
+		div = max(div, unused_frac_mask + 1);
+		div = min_t(u32, div,
+			    GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
+				    CM_DIV_FRAC_BITS - data->frac_bits));
+	}
 
 	return div;
 }
@@ -1512,13 +1522,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.ctl_reg = CM_PCMCTL,
 		.div_reg = CM_PCMDIV,
 		.int_bits = 12,
-		.frac_bits = 12),
+		.frac_bits = 12,
+		.is_mash_clock = true),
 	[BCM2835_CLOCK_PWM]	= REGISTER_PER_CLK(
 		.name = "pwm",
 		.ctl_reg = CM_PWMCTL,
 		.div_reg = CM_PWMDIV,
 		.int_bits = 12,
-		.frac_bits = 12),
+		.frac_bits = 12,
+		.is_mash_clock = true),
 	[BCM2835_CLOCK_UART]	= REGISTER_PER_CLK(
 		.name = "uart",
 		.ctl_reg = CM_UARTCTL,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 11/20] clk: bcm2835: divider value has to be 1 or more
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (9 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 10/20] clk: bcm2835: implement correct clamping for mash clocks kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 12/20] clk: bcm2835: expose raw clock-registers via debugfs kernel at martin.sperl.org
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Current clamping of a normal divider allows a value < 1 to be valid.

A divider of < 1 would actually only be possible if we had a PLL...

So this patch clamps the divider for non-mash clocks to 1.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 2fb9923..211d231 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -789,7 +789,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
 		div = min_t(u32, div,
 			    (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS);
 	} else {
-		div = max(div, unused_frac_mask + 1);
+		/* clamp to min divider of 1 */
+		div = max_t(u32, div, 1 << CM_DIV_FRAC_BITS);
+		/* clamp to the highest possible fractional divider */
 		div = min_t(u32, div,
 			    GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
 				    CM_DIV_FRAC_BITS - data->frac_bits));
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 12/20] clk: bcm2835: expose raw clock-registers via debugfs
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (10 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 11/20] clk: bcm2835: divider value has to be 1 or more kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 13/20] clk: bcm2835: expose current divider, parent and mash " kernel at martin.sperl.org
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

For debugging purposes under some circumstance
it helps to be able to see the actual clock registers.

E.g: when looking at the clock divider it is helpful to
see what the actual clock divider is.

This patch exposes all the clock registers specific to each
clock/pll/pll-divider via debugfs.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |  101 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 211d231..366f975 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -38,6 +38,7 @@
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clk/bcm2835.h>
+#include <linux/debugfs.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -314,6 +315,27 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg)
 	return readl(cprman->regs + reg);
 }
 
+static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
+				  struct debugfs_reg32 *regs, size_t nregs,
+				  struct dentry *dentry)
+{
+	struct dentry *regdump;
+	struct debugfs_regset32 *regset;
+
+	regset = devm_kzalloc(cprman->dev, sizeof(*regset), GFP_KERNEL);
+	if (!regset)
+		return -ENOMEM;
+
+	regset->regs = regs;
+	regset->nregs = nregs;
+	regset->base = cprman->regs + base;
+
+	regdump = debugfs_create_regset32("regdump", S_IRUGO, dentry,
+					  regset);
+
+	return regdump ? 0 : -ENOMEM;
+}
+
 /*
  * These are fixed clocks. They're probably not all root clocks and it may
  * be possible to turn them on and off but until this is mapped out better
@@ -627,6 +649,36 @@ static int bcm2835_pll_set_rate(struct clk_hw *hw,
 	return 0;
 }
 
+static int bcm2835_pll_debug_init(struct clk_hw *hw,
+				  struct dentry *dentry)
+{
+	struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw);
+	struct bcm2835_cprman *cprman = pll->cprman;
+	const struct bcm2835_pll_data *data = pll->data;
+	struct debugfs_reg32 *regs;
+
+	regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL);
+	if (!regs)
+		return -ENOMEM;
+
+	regs[0].name = "cm_ctrl";
+	regs[0].offset = data->cm_ctrl_reg;
+	regs[1].name = "a2w_ctrl";
+	regs[1].offset = data->a2w_ctrl_reg;
+	regs[2].name = "frac";
+	regs[2].offset = data->frac_reg;
+	regs[3].name = "ana0";
+	regs[3].offset = data->ana_reg_base + 0 * 4;
+	regs[4].name = "ana1";
+	regs[4].offset = data->ana_reg_base + 1 * 4;
+	regs[5].name = "ana2";
+	regs[5].offset = data->ana_reg_base + 2 * 4;
+	regs[6].name = "ana3";
+	regs[6].offset = data->ana_reg_base + 3 * 4;
+
+	return bcm2835_debugfs_regset(cprman, 0, regs, 7, dentry);
+}
+
 static const struct clk_ops bcm2835_pll_clk_ops = {
 	.is_prepared = bcm2835_pll_is_on,
 	.prepare = bcm2835_pll_on,
@@ -634,6 +686,7 @@ static const struct clk_ops bcm2835_pll_clk_ops = {
 	.recalc_rate = bcm2835_pll_get_rate,
 	.set_rate = bcm2835_pll_set_rate,
 	.round_rate = bcm2835_pll_round_rate,
+	.debug_init = bcm2835_pll_debug_init,
 };
 
 struct bcm2835_pll_divider {
@@ -725,6 +778,26 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw *hw,
 	return 0;
 }
 
+static int bcm2835_pll_divider_debug_init(struct clk_hw *hw,
+					  struct dentry *dentry)
+{
+	struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw);
+	struct bcm2835_cprman *cprman = divider->cprman;
+	const struct bcm2835_pll_divider_data *data = divider->data;
+	struct debugfs_reg32 *regs;
+
+	regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL);
+	if (!regs)
+		return -ENOMEM;
+
+	regs[0].name = "cm";
+	regs[0].offset = data->cm_reg;
+	regs[1].name = "a2w";
+	regs[1].offset = data->a2w_reg;
+
+	return bcm2835_debugfs_regset(cprman, 0, regs, 2, dentry);
+}
+
 static const struct clk_ops bcm2835_pll_divider_clk_ops = {
 	.is_prepared = bcm2835_pll_divider_is_on,
 	.prepare = bcm2835_pll_divider_on,
@@ -732,6 +805,7 @@ static const struct clk_ops bcm2835_pll_divider_clk_ops = {
 	.recalc_rate = bcm2835_pll_divider_get_rate,
 	.set_rate = bcm2835_pll_divider_set_rate,
 	.round_rate = bcm2835_pll_divider_round_rate,
+	.debug_init = bcm2835_pll_divider_debug_init,
 };
 
 /*
@@ -971,6 +1045,31 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw)
 	return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
 }
 
+static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
+	{
+		.name = "ctl",
+		.offset = 0,
+	},
+	{
+		.name = "div",
+		.offset = 4,
+	},
+};
+
+static int bcm2835_clock_debug_init(struct clk_hw *hw,
+				    struct dentry *dentry)
+{
+	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+	struct bcm2835_cprman *cprman = clock->cprman;
+	const struct bcm2835_clock_data *data = clock->data;
+
+	return bcm2835_debugfs_regset(
+		cprman, data->ctl_reg,
+		bcm2835_debugfs_clock_reg32,
+		ARRAY_SIZE(bcm2835_debugfs_clock_reg32),
+		dentry);
+}
+
 static const struct clk_ops bcm2835_clock_clk_ops = {
 	.is_prepared = bcm2835_clock_is_on,
 	.prepare = bcm2835_clock_on,
@@ -980,6 +1079,7 @@ static const struct clk_ops bcm2835_clock_clk_ops = {
 	.determine_rate = bcm2835_clock_determine_rate,
 	.set_parent = bcm2835_clock_set_parent,
 	.get_parent = bcm2835_clock_get_parent,
+	.debug_init = bcm2835_clock_debug_init,
 };
 
 static int bcm2835_vpu_clock_is_on(struct clk_hw *hw)
@@ -998,6 +1098,7 @@ static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
 	.determine_rate = bcm2835_clock_determine_rate,
 	.set_parent = bcm2835_clock_set_parent,
 	.get_parent = bcm2835_clock_get_parent,
+	.debug_init = bcm2835_clock_debug_init,
 };
 
 static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 13/20] clk: bcm2835: expose current divider, parent and mash via debugfs
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (11 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 12/20] clk: bcm2835: expose raw clock-registers via debugfs kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 14/20] clk: bcm2835: added missing PLL clock divider kernel at martin.sperl.org
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

For each clock expose the following values via debugfs:
* current_parent - the currently selected parent
* current_divi - the integer portion of the currently set divider
* current_divf - the fractional portion of the currently set divider
* current_frac - the current frac/mash settings for the divider

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c |  101 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 366f975..b67147b 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -129,6 +129,10 @@
 # define CM_BUSY			BIT(7)
 # define CM_BUSYD			BIT(8)
 # define CM_FRAC			BIT(9)
+# define CM_MASH0			BIT(9)
+# define CM_MASH1			BIT(10)
+# define CM_MASH_MASK			(CM_MASH0 | CM_MASH1)
+# define CM_MASH_SHIFT			9
 # define CM_SRC_SHIFT			0
 # define CM_SRC_BITS			4
 # define CM_SRC_MASK			0xf
@@ -1045,6 +1049,90 @@ static u8 bcm2835_clock_get_parent(struct clk_hw *hw)
 	return (src & CM_SRC_MASK) >> CM_SRC_SHIFT;
 }
 
+static const char *bcm2835_clock_get_parent_name(struct clk_hw *hw)
+{
+	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+	const struct bcm2835_clock_data *data = clock->data;
+	u8 id = bcm2835_clock_get_parent(hw);
+
+	return (id < data->num_mux_parents) ?
+		data->parents[id] : "unknown";
+}
+
+static int bcm2835_clock_debug_current_parent_open(struct inode *inode,
+						   struct file *file)
+{
+	const char *parent = bcm2835_clock_get_parent_name(inode->i_private);
+
+	file->private_data = kstrdup(parent, GFP_KERNEL);
+	return 0;
+}
+
+static ssize_t bcm2835_clock_debug_current_parent_read(struct file *file,
+						       char __user *buf,
+						       size_t len,
+						       loff_t *ppos)
+{
+	const char *parent = file->private_data;
+	size_t size = strlen(parent);
+
+	return simple_read_from_buffer(buf, len, ppos, parent, size);
+}
+
+static const struct file_operations bcm2835_clock_debug_current_parent_fops = {
+	.owner   = THIS_MODULE,
+	.open    = bcm2835_clock_debug_current_parent_open,
+	.release = simple_attr_release,
+	.read    = bcm2835_clock_debug_current_parent_read,
+	.llseek  = generic_file_llseek,
+};
+
+static int bcm2835_clock_debug_current_divi_get(void *hw, u64 *val)
+{
+	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+	struct bcm2835_cprman *cprman = clock->cprman;
+	const struct bcm2835_clock_data *data = clock->data;
+	u32 div = cprman_read(cprman, data->div_reg);
+
+	*val = div >> CM_DIV_FRAC_BITS;
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(bcm2835_clock_debug_current_divi_fops,
+			bcm2835_clock_debug_current_divi_get,
+			NULL, "%llu\n");
+
+static int bcm2835_clock_debug_current_divf_get(void *hw, u64 *val)
+{
+	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+	struct bcm2835_cprman *cprman = clock->cprman;
+	const struct bcm2835_clock_data *data = clock->data;
+	u32 div = cprman_read(cprman, data->div_reg);
+
+	*val = div & CM_DIV_FRAC_MASK;
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(bcm2835_clock_debug_current_divf_fops,
+			bcm2835_clock_debug_current_divf_get,
+			NULL, "%llu\n");
+
+static int bcm2835_clock_debug_current_frac_get(void *hw, u64 *val)
+{
+	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+	struct bcm2835_cprman *cprman = clock->cprman;
+	const struct bcm2835_clock_data *data = clock->data;
+	u32 ctl = cprman_read(cprman, data->ctl_reg);
+
+	if (data->is_mash_clock)
+		*val = (ctl & CM_MASH_MASK) >> CM_MASH_SHIFT;
+	else
+		*val = ctl & CM_FRAC ? 1 : 0;
+
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(bcm2835_clock_debug_current_frac_fops,
+			bcm2835_clock_debug_current_frac_get,
+			NULL, "%llu\n");
+
 static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = {
 	{
 		.name = "ctl",
@@ -1063,6 +1151,19 @@ static int bcm2835_clock_debug_init(struct clk_hw *hw,
 	struct bcm2835_cprman *cprman = clock->cprman;
 	const struct bcm2835_clock_data *data = clock->data;
 
+	/* expose the current parrent */
+	debugfs_create_file("current_parent", S_IRUGO, dentry, hw,
+			    &bcm2835_clock_debug_current_parent_fops);
+
+	/* expose the current divider components */
+	debugfs_create_file("current_divi", S_IRUGO, dentry, hw,
+			    &bcm2835_clock_debug_current_divi_fops);
+	debugfs_create_file("current_divf", S_IRUGO, dentry, hw,
+			    &bcm2835_clock_debug_current_divf_fops);
+	debugfs_create_file("current_frac", S_IRUGO, dentry, hw,
+			    &bcm2835_clock_debug_current_frac_fops);
+
+	/* add the regset */
 	return bcm2835_debugfs_regset(
 		cprman, data->ctl_reg,
 		bcm2835_debugfs_clock_reg32,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 14/20] clk: bcm2835: added missing PLL clock divider
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (12 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 13/20] clk: bcm2835: expose current divider, parent and mash " kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 15/20] clk: bcm2835: add additional clocks kernel at martin.sperl.org
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Added the missing pll clock divider definitions.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c       |   50 +++++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/bcm2835.h |    8 ++++++
 2 files changed, 58 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index b67147b..ff02871 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -1470,6 +1470,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.load_mask = CM_PLLA_LOADPER,
 		.hold_mask = CM_PLLA_HOLDPER,
 		.fixed_divider = 1),
+	[BCM2835_PLLA_DSI0]	= REGISTER_PLL_DIV(
+		.name = "plla_dsi0",
+		.source_pll = "plla",
+		.cm_reg = CM_PLLA,
+		.a2w_reg = A2W_PLLA_DSI0,
+		.load_mask = CM_PLLA_LOADDSI0,
+		.hold_mask = CM_PLLA_HOLDDSI0,
+		.fixed_divider = 1),
+	[BCM2835_PLLA_CCP2]	= REGISTER_PLL_DIV(
+		.name = "plla_ccp2",
+		.source_pll = "plla",
+		.cm_reg = CM_PLLA,
+		.a2w_reg = A2W_PLLA_DSI0,
+		.load_mask = CM_PLLA_LOADCCP2,
+		.hold_mask = CM_PLLA_HOLDCCP2,
+		.fixed_divider = 1),
 
 	/* PLLB is used for the ARM's clock. */
 	[BCM2835_PLLB]		= REGISTER_PLL(
@@ -1494,6 +1510,24 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.load_mask = CM_PLLB_LOADARM,
 		.hold_mask = CM_PLLB_HOLDARM,
 		.fixed_divider = 1),
+	[BCM2835_PLLB_SP0]	= REGISTER_PLL_DIV(
+		.name = "pllb_sp0",
+		.source_pll = "pllb",
+		.cm_reg = CM_PLLB,
+		.a2w_reg = A2W_PLLB_SP0,
+		.fixed_divider = 1),
+	[BCM2835_PLLB_SP1]	= REGISTER_PLL_DIV(
+		.name = "pllb_sp1",
+		.source_pll = "pllb",
+		.cm_reg = CM_PLLB,
+		.a2w_reg = A2W_PLLB_SP1,
+		.fixed_divider = 1),
+	[BCM2835_PLLB_SP2]	= REGISTER_PLL_DIV(
+		.name = "pllb_sp2",
+		.source_pll = "pllb",
+		.cm_reg = CM_PLLB,
+		.a2w_reg = A2W_PLLB_SP2,
+		.fixed_divider = 1),
 
 	/*
 	 * PLLC is the core PLL, used to drive the core VPU clock.
@@ -1584,6 +1618,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.load_mask = CM_PLLD_LOADPER,
 		.hold_mask = CM_PLLD_HOLDPER,
 		.fixed_divider = 1),
+	[BCM2835_PLLD_DSI0]	= REGISTER_PLL_DIV(
+		.name = "plld_dsi0",
+		.source_pll = "plld",
+		.cm_reg = CM_PLLD,
+		.a2w_reg = A2W_PLLD_DSI0,
+		.load_mask = CM_PLLD_LOADDSI0,
+		.hold_mask = CM_PLLD_HOLDDSI0,
+		.fixed_divider = 1),
+	[BCM2835_PLLD_DSI1]	= REGISTER_PLL_DIV(
+		.name = "plld_dsi1",
+		.source_pll = "plld",
+		.cm_reg = CM_PLLD,
+		.a2w_reg = A2W_PLLD_DSI1,
+		.load_mask = CM_PLLD_LOADDSI1,
+		.hold_mask = CM_PLLD_HOLDDSI1,
+		.fixed_divider = 1),
 
 	/*
 	 * PLLH is used to supply the pixel clock or the AUX clock for the
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 9a7b4a5..9689812 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -45,3 +45,11 @@
 #define BCM2835_CLOCK_PERI_IMAGE	29
 #define BCM2835_CLOCK_PWM		30
 #define BCM2835_CLOCK_PCM		31
+
+#define BCM2835_PLLA_DSI0		32
+#define BCM2835_PLLA_CCP2		33
+#define BCM2835_PLLB_SP0		34
+#define BCM2835_PLLB_SP1		35
+#define BCM2835_PLLB_SP2		36
+#define BCM2835_PLLD_DSI0		37
+#define BCM2835_PLLD_DSI1		38
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 15/20] clk: bcm2835: add additional clocks
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (13 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 14/20] clk: bcm2835: added missing PLL clock divider kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 16/20] clk: bcm2835: add the camera related clocks cam0, cam1 and ccp2 kernel at martin.sperl.org
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Add definitions for the following clocks:
* AVE0
* DFT
* GP0
* GP1
* GP2
* PULSE
* SLIM
* SMI
* TEC

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c       |   71 +++++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/bcm2835.h |   10 +++++
 2 files changed, 81 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index ff02871..5c62672 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -118,6 +118,8 @@
 #define CM_SDCCTL		0x1a8
 #define CM_SDCDIV		0x1ac
 #define CM_ARMCTL		0x1b0
+#define CM_AVEOCTL		0x1b8
+#define CM_AVEODIV		0x1bc
 #define CM_EMMCCTL		0x1c0
 #define CM_EMMCDIV		0x1c4
 
@@ -1711,6 +1713,18 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.div_reg = CM_TSENSDIV,
 		.int_bits = 5,
 		.frac_bits = 0),
+	[BCM2835_CLOCK_PULSE]	= REGISTER_OSC_CLK(
+		.name = "pulse",
+		.ctl_reg = CM_PULSECTL,
+		.div_reg = CM_PULSEDIV,
+		.int_bits = 12,
+		.frac_bits = 0),
+	[BCM2835_CLOCK_TEC]	= REGISTER_OSC_CLK(
+		.name = "tec",
+		.ctl_reg = CM_TECCTL,
+		.div_reg = CM_TECDIV,
+		.int_bits = 6,
+		.frac_bits = 0),
 
 	/* clocks with vpu parent mux */
 	[BCM2835_CLOCK_H264]	= REGISTER_VPU_CLK(
@@ -1725,6 +1739,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.div_reg = CM_ISPDIV,
 		.int_bits = 4,
 		.frac_bits = 8),
+
 	/*
 	 * Secondary SDRAM clock.  Used for low-voltage modes when the PLL
 	 * in the SDRAM controller can't be used.
@@ -1756,6 +1771,24 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.is_vpu_clock = true),
 
 	/* clocks with per parent mux */
+	[BCM2835_CLOCK_AVEO]	= REGISTER_PER_CLK(
+		.name = "aveo",
+		.ctl_reg = CM_AVEOCTL,
+		.div_reg = CM_AVEODIV,
+		.int_bits = 4,
+		.frac_bits = 0),
+	[BCM2835_CLOCK_DFT]	= REGISTER_PER_CLK(
+		.name = "dft",
+		.ctl_reg = CM_DFTCTL,
+		.div_reg = CM_DFTDIV,
+		.int_bits = 5,
+		.frac_bits = 0),
+	[BCM2835_CLOCK_DFT]	= REGISTER_PER_CLK(
+		.name = "dpi",
+		.ctl_reg = CM_DPICTL,
+		.div_reg = CM_DPIDIV,
+		.int_bits = 4,
+		.frac_bits = 8),
 
 	/* Arasan EMMC clock */
 	[BCM2835_CLOCK_EMMC]	= REGISTER_PER_CLK(
@@ -1764,6 +1797,30 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.div_reg = CM_EMMCDIV,
 		.int_bits = 4,
 		.frac_bits = 8),
+
+	/* General purpose (GPIO) clocks */
+	[BCM2835_CLOCK_GP0]	= REGISTER_PER_CLK(
+		.name = "gp0",
+		.ctl_reg = CM_GP0CTL,
+		.div_reg = CM_GP0DIV,
+		.int_bits = 12,
+		.frac_bits = 12,
+		.is_mash_clock = true),
+	[BCM2835_CLOCK_GP1]	= REGISTER_PER_CLK(
+		.name = "gp1",
+		.ctl_reg = CM_GP1CTL,
+		.div_reg = CM_GP1DIV,
+		.int_bits = 12,
+		.frac_bits = 12,
+		.is_mash_clock = true),
+	[BCM2835_CLOCK_GP2]	= REGISTER_PER_CLK(
+		.name = "gp2",
+		.ctl_reg = CM_GP2CTL,
+		.div_reg = CM_GP2DIV,
+		.int_bits = 12,
+		.frac_bits = 12,
+		.is_mash_clock = true),
+
 	/* HDMI state machine */
 	[BCM2835_CLOCK_HSM]	= REGISTER_PER_CLK(
 		.name = "hsm",
@@ -1785,12 +1842,26 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.int_bits = 12,
 		.frac_bits = 12,
 		.is_mash_clock = true),
+	[BCM2835_CLOCK_SLIM]	= REGISTER_PER_CLK(
+		.name = "slim",
+		.ctl_reg = CM_SLIMCTL,
+		.div_reg = CM_SLIMDIV,
+		.int_bits = 12,
+		.frac_bits = 12,
+		.is_mash_clock = true),
+	[BCM2835_CLOCK_SMI]	= REGISTER_PER_CLK(
+		.name = "smi",
+		.ctl_reg = CM_SMICTL,
+		.div_reg = CM_SMIDIV,
+		.int_bits = 4,
+		.frac_bits = 8),
 	[BCM2835_CLOCK_UART]	= REGISTER_PER_CLK(
 		.name = "uart",
 		.ctl_reg = CM_UARTCTL,
 		.div_reg = CM_UARTDIV,
 		.int_bits = 10,
 		.frac_bits = 12),
+
 	/* TV encoder clock.  Only operating frequency is 108Mhz.  */
 	[BCM2835_CLOCK_VEC]	= REGISTER_PER_CLK(
 		.name = "vec",
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 9689812..f2e72e7 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -53,3 +53,13 @@
 #define BCM2835_PLLB_SP2		36
 #define BCM2835_PLLD_DSI0		37
 #define BCM2835_PLLD_DSI1		38
+
+#define BCM2835_CLOCK_AVEO		39
+#define BCM2835_CLOCK_DFT		40
+#define BCM2835_CLOCK_GP0		41
+#define BCM2835_CLOCK_GP1		42
+#define BCM2835_CLOCK_GP2		43
+#define BCM2835_CLOCK_PULSE		44
+#define BCM2835_CLOCK_SLIM		45
+#define BCM2835_CLOCK_SMI		46
+#define BCM2835_CLOCK_TEC		47
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 16/20] clk: bcm2835: add the camera related clocks cam0, cam1 and ccp2
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (14 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 15/20] clk: bcm2835: add additional clocks kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 17/20] clk: bcm2835: add the dsi clocks kernel at martin.sperl.org
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Add the camera related clocks: cam0, cam1 and ccp2
and the corresponding ccp2 clock mux definition.

Note that the mux definition is incomplete and essentially
is identical to the osc mux right now. But it should contain
at least plla_ccp2 in one location.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c       |   53 +++++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/bcm2835.h |    3 ++
 2 files changed, 56 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 5c62672..5364f10 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -1428,6 +1428,34 @@ static const char *const bcm2835_clock_vpu_parents[] = {
 	.parents = bcm2835_clock_vpu_parents,				\
 	__VA_ARGS__)
 
+/* ccp2 (camera) parent mux */
+static const char * const bcm2835_clock_ccp2_parents[] = {
+	"gnd",
+	"xosc",
+	"testdebug0",
+	"testdebug1",
+	/*
+	 * more parent clocks, but unknown at this time
+	 * the current definition follows the "common" pattern
+	 * that already applies to all the other parent mux
+	 * in so far as all the known mux contain gnd, xosc, testdebug0/1
+	 * as the first 3 entries.
+	 * The mux should contain "plla_ccp2" at one position.
+	 * here some possible candidates for the next parents in the list.
+	 *   plla_ccp2 or ppla_core/per
+	 *   pllb_core/per
+	 *   pllc_core/per
+	 *   plld_core/per
+	 *   pllh_aux/pix
+	 * up to 16 different parents
+	 */
+};
+
+#define REGISTER_CCP2_CLK(...)	REGISTER_CLK(				\
+	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_ccp2_parents),	\
+	.parents = bcm2835_clock_ccp2_parents,				\
+	__VA_ARGS__)
+
 /*
  * the real definition of all the pll, pll_dividers and clocks
  * these make use of the above REGISTER_* macros
@@ -1777,6 +1805,18 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.div_reg = CM_AVEODIV,
 		.int_bits = 4,
 		.frac_bits = 0),
+	[BCM2835_CLOCK_CAM0]	= REGISTER_PER_CLK(
+		.name = "cam0",
+		.ctl_reg = CM_CAM0CTL,
+		.div_reg = CM_CAM0DIV,
+		.int_bits = 4,
+		.frac_bits = 8),
+	[BCM2835_CLOCK_CAM1]	= REGISTER_PER_CLK(
+		.name = "cam1",
+		.ctl_reg = CM_CAM1CTL,
+		.div_reg = CM_CAM1DIV,
+		.int_bits = 4,
+		.frac_bits = 8),
 	[BCM2835_CLOCK_DFT]	= REGISTER_PER_CLK(
 		.name = "dft",
 		.ctl_reg = CM_DFTCTL,
@@ -1870,6 +1910,19 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.int_bits = 4,
 		.frac_bits = 0),
 
+	/* clocks with ccp2 parent mux */
+	[BCM2835_CLOCK_CCP2]	= REGISTER_CCP2_CLK(
+		/*
+		 * this is possibly a gate of the plla_ccp2 divider
+		 * but as CTL contains 4 bits for mux selection
+		 * it must be a mux
+		 */
+		.name = "ccp2",
+		.ctl_reg = CM_CCP2CTL,
+		.div_reg = CM_CCP2DIV,
+		.int_bits = 1,
+		.frac_bits = 0),
+
 	/* the gates */
 
 	/*
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index f2e72e7..1d70088 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -63,3 +63,6 @@
 #define BCM2835_CLOCK_SLIM		45
 #define BCM2835_CLOCK_SMI		46
 #define BCM2835_CLOCK_TEC		47
+#define BCM2835_CLOCK_CAM0		48
+#define BCM2835_CLOCK_CAM1		49
+#define BCM2835_CLOCK_CCP2		50
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 17/20] clk: bcm2835: add the dsi clocks
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (15 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 16/20] clk: bcm2835: add the camera related clocks cam0, cam1 and ccp2 kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 18/20] clk: bcm2835: add arm clock kernel at martin.sperl.org
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Add the missing dsi clocks using the currently "best known"
parent-mux available for these clocks.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c       |   88 +++++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/bcm2835.h |    4 ++
 2 files changed, 92 insertions(+)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 5364f10..a5c108a 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -199,6 +199,8 @@
 # define CM_LOCK_FLOCKA			BIT(8)
 
 #define CM_EVENT		0x118
+#define CM_DSI0HSCK		0x120
+# define CM_DSI0HSCK_SELPLLD		BIT(0)
 #define CM_DSI1ECTL		0x158
 #define CM_DSI1EDIV		0x15c
 #define CM_DSI1PCTL		0x160
@@ -1456,10 +1458,68 @@ static const char * const bcm2835_clock_ccp2_parents[] = {
 	.parents = bcm2835_clock_ccp2_parents,				\
 	__VA_ARGS__)
 
+/* dsi0 parent mux */
+static const char * const bcm2835_clock_dsi0_parents[] = {
+	"gnd",
+	"xosc",
+	"testdebug0",
+	"testdebug1",
+	/*
+	 * more parent clocks, but unknown at this time
+	 * the current definition follows the "common" pattern
+	 * that already applies to all the other parent mux
+	 * in so far as all the known mux contain gnd, xosc, testdebug0/1
+	 * as the first 3 entries.
+	 * The mux should contain "plla_dsi0/plld_dsi0" at one position.
+	 *   the selection which pll is used depends on CM_DSI0HSCK_SELPLLD
+	 * here some possible candidates for the next parents in the list.
+	 *   plla_core/per or plla_dsi0/plld_dsi0
+	 *   pllc_core/per
+	 *   plld_core/per
+	 *   pllh_aux/pix
+	 *   maybe plla_dsi0/plld_dsi0 (depends on CM_DSI0HSCK_SELPLLD)
+	 * up to 16 different parents
+	 */
+};
+
+#define REGISTER_DSI0_CLK(...)	REGISTER_CLK(				\
+	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents),	\
+	.parents = bcm2835_clock_dsi0_parents,				\
+	__VA_ARGS__)
+
+/* dsi1 parent mux */
+static const char * const bcm2835_clock_dsi1_parents[] = {
+	"gnd",
+	"xosc",
+	"testdebug0",
+	"testdebug1",
+	/*
+	 * more parent clocks, but unknown at this time
+	 * the current definition follows the "common" pattern
+	 * that already applies to all the other parent mux
+	 * in so far as all the known mux contain gnd, xosc, testdebug0/1
+	 * as the first 3 entries.
+	 * The mux should contain "plld_dsi1" at one position.
+	 * here some possible candidates for the next parents in the list.
+	 *   plla_core/per
+	 *   pllc_core/per
+	 *   plld_core/per or plld_dsi1
+	 *   pllh_aux/pix
+	 *   maybe plld_dsi1
+	 * up to 16 different parents
+	 */
+};
+
+#define REGISTER_DSI1_CLK(...)	REGISTER_CLK(				\
+	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents),	\
+	.parents = bcm2835_clock_dsi1_parents,				\
+	__VA_ARGS__)
+
 /*
  * the real definition of all the pll, pll_dividers and clocks
  * these make use of the above REGISTER_* macros
  */
+
 static const struct bcm2835_clk_desc clk_desc_array[] = {
 	/* the PLL + PLL dividers */
 
@@ -1923,6 +1983,34 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.int_bits = 1,
 		.frac_bits = 0),
 
+	/* dsi clocks */
+	[BCM2835_CLOCK_DSI0E]	= REGISTER_DSI0_CLK(
+		.name = "dsi0e",
+		.ctl_reg = CM_DSI0ECTL,
+		.div_reg = CM_DSI0EDIV,
+		.int_bits = 4,
+		.frac_bits = 8),
+	[BCM2835_CLOCK_DSI0_IMAGE] = REGISTER_DSI0_CLK(
+		/* this is in principle a gate with a 4 bit mux */
+		.name = "dsi0_image",
+		.ctl_reg = CM_DSI0PCTL,
+		.div_reg = CM_DSI0PDIV,
+		.int_bits = 1,
+		.frac_bits = 0),
+	[BCM2835_CLOCK_DSI1E]	= REGISTER_DSI1_CLK(
+		.name = "dsi1e",
+		.ctl_reg = CM_DSI1ECTL,
+		.div_reg = CM_DSI1EDIV,
+		.int_bits = 4,
+		.frac_bits = 8),
+	[BCM2835_CLOCK_DSI1_IMAGE] = REGISTER_DSI1_CLK(
+		/* this is in principle a gate with a 4 bit mux */
+		.name = "dsi1_image",
+		.ctl_reg = CM_DSI1PCTL,
+		.div_reg = CM_DSI1PDIV,
+		.int_bits = 1,
+		.frac_bits = 0),
+
 	/* the gates */
 
 	/*
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 1d70088..9254c78 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -66,3 +66,7 @@
 #define BCM2835_CLOCK_CAM0		48
 #define BCM2835_CLOCK_CAM1		49
 #define BCM2835_CLOCK_CCP2		50
+#define BCM2835_CLOCK_DSI0E		51
+#define BCM2835_CLOCK_DSI0_IMAGE	52
+#define BCM2835_CLOCK_DSI1E		53
+#define BCM2835_CLOCK_DSI1_IMAGE	54
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 18/20] clk: bcm2835: add arm clock
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (16 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 17/20] clk: bcm2835: add the dsi clocks kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 15:37 ` [PATCH v5 19/20] clk: bcm2835: add gates that require PM_DEBUG to be set kernel at martin.sperl.org
  2016-02-28 17:48 ` [PATCH v5 00/20] add additional clocks and frac/mash support Stefan Wahren
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Add the missing "ARM" clock to the clock framework.
This clock is essentially a gate clock but with a
16 channel mux.

We assume this is a mux that uses PLLB_ARM, so a dedicated
mux for arm was created.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c       |   34 +++++++++++++++++++++++++++++++++-
 include/dt-bindings/clock/bcm2835.h |    1 +
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index a5c108a..4f002b7 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -118,6 +118,7 @@
 #define CM_SDCCTL		0x1a8
 #define CM_SDCDIV		0x1ac
 #define CM_ARMCTL		0x1b0
+#define CM_ARMDIV		0x1b4
 #define CM_AVEOCTL		0x1b8
 #define CM_AVEODIV		0x1bc
 #define CM_EMMCCTL		0x1c0
@@ -1515,11 +1516,33 @@ static const char * const bcm2835_clock_dsi1_parents[] = {
 	.parents = bcm2835_clock_dsi1_parents,				\
 	__VA_ARGS__)
 
+/* arm parent mux */
+static const char * const bcm2835_clock_arm_parents[] = {
+	"gnd",
+	"xosc",
+	"testdebug0",
+	"testdebug1",
+	/*
+	 * see comments for dsi0 for possible candidates
+	 * should contain "pllb_arm" at one position
+	 *   plla_core/per
+	 *   pllb_arm or pllb_core/per
+	 *   pllc_core/per
+	 *   plld_core/per
+	 *   pllh_aux/pix
+	 * up to 16 different parents
+	 */
+};
+
+#define REGISTER_ARM_CLK(...)	REGISTER_CLK(				\
+	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_arm_parents),	\
+	.parents = bcm2835_clock_arm_parents,				\
+	__VA_ARGS__)
+
 /*
  * the real definition of all the pll, pll_dividers and clocks
  * these make use of the above REGISTER_* macros
  */
-
 static const struct bcm2835_clk_desc clk_desc_array[] = {
 	/* the PLL + PLL dividers */
 
@@ -2011,6 +2034,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.int_bits = 1,
 		.frac_bits = 0),
 
+	/* arm clocks */
+	[BCM2835_CLOCK_DSI1_IMAGE] = REGISTER_ARM_CLK(
+		/* this is in principle a gate with a 4 bit mux */
+		.name = "arm",
+		.ctl_reg = CM_ARMCTL,
+		.div_reg = CM_ARMDIV,
+		.int_bits = 1,
+		.frac_bits = 0),
+
 	/* the gates */
 
 	/*
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 9254c78..109086e 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -70,3 +70,4 @@
 #define BCM2835_CLOCK_DSI0_IMAGE	52
 #define BCM2835_CLOCK_DSI1E		53
 #define BCM2835_CLOCK_DSI1_IMAGE	54
+#define BCM2835_CLOCK_ARM		55
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 19/20] clk: bcm2835: add gates that require PM_DEBUG to be set
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (17 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 18/20] clk: bcm2835: add arm clock kernel at martin.sperl.org
@ 2016-02-28 15:37 ` kernel at martin.sperl.org
  2016-02-28 17:48 ` [PATCH v5 00/20] add additional clocks and frac/mash support Stefan Wahren
  19 siblings, 0 replies; 23+ messages in thread
From: kernel at martin.sperl.org @ 2016-02-28 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Martin Sperl <kernel@martin.sperl.org>

Add clocks that require PM_DEBUG to be set and mark this
fact in the gate_data structure, so that this fact can get
referred to if needed.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
 drivers/clk/bcm/clk-bcm2835.c       |   16 +++++++++++++++-
 include/dt-bindings/clock/bcm2835.h |    2 ++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 4f002b7..fb5706c 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -447,6 +447,8 @@ struct bcm2835_gate_data {
 	const char *parent;
 
 	u32 ctl_reg;
+
+	bool requires_pm_debug;
 };
 
 struct bcm2835_pll {
@@ -2051,10 +2053,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 	 * don't bother exposing) are individual gates off of the
 	 * non-stop vpu clock.
 	 */
+	[BCM2835_CLOCK_PERA] = REGISTER_GATE(
+		.name = "pera",
+		.parent = "vpu",
+		.ctl_reg = CM_PERIACTL,
+		.requires_pm_debug = true),
 	[BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
 		.name = "peri_image",
 		.parent = "vpu",
-		.ctl_reg = CM_PERIICTL),
+		.ctl_reg = CM_PERIICTL,
+		.requires_pm_debug = true),
+	[BCM2835_CLOCK_SYS] = REGISTER_GATE(
+		.name = "sys",
+		.parent = "vpu",
+		.ctl_reg = CM_SYSCTL,
+		.requires_pm_debug = true),
+
 };
 
 static int bcm2835_clk_probe(struct platform_device *pdev)
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 109086e..7bc03cd 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -71,3 +71,5 @@
 #define BCM2835_CLOCK_DSI1E		53
 #define BCM2835_CLOCK_DSI1_IMAGE	54
 #define BCM2835_CLOCK_ARM		55
+#define BCM2835_CLOCK_PERA		56
+#define BCM2835_CLOCK_SYS		57
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 00/20] add additional clocks and frac/mash support
  2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
                   ` (18 preceding siblings ...)
  2016-02-28 15:37 ` [PATCH v5 19/20] clk: bcm2835: add gates that require PM_DEBUG to be set kernel at martin.sperl.org
@ 2016-02-28 17:48 ` Stefan Wahren
  19 siblings, 0 replies; 23+ messages in thread
From: Stefan Wahren @ 2016-02-28 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Martin,

> kernel at martin.sperl.org hat am 28. Februar 2016 um 16:36 geschrieben:
>
>
> From: Martin Sperl <kernel@martin.sperl.org>
>
> Fix issues found with current driver with regards to:
> * coding style
> * locking
> * setting register instead of bits in register
> * the use of BCM2835_CLOCK_COUNT in the device tree bindings
>
> adds:
> * frac/mash support (with correct limits)
> * exposing of additional clock parameters in debugfs
> (registers, divider and parent)
> * added all the missing pll dividers
> * almost all so far undefined clocks
>
> [...]
>
> Martin Sperl (20):
> clk: bcm2835: pll_off should only set CM_PLL_ANARST
> [...]
> clk: bcm2835: add locking to pll*_on/off methods
> [...]
> clk: bcm2835: enable clocks that have been enabled by firmware

i suggest you separate these 3 important fixes out of these series to get them
faster in.

Regards
Stefan

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 01/20] clk: bcm2835: pll_off should only set CM_PLL_ANARST
  2016-02-28 15:36 ` [PATCH v5 01/20] clk: bcm2835: pll_off should only set CM_PLL_ANARST kernel at martin.sperl.org
@ 2016-02-28 17:58   ` Stefan Wahren
  0 siblings, 0 replies; 23+ messages in thread
From: Stefan Wahren @ 2016-02-28 17:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Martin,

> kernel at martin.sperl.org hat am 28. Februar 2016 um 16:36 geschrieben:
>
>
> From: Martin Sperl <kernel@martin.sperl.org>
>
> bcm2835_pll_off is currently assigning CM_PLL_ANARST
> to the control register.
>
> This patch only sets the CM_PLL_ANARST bit
> not resetting any of the other bits, which allows
> restoring the register to its original value
> via bcm2834_pll_on.
>
> Signed-off-by: Martin Sperl <kernel@martin.sperl.org>

Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain
clocks")

> ---
> drivers/clk/bcm/clk-bcm2835.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
> index 5747a9d..d3009a6 100644
> --- a/drivers/clk/bcm/clk-bcm2835.c
> +++ b/drivers/clk/bcm/clk-bcm2835.c
> @@ -913,8 +913,12 @@ static void bcm2835_pll_off(struct clk_hw *hw)
> struct bcm2835_cprman *cprman = pll->cprman;
> const struct bcm2835_pll_data *data = pll->data;
>
> - cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
> - cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
> + cprman_write(cprman, data->cm_ctrl_reg,
> + cprman_read(cprman, data->cm_ctrl_reg) |
> + CM_PLL_ANARST);
> + cprman_write(cprman, data->a2w_ctrl_reg,
> + cprman_read(cprman, data->a2w_ctrl_reg) |
> + A2W_PLL_CTRL_PWRDN);

Since this change adds a RMW cycle we should add the spinlocks for
bcm2835_pll_off here and not in 03/20.

Regards
Stefan

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 03/20] clk: bcm2835: add locking to pll*_on/off methods
  2016-02-28 15:36 ` [PATCH v5 03/20] clk: bcm2835: add locking to pll*_on/off methods kernel at martin.sperl.org
@ 2016-02-28 18:04   ` Stefan Wahren
  0 siblings, 0 replies; 23+ messages in thread
From: Stefan Wahren @ 2016-02-28 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Martin,

> kernel at martin.sperl.org hat am 28. Februar 2016 um 16:36 geschrieben:
>
>
> From: Martin Sperl <kernel@martin.sperl.org>
>
> Add missing locking to:
> * bcm2835_pll_on
> * bcm2835_pll_off
> * bcm2835_pll_divider_on

this should be obvious. Please explain the why.

>
> Signed-off-by: Martin Sperl <kernel@martin.sperl.org>

Fixes: 41691b8862e2 ("clk: bcm2835: Add support for programming the audio domain
clocks")

> ---
> drivers/clk/bcm/clk-bcm2835.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
> index 3aa3e7a..d999a13 100644
> --- a/drivers/clk/bcm/clk-bcm2835.c
> +++ b/drivers/clk/bcm/clk-bcm2835.c
> @@ -910,12 +910,14 @@ static void bcm2835_pll_off(struct clk_hw *hw)
> struct bcm2835_cprman *cprman = pll->cprman;
> const struct bcm2835_pll_data *data = pll->data;
>
> + spin_lock(&cprman->regs_lock);
> cprman_write(cprman, data->cm_ctrl_reg,
> cprman_read(cprman, data->cm_ctrl_reg) |
> CM_PLL_ANARST);
> cprman_write(cprman, data->a2w_ctrl_reg,
> cprman_read(cprman, data->a2w_ctrl_reg) |
> A2W_PLL_CTRL_PWRDN);
> + spin_unlock(&cprman->regs_lock);
> }

As i told please move this particular change into 01/20, the rest is okay.

Regards
Stefan

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2016-02-28 18:04 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 01/20] clk: bcm2835: pll_off should only set CM_PLL_ANARST kernel at martin.sperl.org
2016-02-28 17:58   ` Stefan Wahren
2016-02-28 15:36 ` [PATCH v5 02/20] clk: bcm2835: clean up coding style issues kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 03/20] clk: bcm2835: add locking to pll*_on/off methods kernel at martin.sperl.org
2016-02-28 18:04   ` Stefan Wahren
2016-02-28 15:36 ` [PATCH v5 04/20] clk: bcm2835: remove uart0/1_pclk fixed clocks kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 05/20] clk: bcm2835: enable clocks that have been enabled by firmware kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 06/20] clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in driver kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 07/20] clk: bcm2835: reorganize bcm2835_clock_array assignment kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 08/20] clk: bcm2835: add fractional support kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 09/20] clk: bcm2835: enable management of PCM clock kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 10/20] clk: bcm2835: implement correct clamping for mash clocks kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 11/20] clk: bcm2835: divider value has to be 1 or more kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 12/20] clk: bcm2835: expose raw clock-registers via debugfs kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 13/20] clk: bcm2835: expose current divider, parent and mash " kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 14/20] clk: bcm2835: added missing PLL clock divider kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 15/20] clk: bcm2835: add additional clocks kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 16/20] clk: bcm2835: add the camera related clocks cam0, cam1 and ccp2 kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 17/20] clk: bcm2835: add the dsi clocks kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 18/20] clk: bcm2835: add arm clock kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 19/20] clk: bcm2835: add gates that require PM_DEBUG to be set kernel at martin.sperl.org
2016-02-28 17:48 ` [PATCH v5 00/20] add additional clocks and frac/mash support Stefan Wahren

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).