1 // SPDX-License-Identifier: GPL-2.0-only
3 * Cobalt CPLD functions
5 * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates.
9 #include <linux/delay.h>
11 #include "cobalt-cpld.h"
13 #define ADRS(offset) (COBALT_BUS_CPLD_BASE + offset)
15 static u16
cpld_read(struct cobalt
*cobalt
, u32 offset
)
17 return cobalt_bus_read32(cobalt
->bar1
, ADRS(offset
));
20 static void cpld_write(struct cobalt
*cobalt
, u32 offset
, u16 val
)
22 return cobalt_bus_write32(cobalt
->bar1
, ADRS(offset
), val
);
25 static void cpld_info_ver3(struct cobalt
*cobalt
)
30 cobalt_info("CPLD System control register (read/write)\n");
31 cobalt_info("\t\tSystem control: 0x%04x (0x0f00)\n",
32 cpld_read(cobalt
, 0));
33 cobalt_info("CPLD Clock control register (read/write)\n");
34 cobalt_info("\t\tClock control: 0x%04x (0x0000)\n",
35 cpld_read(cobalt
, 0x04));
36 cobalt_info("CPLD HSMA Clk Osc register (read/write) - Must set wr trigger to load default values\n");
37 cobalt_info("\t\tRegister #7:\t0x%04x (0x0022)\n",
38 cpld_read(cobalt
, 0x08));
39 cobalt_info("\t\tRegister #8:\t0x%04x (0x0047)\n",
40 cpld_read(cobalt
, 0x0c));
41 cobalt_info("\t\tRegister #9:\t0x%04x (0x00fa)\n",
42 cpld_read(cobalt
, 0x10));
43 cobalt_info("\t\tRegister #10:\t0x%04x (0x0061)\n",
44 cpld_read(cobalt
, 0x14));
45 cobalt_info("\t\tRegister #11:\t0x%04x (0x001e)\n",
46 cpld_read(cobalt
, 0x18));
47 cobalt_info("\t\tRegister #12:\t0x%04x (0x0045)\n",
48 cpld_read(cobalt
, 0x1c));
49 cobalt_info("\t\tRegister #135:\t0x%04x\n",
50 cpld_read(cobalt
, 0x20));
51 cobalt_info("\t\tRegister #137:\t0x%04x\n",
52 cpld_read(cobalt
, 0x24));
53 cobalt_info("CPLD System status register (read only)\n");
54 cobalt_info("\t\tSystem status: 0x%04x\n",
55 cpld_read(cobalt
, 0x28));
56 cobalt_info("CPLD MAXII info register (read only)\n");
57 cobalt_info("\t\tBoard serial number: 0x%04x\n",
58 cpld_read(cobalt
, 0x2c));
59 cobalt_info("\t\tMAXII program revision: 0x%04x\n",
60 cpld_read(cobalt
, 0x30));
61 cobalt_info("CPLD temp and voltage ADT7411 registers (read only)\n");
62 cobalt_info("\t\tBoard temperature: %u Celsius\n",
63 cpld_read(cobalt
, 0x34) / 4);
64 cobalt_info("\t\tFPGA temperature: %u Celsius\n",
65 cpld_read(cobalt
, 0x38) / 4);
66 rd
= cpld_read(cobalt
, 0x3c);
67 tmp
= (rd
* 33 * 1000) / (483 * 10);
68 cobalt_info("\t\tVDD 3V3: %u,%03uV\n", tmp
/ 1000, tmp
% 1000);
69 rd
= cpld_read(cobalt
, 0x40);
70 tmp
= (rd
* 74 * 2197) / (27 * 1000);
71 cobalt_info("\t\tADC ch3 5V: %u,%03uV\n", tmp
/ 1000, tmp
% 1000);
72 rd
= cpld_read(cobalt
, 0x44);
73 tmp
= (rd
* 74 * 2197) / (47 * 1000);
74 cobalt_info("\t\tADC ch4 3V: %u,%03uV\n", tmp
/ 1000, tmp
% 1000);
75 rd
= cpld_read(cobalt
, 0x48);
76 tmp
= (rd
* 57 * 2197) / (47 * 1000);
77 cobalt_info("\t\tADC ch5 2V5: %u,%03uV\n", tmp
/ 1000, tmp
% 1000);
78 rd
= cpld_read(cobalt
, 0x4c);
79 tmp
= (rd
* 2197) / 1000;
80 cobalt_info("\t\tADC ch6 1V8: %u,%03uV\n", tmp
/ 1000, tmp
% 1000);
81 rd
= cpld_read(cobalt
, 0x50);
82 tmp
= (rd
* 2197) / 1000;
83 cobalt_info("\t\tADC ch7 1V5: %u,%03uV\n", tmp
/ 1000, tmp
% 1000);
84 rd
= cpld_read(cobalt
, 0x54);
85 tmp
= (rd
* 2197) / 1000;
86 cobalt_info("\t\tADC ch8 0V9: %u,%03uV\n", tmp
/ 1000, tmp
% 1000);
89 void cobalt_cpld_status(struct cobalt
*cobalt
)
91 u32 rev
= cpld_read(cobalt
, 0x30);
97 cpld_info_ver3(cobalt
);
100 cobalt_info("CPLD revision %u is not supported!\n", rev
);
105 #define DCO_MIN 4850000000ULL
106 #define DCO_MAX 5670000000ULL
108 #define SI570_CLOCK_CTRL 0x04
109 #define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_WR_TRIGGER 0x200
110 #define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_RST_TRIGGER 0x100
111 #define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL 0x80
112 #define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN 0x40
114 #define SI570_REG7 0x08
115 #define SI570_REG8 0x0c
116 #define SI570_REG9 0x10
117 #define SI570_REG10 0x14
118 #define SI570_REG11 0x18
119 #define SI570_REG12 0x1c
120 #define SI570_REG135 0x20
121 #define SI570_REG137 0x24
124 unsigned mult
, hsdiv
, n1
;
127 /* List all possible multipliers (= hsdiv * n1). There are lots of duplicates,
128 which are all removed in this list to keep the list as short as possible.
129 The values for hsdiv and n1 are the actual values, not the register values.
131 static const struct multiplier multipliers
[] = {
132 { 4, 4, 1 }, { 5, 5, 1 }, { 6, 6, 1 },
133 { 7, 7, 1 }, { 8, 4, 2 }, { 9, 9, 1 },
134 { 10, 5, 2 }, { 11, 11, 1 }, { 12, 6, 2 },
135 { 14, 7, 2 }, { 16, 4, 4 }, { 18, 9, 2 },
136 { 20, 5, 4 }, { 22, 11, 2 }, { 24, 4, 6 },
137 { 28, 7, 4 }, { 30, 5, 6 }, { 32, 4, 8 },
138 { 36, 6, 6 }, { 40, 4, 10 }, { 42, 7, 6 },
139 { 44, 11, 4 }, { 48, 4, 12 }, { 50, 5, 10 },
140 { 54, 9, 6 }, { 56, 4, 14 }, { 60, 5, 12 },
141 { 64, 4, 16 }, { 66, 11, 6 }, { 70, 5, 14 },
142 { 72, 4, 18 }, { 80, 4, 20 }, { 84, 6, 14 },
143 { 88, 11, 8 }, { 90, 5, 18 }, { 96, 4, 24 },
144 { 98, 7, 14 }, { 100, 5, 20 }, { 104, 4, 26 },
145 { 108, 6, 18 }, { 110, 11, 10 }, { 112, 4, 28 },
146 { 120, 4, 30 }, { 126, 7, 18 }, { 128, 4, 32 },
147 { 130, 5, 26 }, { 132, 11, 12 }, { 136, 4, 34 },
148 { 140, 5, 28 }, { 144, 4, 36 }, { 150, 5, 30 },
149 { 152, 4, 38 }, { 154, 11, 14 }, { 156, 6, 26 },
150 { 160, 4, 40 }, { 162, 9, 18 }, { 168, 4, 42 },
151 { 170, 5, 34 }, { 176, 11, 16 }, { 180, 5, 36 },
152 { 182, 7, 26 }, { 184, 4, 46 }, { 190, 5, 38 },
153 { 192, 4, 48 }, { 196, 7, 28 }, { 198, 11, 18 },
154 { 198, 9, 22 }, { 200, 4, 50 }, { 204, 6, 34 },
155 { 208, 4, 52 }, { 210, 5, 42 }, { 216, 4, 54 },
156 { 220, 11, 20 }, { 224, 4, 56 }, { 228, 6, 38 },
157 { 230, 5, 46 }, { 232, 4, 58 }, { 234, 9, 26 },
158 { 238, 7, 34 }, { 240, 4, 60 }, { 242, 11, 22 },
159 { 248, 4, 62 }, { 250, 5, 50 }, { 252, 6, 42 },
160 { 256, 4, 64 }, { 260, 5, 52 }, { 264, 11, 24 },
161 { 266, 7, 38 }, { 270, 5, 54 }, { 272, 4, 68 },
162 { 276, 6, 46 }, { 280, 4, 70 }, { 286, 11, 26 },
163 { 288, 4, 72 }, { 290, 5, 58 }, { 294, 7, 42 },
164 { 296, 4, 74 }, { 300, 5, 60 }, { 304, 4, 76 },
165 { 306, 9, 34 }, { 308, 11, 28 }, { 310, 5, 62 },
166 { 312, 4, 78 }, { 320, 4, 80 }, { 322, 7, 46 },
167 { 324, 6, 54 }, { 328, 4, 82 }, { 330, 11, 30 },
168 { 336, 4, 84 }, { 340, 5, 68 }, { 342, 9, 38 },
169 { 344, 4, 86 }, { 348, 6, 58 }, { 350, 5, 70 },
170 { 352, 11, 32 }, { 360, 4, 90 }, { 364, 7, 52 },
171 { 368, 4, 92 }, { 370, 5, 74 }, { 372, 6, 62 },
172 { 374, 11, 34 }, { 376, 4, 94 }, { 378, 7, 54 },
173 { 380, 5, 76 }, { 384, 4, 96 }, { 390, 5, 78 },
174 { 392, 4, 98 }, { 396, 11, 36 }, { 400, 4, 100 },
175 { 406, 7, 58 }, { 408, 4, 102 }, { 410, 5, 82 },
176 { 414, 9, 46 }, { 416, 4, 104 }, { 418, 11, 38 },
177 { 420, 5, 84 }, { 424, 4, 106 }, { 430, 5, 86 },
178 { 432, 4, 108 }, { 434, 7, 62 }, { 440, 11, 40 },
179 { 444, 6, 74 }, { 448, 4, 112 }, { 450, 5, 90 },
180 { 456, 4, 114 }, { 460, 5, 92 }, { 462, 11, 42 },
181 { 464, 4, 116 }, { 468, 6, 78 }, { 470, 5, 94 },
182 { 472, 4, 118 }, { 476, 7, 68 }, { 480, 4, 120 },
183 { 484, 11, 44 }, { 486, 9, 54 }, { 488, 4, 122 },
184 { 490, 5, 98 }, { 492, 6, 82 }, { 496, 4, 124 },
185 { 500, 5, 100 }, { 504, 4, 126 }, { 506, 11, 46 },
186 { 510, 5, 102 }, { 512, 4, 128 }, { 516, 6, 86 },
187 { 518, 7, 74 }, { 520, 5, 104 }, { 522, 9, 58 },
188 { 528, 11, 48 }, { 530, 5, 106 }, { 532, 7, 76 },
189 { 540, 5, 108 }, { 546, 7, 78 }, { 550, 11, 50 },
190 { 552, 6, 92 }, { 558, 9, 62 }, { 560, 5, 112 },
191 { 564, 6, 94 }, { 570, 5, 114 }, { 572, 11, 52 },
192 { 574, 7, 82 }, { 576, 6, 96 }, { 580, 5, 116 },
193 { 588, 6, 98 }, { 590, 5, 118 }, { 594, 11, 54 },
194 { 600, 5, 120 }, { 602, 7, 86 }, { 610, 5, 122 },
195 { 612, 6, 102 }, { 616, 11, 56 }, { 620, 5, 124 },
196 { 624, 6, 104 }, { 630, 5, 126 }, { 636, 6, 106 },
197 { 638, 11, 58 }, { 640, 5, 128 }, { 644, 7, 92 },
198 { 648, 6, 108 }, { 658, 7, 94 }, { 660, 11, 60 },
199 { 666, 9, 74 }, { 672, 6, 112 }, { 682, 11, 62 },
200 { 684, 6, 114 }, { 686, 7, 98 }, { 696, 6, 116 },
201 { 700, 7, 100 }, { 702, 9, 78 }, { 704, 11, 64 },
202 { 708, 6, 118 }, { 714, 7, 102 }, { 720, 6, 120 },
203 { 726, 11, 66 }, { 728, 7, 104 }, { 732, 6, 122 },
204 { 738, 9, 82 }, { 742, 7, 106 }, { 744, 6, 124 },
205 { 748, 11, 68 }, { 756, 6, 126 }, { 768, 6, 128 },
206 { 770, 11, 70 }, { 774, 9, 86 }, { 784, 7, 112 },
207 { 792, 11, 72 }, { 798, 7, 114 }, { 810, 9, 90 },
208 { 812, 7, 116 }, { 814, 11, 74 }, { 826, 7, 118 },
209 { 828, 9, 92 }, { 836, 11, 76 }, { 840, 7, 120 },
210 { 846, 9, 94 }, { 854, 7, 122 }, { 858, 11, 78 },
211 { 864, 9, 96 }, { 868, 7, 124 }, { 880, 11, 80 },
212 { 882, 7, 126 }, { 896, 7, 128 }, { 900, 9, 100 },
213 { 902, 11, 82 }, { 918, 9, 102 }, { 924, 11, 84 },
214 { 936, 9, 104 }, { 946, 11, 86 }, { 954, 9, 106 },
215 { 968, 11, 88 }, { 972, 9, 108 }, { 990, 11, 90 },
216 { 1008, 9, 112 }, { 1012, 11, 92 }, { 1026, 9, 114 },
217 { 1034, 11, 94 }, { 1044, 9, 116 }, { 1056, 11, 96 },
218 { 1062, 9, 118 }, { 1078, 11, 98 }, { 1080, 9, 120 },
219 { 1098, 9, 122 }, { 1100, 11, 100 }, { 1116, 9, 124 },
220 { 1122, 11, 102 }, { 1134, 9, 126 }, { 1144, 11, 104 },
221 { 1152, 9, 128 }, { 1166, 11, 106 }, { 1188, 11, 108 },
222 { 1210, 11, 110 }, { 1232, 11, 112 }, { 1254, 11, 114 },
223 { 1276, 11, 116 }, { 1298, 11, 118 }, { 1320, 11, 120 },
224 { 1342, 11, 122 }, { 1364, 11, 124 }, { 1386, 11, 126 },
228 bool cobalt_cpld_set_freq(struct cobalt
*cobalt
, unsigned f_out
)
230 const unsigned f_xtal
= 39170000; /* xtal for si598 */
233 unsigned delta
= 0xffffffff;
241 for (i
= 0; i
< ARRAY_SIZE(multipliers
); i
++) {
242 unsigned mult
= multipliers
[i
].mult
;
245 dco
= (u64
)f_out
* mult
;
246 if (dco
< DCO_MIN
|| dco
> DCO_MAX
)
248 div_u64_rem((dco
<< 28) + f_xtal
/ 2, f_xtal
, &d
);
257 dco
= (u64
)f_out
* multipliers
[i_best
].mult
;
258 n1
= multipliers
[i_best
].n1
- 1;
259 hsdiv
= multipliers
[i_best
].hsdiv
- 4;
260 rfreq
= div_u64(dco
<< 28, f_xtal
);
262 cpld_read(cobalt
, SI570_CLOCK_CTRL
);
264 regs
[0] = (hsdiv
<< 5) | (n1
>> 2);
265 regs
[1] = ((n1
& 0x3) << 6) | (rfreq
>> 32);
266 regs
[2] = (rfreq
>> 24) & 0xff;
267 regs
[3] = (rfreq
>> 16) & 0xff;
268 regs
[4] = (rfreq
>> 8) & 0xff;
269 regs
[5] = rfreq
& 0xff;
271 /* The sequence of clock_ctrl flags to set is very weird. It looks
272 like I have to reset it, then set the new frequency and reset it
273 again. It shouldn't be necessary to do a reset, but if I don't,
274 then a strange frequency is set (156.412034 MHz, or register values
275 0x01, 0xc7, 0xfc, 0x7f, 0x53, 0x62).
278 cobalt_dbg(1, "%u: %6ph\n", f_out
, regs
);
283 cpld_write(cobalt
, SI570_CLOCK_CTRL
,
284 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN
|
285 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL
);
286 usleep_range(10000, 15000);
287 cpld_write(cobalt
, SI570_REG7
, regs
[0]);
288 cpld_write(cobalt
, SI570_REG8
, regs
[1]);
289 cpld_write(cobalt
, SI570_REG9
, regs
[2]);
290 cpld_write(cobalt
, SI570_REG10
, regs
[3]);
291 cpld_write(cobalt
, SI570_REG11
, regs
[4]);
292 cpld_write(cobalt
, SI570_REG12
, regs
[5]);
293 cpld_write(cobalt
, SI570_CLOCK_CTRL
,
294 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN
|
295 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_WR_TRIGGER
);
296 usleep_range(10000, 15000);
297 cpld_write(cobalt
, SI570_CLOCK_CTRL
,
298 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN
|
299 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL
);
300 usleep_range(10000, 15000);
301 read_regs
[0] = cpld_read(cobalt
, SI570_REG7
);
302 read_regs
[1] = cpld_read(cobalt
, SI570_REG8
);
303 read_regs
[2] = cpld_read(cobalt
, SI570_REG9
);
304 read_regs
[3] = cpld_read(cobalt
, SI570_REG10
);
305 read_regs
[4] = cpld_read(cobalt
, SI570_REG11
);
306 read_regs
[5] = cpld_read(cobalt
, SI570_REG12
);
307 cpld_write(cobalt
, SI570_CLOCK_CTRL
,
308 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN
|
309 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL
|
310 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_RST_TRIGGER
);
311 usleep_range(10000, 15000);
312 cpld_write(cobalt
, SI570_CLOCK_CTRL
,
313 S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN
);
314 usleep_range(10000, 15000);
316 if (!memcmp(read_regs
, regs
, sizeof(read_regs
)))
318 cobalt_dbg(1, "retry: %6ph\n", read_regs
);
321 cobalt_info("Needed %d retries\n", 2 - retries
);