common: Drop linux/delay.h from common header
[oweals/u-boot.git] / board / freescale / common / idt8t49n222a_serdes_clk.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2013 Freescale Semiconductor, Inc.
4  * Author: Shaveta Leekha <shaveta@freescale.com>
5  */
6
7 #include "idt8t49n222a_serdes_clk.h"
8 #include <log.h>
9 #include <linux/delay.h>
10
11 #define DEVICE_ID_REG           0x00
12
13 static int check_pll_status(u8 idt_addr)
14 {
15         u8 val = 0;
16         int ret;
17
18         ret = i2c_read(idt_addr, 0x17, 1, &val, 1);
19         if (ret < 0) {
20                 printf("IDT:0x%x could not read status register from device.\n",
21                         idt_addr);
22                 return ret;
23         }
24
25         if (val & 0x04) {
26                 debug("idt8t49n222a PLL is LOCKED: %x\n", val);
27         } else {
28                 printf("idt8t49n222a PLL is not LOCKED: %x\n", val);
29                 return -1;
30         }
31
32         return 0;
33 }
34
35 int set_serdes_refclk(u8 idt_addr, u8 serdes_num,
36                         enum serdes_refclk refclk1,
37                         enum serdes_refclk refclk2, u8 feedback)
38 {
39         u8 dev_id = 0;
40         int i, ret;
41
42         debug("IDT:Configuring idt8t49n222a device at I2C address: 0x%2x\n",
43                 idt_addr);
44
45         ret = i2c_read(idt_addr, DEVICE_ID_REG, 1, &dev_id, 1);
46         if (ret < 0) {
47                 debug("IDT:0x%x could not read DEV_ID from device.\n",
48                         idt_addr);
49                 return ret;
50         }
51
52         if ((dev_id != 0x00) && (dev_id != 0x24) && (dev_id != 0x2a)) {
53                 debug("IDT: device at address 0x%x is not idt8t49n222a.\n",
54                         idt_addr);
55         }
56
57         if (serdes_num != 1 && serdes_num != 2) {
58                 debug("serdes_num should be 1 for SerDes1 and"
59                         " 2 for SerDes2.\n");
60                 return -1;
61         }
62
63         if ((refclk1 == SERDES_REFCLK_122_88 && refclk2 != SERDES_REFCLK_122_88)
64                 || (refclk1 != SERDES_REFCLK_122_88
65                         && refclk2 == SERDES_REFCLK_122_88)) {
66                 debug("Only one refclk at 122.88MHz is not supported."
67                         " Please set both refclk1 & refclk2 to 122.88MHz"
68                         " or both not to 122.88MHz.\n");
69                 return -1;
70         }
71
72         if (refclk1 != SERDES_REFCLK_100 && refclk1 != SERDES_REFCLK_122_88
73                                         && refclk1 != SERDES_REFCLK_125
74                                         && refclk1 != SERDES_REFCLK_156_25) {
75                 debug("refclk1 should be 100MHZ, 122.88MHz, 125MHz"
76                         " or 156.25MHz.\n");
77                 return -1;
78         }
79
80         if (refclk2 != SERDES_REFCLK_100 && refclk2 != SERDES_REFCLK_122_88
81                                         && refclk2 != SERDES_REFCLK_125
82                                         && refclk2 != SERDES_REFCLK_156_25) {
83                 debug("refclk2 should be 100MHZ, 122.88MHz, 125MHz"
84                         " or 156.25MHz.\n");
85                 return -1;
86         }
87
88         if (feedback != 0 && feedback != 1) {
89                 debug("valid values for feedback are 0(default) or 1.\n");
90                 return -1;
91         }
92
93         /* Configuring IDT for output refclks as
94          * Refclk1 = 122.88MHz  Refclk2 = 122.88MHz
95          */
96         if (refclk1 == SERDES_REFCLK_122_88 &&
97                         refclk2 == SERDES_REFCLK_122_88) {
98                 printf("Setting refclk1:122.88 and refclk2:122.88\n");
99                 for (i = 0; i < NUM_IDT_REGS; i++)
100                         i2c_reg_write(idt_addr, idt_conf_122_88[i][0],
101                                                 idt_conf_122_88[i][1]);
102
103                 if (feedback) {
104                         for (i = 0; i < NUM_IDT_REGS_FEEDBACK; i++)
105                                 i2c_reg_write(idt_addr,
106                                         idt_conf_122_88_feedback[i][0],
107                                         idt_conf_122_88_feedback[i][1]);
108                 }
109         }
110
111         if (refclk1 != SERDES_REFCLK_122_88 &&
112                         refclk2 != SERDES_REFCLK_122_88) {
113                 for (i = 0; i < NUM_IDT_REGS; i++)
114                         i2c_reg_write(idt_addr, idt_conf_not_122_88[i][0],
115                                                 idt_conf_not_122_88[i][1]);
116         }
117
118         /* Configuring IDT for output refclks as
119          * Refclk1 = 100MHz  Refclk2 = 125MHz
120          */
121         if (refclk1 == SERDES_REFCLK_100 && refclk2 == SERDES_REFCLK_125) {
122                 printf("Setting refclk1:100 and refclk2:125\n");
123                 i2c_reg_write(idt_addr, 0x11, 0x10);
124         }
125
126         /* Configuring IDT for output refclks as
127          * Refclk1 = 125MHz  Refclk2 = 125MHz
128          */
129         if (refclk1 == SERDES_REFCLK_125 && refclk2 == SERDES_REFCLK_125) {
130                 printf("Setting refclk1:125 and refclk2:125\n");
131                 i2c_reg_write(idt_addr, 0x10, 0x10);
132                 i2c_reg_write(idt_addr, 0x11, 0x10);
133         }
134
135         /* Configuring IDT for output refclks as
136          * Refclk1 = 125MHz  Refclk2 = 100MHz
137          */
138         if (refclk1 == SERDES_REFCLK_125 && refclk2 == SERDES_REFCLK_100) {
139                 printf("Setting refclk1:125 and refclk2:100\n");
140                 i2c_reg_write(idt_addr, 0x10, 0x10);
141         }
142
143         /* Configuring IDT for output refclks as
144          * Refclk1 = 156.25MHz  Refclk2 = 156.25MHz
145          */
146         if (refclk1 == SERDES_REFCLK_156_25 &&
147                         refclk2 == SERDES_REFCLK_156_25) {
148                 printf("Setting refclk1:156.25 and refclk2:156.25\n");
149                 for (i = 0; i < NUM_IDT_REGS_156_25; i++)
150                         i2c_reg_write(idt_addr, idt_conf_156_25[i][0],
151                                                 idt_conf_156_25[i][1]);
152         }
153
154         /* Configuring IDT for output refclks as
155          * Refclk1 = 100MHz  Refclk2 = 156.25MHz
156          */
157         if (refclk1 == SERDES_REFCLK_100 &&
158                         refclk2 == SERDES_REFCLK_156_25) {
159                 printf("Setting refclk1:100 and refclk2:156.25\n");
160                 for (i = 0; i < NUM_IDT_REGS_156_25; i++)
161                         i2c_reg_write(idt_addr, idt_conf_100_156_25[i][0],
162                                                 idt_conf_100_156_25[i][1]);
163         }
164
165         /* Configuring IDT for output refclks as
166          * Refclk1 = 125MHz  Refclk2 = 156.25MHz
167          */
168         if (refclk1 == SERDES_REFCLK_125 &&
169                         refclk2 == SERDES_REFCLK_156_25) {
170                 printf("Setting refclk1:125 and refclk2:156.25\n");
171                 for (i = 0; i < NUM_IDT_REGS_156_25; i++)
172                         i2c_reg_write(idt_addr, idt_conf_125_156_25[i][0],
173                                                 idt_conf_125_156_25[i][1]);
174         }
175
176         /* Configuring IDT for output refclks as
177          * Refclk1 = 156.25MHz  Refclk2 = 100MHz
178          */
179         if (refclk1 == SERDES_REFCLK_156_25 &&
180                         refclk2 == SERDES_REFCLK_100) {
181                 printf("Setting refclk1:156.25 and refclk2:100\n");
182                 for (i = 0; i < NUM_IDT_REGS_156_25; i++)
183                         i2c_reg_write(idt_addr, idt_conf_156_25_100[i][0],
184                                                 idt_conf_156_25_100[i][1]);
185         }
186
187         /* Configuring IDT for output refclks as
188          * Refclk1 = 156.25MHz  Refclk2 = 125MHz
189          */
190         if (refclk1 == SERDES_REFCLK_156_25 &&
191                         refclk2 == SERDES_REFCLK_125) {
192                 printf("Setting refclk1:156.25 and refclk2:125\n");
193                 for (i = 0; i < NUM_IDT_REGS_156_25; i++)
194                         i2c_reg_write(idt_addr, idt_conf_156_25_125[i][0],
195                                                 idt_conf_156_25_125[i][1]);
196         }
197
198         /* waiting for maximum of 1 second if PLL doesn'r get locked
199          * initially. then check the status again.
200          */
201         if (check_pll_status(idt_addr)) {
202                 mdelay(1000);
203                 if (check_pll_status(idt_addr))
204                         return -1;
205         }
206
207         return 0;
208 }