]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/armv7/am33xx/clk_synthesizer.c
316e677c65c7026d1a4de99f291eccfa171b542b
[people/ms/u-boot.git] / arch / arm / cpu / armv7 / am33xx / clk_synthesizer.c
1 /*
2 * clk-synthesizer.c
3 *
4 * Clock synthesizer apis
5 *
6 * Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 */
10
11
12 #include <common.h>
13 #include <asm/arch/clk_synthesizer.h>
14 #include <i2c.h>
15
16 /**
17 * clk_synthesizer_reg_read - Read register from synthesizer.
18 * @addr: addr within the i2c device
19 * buf: Buffer to which value is to be read.
20 *
21 * For reading the register from this clock synthesizer, a command needs to
22 * be send along with enabling byte read more, and then read can happen.
23 * Returns 0 on success
24 */
25 static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
26 {
27 int rc;
28
29 /* Enable Bye read */
30 addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
31
32 /* Send the command byte */
33 rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
34 if (rc)
35 printf("Failed to send command to clock synthesizer\n");
36
37 /* Read the Data */
38 return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
39 }
40
41 /**
42 * clk_synthesizer_reg_write - Write a value to register in synthesizer.
43 * @addr: addr within the i2c device
44 * val: Value to be written in the addr.
45 *
46 * Enable the byte read mode in the address and start the i2c transfer.
47 * Returns 0 on success
48 */
49 static int clk_synthesizer_reg_write(int addr, uint8_t val)
50 {
51 uint8_t cmd[2];
52 int rc = 0;
53
54 /* Enable byte write */
55 cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
56 cmd[1] = val;
57
58 rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
59 if (rc)
60 printf("Clock synthesizer reg write failed at addr = 0x%x\n",
61 addr);
62 return rc;
63 }
64
65 /**
66 * setup_clock_syntherizer - Program the clock synthesizer to get the desired
67 * frequency.
68 * @data: Data containing the desired output
69 *
70 * This is a PLL-based high performance synthesizer which gives 3 outputs
71 * as per the PLL_DIV and load capacitor programmed.
72 */
73 int setup_clock_synthesizer(struct clk_synth *data)
74 {
75 int rc;
76 uint8_t val;
77
78 rc = i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
79 if (rc) {
80 printf("i2c probe failed at address 0x%x\n",
81 CLK_SYNTHESIZER_I2C_ADDR);
82 return rc;
83 }
84
85 rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
86 if (val != data->id)
87 return rc;
88
89 /* Crystal Load capacitor selection */
90 rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
91 if (rc)
92 return rc;
93 rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
94 if (rc)
95 return rc;
96 rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
97 if (rc)
98 return rc;
99 rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
100 if (rc)
101 return rc;
102
103 return 0;
104 }