[PATCH] Add TI CDCE925 I2C controlled clock synthesizer driver

2014-10-24 Thread Mike Looijmans
This driver supports the TI CDCE925 programmable clock synthesizer.
The chip contains two PLLs with spread-spectrum clocking support and
five output dividers. The driver only supports the following setup,
and uses a fixed setting for the output muxes:
  Y1 is derived from the input clock
  Y2 and Y3 derive from PLL1
  Y4 and Y5 derive from PLL2
Given a target output frequency, the driver will set the PLL and
divider to best approximate the desired output.

Signed-off-by: Mike Looijmans 
---
 drivers/clk/Kconfig   |   17 +
 drivers/clk/Makefile  |1 +
 drivers/clk/clk-cdce925.c |  784 +
 3 files changed, 802 insertions(+)
 create mode 100644 drivers/clk/clk-cdce925.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 6f56d3a..a898ef6 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -64,6 +64,23 @@ config COMMON_CLK_SI570
  This driver supports Silicon Labs 570/571/598/599 programmable
  clock generators.
 
+config COMMON_CLK_CDCE925
+   tristate "Clock driver for TI CDCE925 devices"
+   depends on I2C
+   depends on OF
+   select REGMAP_I2C
+   help
+   ---help---
+ This driver supports the TI CDCE925 programmable clock synthesizer.
+ The chip contains two PLLs with spread-spectrum clocking support and
+ five output dividers. The driver only supports the following setup,
+ and uses a fixed setting for the output muxes.
+ Y1 is derived from the input clock
+ Y2 and Y3 derive from PLL1
+ Y4 and Y5 derive from PLL2
+ Given a target output frequency, the driver will set the PLL and
+ divider to best approximate the desired output.
+
 config COMMON_CLK_S2MPS11
tristate "Clock driver for S2MPS11/S5M8767 MFD"
depends on MFD_SEC_CORE
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 5f8a287..cdd1d06 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)   += clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_SI5351)+= clk-si5351.o
 obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
+obj-$(CONFIG_COMMON_CLK_CDCE925)   += clk-cdce925.o
 obj-$(CONFIG_CLK_TWL6040)  += clk-twl6040.o
 obj-$(CONFIG_ARCH_U300)+= clk-u300.o
 obj-$(CONFIG_ARCH_VT8500)  += clk-vt8500.o
diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
new file mode 100644
index 000..e7fbe0a
--- /dev/null
+++ b/drivers/clk/clk-cdce925.c
@@ -0,0 +1,784 @@
+/*
+ * Driver for TI Dual PLL CDCE925 clock synthesizer
+ *
+ * This driver always connects the Y1 to the input clock, Y2/Y3 to PLL1
+ * and Y4/Y5 to PLL2. PLL frequency is set on a first-come-first-serve
+ * basis. Clients can directly request any frequency that the chip can
+ * deliver using the standard clk framework. In addition, the device can
+ * be configured and activated via the devicetree.
+ *
+ * Copyright (C) 2014, Topic Embedded Products
+ * Licenced under GPL
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* The chip has 2 PLLs which can be routed through dividers to 5 outputs.
+ * Model this as 2 PLL clocks which are parents to the outputs.
+ */
+#define NUMBER_OF_PLLS 2
+#define NUMBER_OF_OUTPUTS  5
+
+#define CDCE925_REG_GLOBAL10x01
+#define CDCE925_REG_Y1SPIPDIVH 0x02
+#define CDCE925_REG_PDIVL  0x03
+#define CDCE925_REG_XCSEL  0x05
+/* PLL parameters start at 0x10, steps of 0x10 */
+#define CDCE925_OFFSET_PLL 0x10
+/* Add CDCE925_OFFSET_PLL * (pll) to these registers before sending */
+#define CDCE925_PLL_MUX_OUTPUTS0x14
+#define CDCE925_PLL_MULDIV 0x18
+
+#define CDCE925_PLL_FREQUENCY_MIN   8000
+#define CDCE925_PLL_FREQUENCY_MAX  23000
+struct clk_cdce925_chip;
+
+struct clk_cdce925_output {
+   struct clk_hw hw;
+   struct clk_cdce925_chip *chip;
+   u8 index;
+   u16 pdiv; /* 1..127 for Y2-Y5; 1..1023 for Y1 */
+};
+#define to_clk_cdce925_output(_hw) \
+   container_of(_hw, struct clk_cdce925_output, hw)
+
+struct clk_cdce925_pll {
+   struct clk_hw hw;
+   struct clk_cdce925_chip *chip;
+   u8 index;
+   u16 m;   /* 1..511 */
+   u16 n;   /* 1..4095 */
+};
+#define to_clk_cdce925_pll(_hw)container_of(_hw, struct 
clk_cdce925_pll, hw)
+
+struct clk_cdce925_chip {
+   struct regmap *regmap;
+   struct i2c_client *i2c_client;
+   struct clk_cdce925_pll pll[NUMBER_OF_PLLS];
+   struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS];
+};
+
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+static unsigned long cdce925_pll_calculate_rate(unsigned long parent_rate,
+   u16 n, u16 m)
+{
+   if ((!m || !n) || (m == n))
+   return parent_rate; /* In bypass mode runs at same frequency 

[PATCH] Add TI CDCE925 I2C controlled clock synthesizer driver

2014-10-24 Thread Mike Looijmans
This driver supports the TI CDCE925 programmable clock synthesizer.
The chip contains two PLLs with spread-spectrum clocking support and
five output dividers. The driver only supports the following setup,
and uses a fixed setting for the output muxes:
  Y1 is derived from the input clock
  Y2 and Y3 derive from PLL1
  Y4 and Y5 derive from PLL2
Given a target output frequency, the driver will set the PLL and
divider to best approximate the desired output.

Signed-off-by: Mike Looijmans mike.looijm...@topic.nl
---
 drivers/clk/Kconfig   |   17 +
 drivers/clk/Makefile  |1 +
 drivers/clk/clk-cdce925.c |  784 +
 3 files changed, 802 insertions(+)
 create mode 100644 drivers/clk/clk-cdce925.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 6f56d3a..a898ef6 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -64,6 +64,23 @@ config COMMON_CLK_SI570
  This driver supports Silicon Labs 570/571/598/599 programmable
  clock generators.
 
+config COMMON_CLK_CDCE925
+   tristate Clock driver for TI CDCE925 devices
+   depends on I2C
+   depends on OF
+   select REGMAP_I2C
+   help
+   ---help---
+ This driver supports the TI CDCE925 programmable clock synthesizer.
+ The chip contains two PLLs with spread-spectrum clocking support and
+ five output dividers. The driver only supports the following setup,
+ and uses a fixed setting for the output muxes.
+ Y1 is derived from the input clock
+ Y2 and Y3 derive from PLL1
+ Y4 and Y5 derive from PLL2
+ Given a target output frequency, the driver will set the PLL and
+ divider to best approximate the desired output.
+
 config COMMON_CLK_S2MPS11
tristate Clock driver for S2MPS11/S5M8767 MFD
depends on MFD_SEC_CORE
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 5f8a287..cdd1d06 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)   += clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_SI5351)+= clk-si5351.o
 obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
+obj-$(CONFIG_COMMON_CLK_CDCE925)   += clk-cdce925.o
 obj-$(CONFIG_CLK_TWL6040)  += clk-twl6040.o
 obj-$(CONFIG_ARCH_U300)+= clk-u300.o
 obj-$(CONFIG_ARCH_VT8500)  += clk-vt8500.o
diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c
new file mode 100644
index 000..e7fbe0a
--- /dev/null
+++ b/drivers/clk/clk-cdce925.c
@@ -0,0 +1,784 @@
+/*
+ * Driver for TI Dual PLL CDCE925 clock synthesizer
+ *
+ * This driver always connects the Y1 to the input clock, Y2/Y3 to PLL1
+ * and Y4/Y5 to PLL2. PLL frequency is set on a first-come-first-serve
+ * basis. Clients can directly request any frequency that the chip can
+ * deliver using the standard clk framework. In addition, the device can
+ * be configured and activated via the devicetree.
+ *
+ * Copyright (C) 2014, Topic Embedded Products
+ * Licenced under GPL
+ */
+#include linux/clk-provider.h
+#include linux/clk-private.h
+#include linux/delay.h
+#include linux/module.h
+#include linux/i2c.h
+#include linux/regmap.h
+#include linux/slab.h
+#include linux/gcd.h
+
+/* The chip has 2 PLLs which can be routed through dividers to 5 outputs.
+ * Model this as 2 PLL clocks which are parents to the outputs.
+ */
+#define NUMBER_OF_PLLS 2
+#define NUMBER_OF_OUTPUTS  5
+
+#define CDCE925_REG_GLOBAL10x01
+#define CDCE925_REG_Y1SPIPDIVH 0x02
+#define CDCE925_REG_PDIVL  0x03
+#define CDCE925_REG_XCSEL  0x05
+/* PLL parameters start at 0x10, steps of 0x10 */
+#define CDCE925_OFFSET_PLL 0x10
+/* Add CDCE925_OFFSET_PLL * (pll) to these registers before sending */
+#define CDCE925_PLL_MUX_OUTPUTS0x14
+#define CDCE925_PLL_MULDIV 0x18
+
+#define CDCE925_PLL_FREQUENCY_MIN   8000
+#define CDCE925_PLL_FREQUENCY_MAX  23000
+struct clk_cdce925_chip;
+
+struct clk_cdce925_output {
+   struct clk_hw hw;
+   struct clk_cdce925_chip *chip;
+   u8 index;
+   u16 pdiv; /* 1..127 for Y2-Y5; 1..1023 for Y1 */
+};
+#define to_clk_cdce925_output(_hw) \
+   container_of(_hw, struct clk_cdce925_output, hw)
+
+struct clk_cdce925_pll {
+   struct clk_hw hw;
+   struct clk_cdce925_chip *chip;
+   u8 index;
+   u16 m;   /* 1..511 */
+   u16 n;   /* 1..4095 */
+};
+#define to_clk_cdce925_pll(_hw)container_of(_hw, struct 
clk_cdce925_pll, hw)
+
+struct clk_cdce925_chip {
+   struct regmap *regmap;
+   struct i2c_client *i2c_client;
+   struct clk_cdce925_pll pll[NUMBER_OF_PLLS];
+   struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS];
+};
+
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+static unsigned long cdce925_pll_calculate_rate(unsigned long parent_rate,
+