The CDCE913 and CDCEL913 devices are modular PLL-based, low cost,
high performance , programmable clock synthesizers. They generate
upto 3 output clocks from a single input frequency. Each output can
be programmed for any clock-frequency.

Adding support for the same.

Reviewed-by: Tom Rini <tr...@konsulko.com>
Signed-off-by: Lokesh Vutla <lokeshvu...@ti.com>
---
Changes since v1:
- None

 arch/arm/cpu/armv7/am33xx/Makefile                 |   2 +
 arch/arm/cpu/armv7/am33xx/clk_synthesizer.c        | 104 +++++++++++++++++++++
 arch/arm/include/asm/arch-am33xx/clk_synthesizer.h |  43 +++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/am33xx/clk_synthesizer.c
 create mode 100644 arch/arm/include/asm/arch-am33xx/clk_synthesizer.h

diff --git a/arch/arm/cpu/armv7/am33xx/Makefile 
b/arch/arm/cpu/armv7/am33xx/Makefile
index aae3f09..6fda482 100644
--- a/arch/arm/cpu/armv7/am33xx/Makefile
+++ b/arch/arm/cpu/armv7/am33xx/Makefile
@@ -18,3 +18,5 @@ obj-y += ddr.o
 obj-y  += emif4.o
 obj-y  += board.o
 obj-y  += mux.o
+
+obj-$(CONFIG_CLOCK_SYNTHESIZER)        += clk_synthesizer.o
diff --git a/arch/arm/cpu/armv7/am33xx/clk_synthesizer.c 
b/arch/arm/cpu/armv7/am33xx/clk_synthesizer.c
new file mode 100644
index 0000000..316e677
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/clk_synthesizer.c
@@ -0,0 +1,104 @@
+/*
+ * clk-synthesizer.c
+ *
+ * Clock synthesizer apis
+ *
+ * Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+
+#include <common.h>
+#include <asm/arch/clk_synthesizer.h>
+#include <i2c.h>
+
+/**
+ * clk_synthesizer_reg_read - Read register from synthesizer.
+ * @addr:      addr within the i2c device
+ * buf:                Buffer to which value is to be read.
+ *
+ * For reading the register from this clock synthesizer, a command needs to
+ * be send along with enabling byte read more, and then read can happen.
+ * Returns 0 on success
+ */
+static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
+{
+       int rc;
+
+       /* Enable Bye read */
+       addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
+
+       /* Send the command byte */
+       rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
+       if (rc)
+               printf("Failed to send command to clock synthesizer\n");
+
+       /* Read the Data */
+       return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
+}
+
+/**
+ * clk_synthesizer_reg_write - Write a value to register in synthesizer.
+ * @addr:      addr within the i2c device
+ * val:                Value to be written in the addr.
+ *
+ * Enable the byte read mode in the address and start the i2c transfer.
+ * Returns 0 on success
+ */
+static int clk_synthesizer_reg_write(int addr, uint8_t val)
+{
+       uint8_t cmd[2];
+       int rc = 0;
+
+       /* Enable byte write */
+       cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
+       cmd[1] = val;
+
+       rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
+       if (rc)
+               printf("Clock synthesizer reg write failed at addr = 0x%x\n",
+                      addr);
+       return rc;
+}
+
+/**
+ * setup_clock_syntherizer - Program the clock synthesizer to get the desired
+ *                             frequency.
+ * @data: Data containing the desired output
+ *
+ * This is a PLL-based high performance synthesizer which gives 3 outputs
+ * as per the PLL_DIV and load capacitor programmed.
+ */
+int setup_clock_synthesizer(struct clk_synth *data)
+{
+       int rc;
+       uint8_t val;
+
+       rc =  i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
+       if (rc) {
+               printf("i2c probe failed at address 0x%x\n",
+                      CLK_SYNTHESIZER_I2C_ADDR);
+               return rc;
+       }
+
+       rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
+       if (val != data->id)
+               return rc;
+
+       /* Crystal Load capacitor selection */
+       rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
+       if (rc)
+               return rc;
+       rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
+       if (rc)
+               return rc;
+       rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
+       if (rc)
+               return rc;
+       rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
+       if (rc)
+               return rc;
+
+       return 0;
+}
diff --git a/arch/arm/include/asm/arch-am33xx/clk_synthesizer.h 
b/arch/arm/include/asm/arch-am33xx/clk_synthesizer.h
new file mode 100644
index 0000000..a5af012
--- /dev/null
+++ b/arch/arm/include/asm/arch-am33xx/clk_synthesizer.h
@@ -0,0 +1,43 @@
+/*
+ * clk-synthesizer.h
+ *
+ * Clock synthesizer header
+ *
+ * Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CLK_SYNTHESIZER_H
+#define __CLK_SYNTHESIZER_H
+
+#include <common.h>
+
+#define CLK_SYNTHESIZER_ID_REG         0x0
+#define CLK_SYNTHESIZER_XCSEL          0x05
+#define CLK_SYNTHESIZER_MUX_REG                0x14
+#define CLK_SYNTHESIZER_PDIV2_REG      0x16
+#define CLK_SYNTHESIZER_PDIV3_REG      0x17
+
+#define CLK_SYNTHESIZER_BYTE_MODE      0x80
+
+/**
+ * struct clk_synth: This structure holds data neeed for configuring
+ *                  for clock synthesizer.
+ * @id: The id of synthesizer
+ * @capacitor: value of the capacitor attached
+ * @mux: mux settings.
+ * @pdiv2: Div to be applied to second output
+ * @pdiv3: Div to be applied to third output
+ */
+struct clk_synth {
+       u32 id;
+       u32 capacitor;
+       u32 mux;
+       u32 pdiv2;
+       u32 pdiv3;
+};
+
+int setup_clock_synthesizer(struct clk_synth *data);
+
+#endif
-- 
2.8.2

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to