ARM: AM33xx: Add support for Clock Synthesizer
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 <trini@konsulko.com> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
This commit is contained in:
parent
d8ff4fdb10
commit
3164f3c689
@ -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
|
||||
|
104
arch/arm/cpu/armv7/am33xx/clk_synthesizer.c
Normal file
104
arch/arm/cpu/armv7/am33xx/clk_synthesizer.c
Normal file
@ -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;
|
||||
}
|
43
arch/arm/include/asm/arch-am33xx/clk_synthesizer.h
Normal file
43
arch/arm/include/asm/arch-am33xx/clk_synthesizer.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user