]> Git Repo - linux.git/blob - drivers/clk/clk-versaclock5.c
net: Call into DSA netdevice_ops wrappers
[linux.git] / drivers / clk / clk-versaclock5.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Driver for IDT Versaclock 5
4  *
5  * Copyright (C) 2017 Marek Vasut <[email protected]>
6  */
7
8 /*
9  * Possible optimizations:
10  * - Use spread spectrum
11  * - Use integer divider in FOD if applicable
12  */
13
14 #include <linux/clk.h>
15 #include <linux/clk-provider.h>
16 #include <linux/delay.h>
17 #include <linux/i2c.h>
18 #include <linux/interrupt.h>
19 #include <linux/mod_devicetable.h>
20 #include <linux/module.h>
21 #include <linux/of.h>
22 #include <linux/of_platform.h>
23 #include <linux/rational.h>
24 #include <linux/regmap.h>
25 #include <linux/slab.h>
26
27 /* VersaClock5 registers */
28 #define VC5_OTP_CONTROL                         0x00
29
30 /* Factory-reserved register block */
31 #define VC5_RSVD_DEVICE_ID                      0x01
32 #define VC5_RSVD_ADC_GAIN_7_0                   0x02
33 #define VC5_RSVD_ADC_GAIN_15_8                  0x03
34 #define VC5_RSVD_ADC_OFFSET_7_0                 0x04
35 #define VC5_RSVD_ADC_OFFSET_15_8                0x05
36 #define VC5_RSVD_TEMPY                          0x06
37 #define VC5_RSVD_OFFSET_TBIN                    0x07
38 #define VC5_RSVD_GAIN                           0x08
39 #define VC5_RSVD_TEST_NP                        0x09
40 #define VC5_RSVD_UNUSED                         0x0a
41 #define VC5_RSVD_BANDGAP_TRIM_UP                0x0b
42 #define VC5_RSVD_BANDGAP_TRIM_DN                0x0c
43 #define VC5_RSVD_CLK_R_12_CLK_AMP_4             0x0d
44 #define VC5_RSVD_CLK_R_34_CLK_AMP_4             0x0e
45 #define VC5_RSVD_CLK_AMP_123                    0x0f
46
47 /* Configuration register block */
48 #define VC5_PRIM_SRC_SHDN                       0x10
49 #define VC5_PRIM_SRC_SHDN_EN_XTAL               BIT(7)
50 #define VC5_PRIM_SRC_SHDN_EN_CLKIN              BIT(6)
51 #define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ   BIT(3)
52 #define VC5_PRIM_SRC_SHDN_SP                    BIT(1)
53 #define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN           BIT(0)
54
55 #define VC5_VCO_BAND                            0x11
56 #define VC5_XTAL_X1_LOAD_CAP                    0x12
57 #define VC5_XTAL_X2_LOAD_CAP                    0x13
58 #define VC5_REF_DIVIDER                         0x15
59 #define VC5_REF_DIVIDER_SEL_PREDIV2             BIT(7)
60 #define VC5_REF_DIVIDER_REF_DIV(n)              ((n) & 0x3f)
61
62 #define VC5_VCO_CTRL_AND_PREDIV                 0x16
63 #define VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV   BIT(7)
64
65 #define VC5_FEEDBACK_INT_DIV                    0x17
66 #define VC5_FEEDBACK_INT_DIV_BITS               0x18
67 #define VC5_FEEDBACK_FRAC_DIV(n)                (0x19 + (n))
68 #define VC5_RC_CONTROL0                         0x1e
69 #define VC5_RC_CONTROL1                         0x1f
70 /* Register 0x20 is factory reserved */
71
72 /* Output divider control for divider 1,2,3,4 */
73 #define VC5_OUT_DIV_CONTROL(idx)        (0x21 + ((idx) * 0x10))
74 #define VC5_OUT_DIV_CONTROL_RESET       BIT(7)
75 #define VC5_OUT_DIV_CONTROL_SELB_NORM   BIT(3)
76 #define VC5_OUT_DIV_CONTROL_SEL_EXT     BIT(2)
77 #define VC5_OUT_DIV_CONTROL_INT_MODE    BIT(1)
78 #define VC5_OUT_DIV_CONTROL_EN_FOD      BIT(0)
79
80 #define VC5_OUT_DIV_FRAC(idx, n)        (0x22 + ((idx) * 0x10) + (n))
81 #define VC5_OUT_DIV_FRAC4_OD_SCEE       BIT(1)
82
83 #define VC5_OUT_DIV_STEP_SPREAD(idx, n) (0x26 + ((idx) * 0x10) + (n))
84 #define VC5_OUT_DIV_SPREAD_MOD(idx, n)  (0x29 + ((idx) * 0x10) + (n))
85 #define VC5_OUT_DIV_SKEW_INT(idx, n)    (0x2b + ((idx) * 0x10) + (n))
86 #define VC5_OUT_DIV_INT(idx, n)         (0x2d + ((idx) * 0x10) + (n))
87 #define VC5_OUT_DIV_SKEW_FRAC(idx)      (0x2f + ((idx) * 0x10))
88 /* Registers 0x30, 0x40, 0x50 are factory reserved */
89
90 /* Clock control register for clock 1,2 */
91 #define VC5_CLK_OUTPUT_CFG(idx, n)      (0x60 + ((idx) * 0x2) + (n))
92 #define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF   BIT(0)
93
94 #define VC5_CLK_OE_SHDN                         0x68
95 #define VC5_CLK_OS_SHDN                         0x69
96
97 #define VC5_GLOBAL_REGISTER                     0x76
98 #define VC5_GLOBAL_REGISTER_GLOBAL_RESET        BIT(5)
99
100 /* PLL/VCO runs between 2.5 GHz and 3.0 GHz */
101 #define VC5_PLL_VCO_MIN                         2500000000UL
102 #define VC5_PLL_VCO_MAX                         3000000000UL
103
104 /* VC5 Input mux settings */
105 #define VC5_MUX_IN_XIN          BIT(0)
106 #define VC5_MUX_IN_CLKIN        BIT(1)
107
108 /* Maximum number of clk_out supported by this driver */
109 #define VC5_MAX_CLK_OUT_NUM     5
110
111 /* Maximum number of FODs supported by this driver */
112 #define VC5_MAX_FOD_NUM 4
113
114 /* flags to describe chip features */
115 /* chip has built-in oscilator */
116 #define VC5_HAS_INTERNAL_XTAL   BIT(0)
117 /* chip has PFD requency doubler */
118 #define VC5_HAS_PFD_FREQ_DBL    BIT(1)
119
120 /* Supported IDT VC5 models. */
121 enum vc5_model {
122         IDT_VC5_5P49V5923,
123         IDT_VC5_5P49V5925,
124         IDT_VC5_5P49V5933,
125         IDT_VC5_5P49V5935,
126         IDT_VC6_5P49V6901,
127         IDT_VC6_5P49V6965,
128 };
129
130 /* Structure to describe features of a particular VC5 model */
131 struct vc5_chip_info {
132         const enum vc5_model    model;
133         const unsigned int      clk_fod_cnt;
134         const unsigned int      clk_out_cnt;
135         const u32               flags;
136 };
137
138 struct vc5_driver_data;
139
140 struct vc5_hw_data {
141         struct clk_hw           hw;
142         struct vc5_driver_data  *vc5;
143         u32                     div_int;
144         u32                     div_frc;
145         unsigned int            num;
146 };
147
148 struct vc5_driver_data {
149         struct i2c_client       *client;
150         struct regmap           *regmap;
151         const struct vc5_chip_info      *chip_info;
152
153         struct clk              *pin_xin;
154         struct clk              *pin_clkin;
155         unsigned char           clk_mux_ins;
156         struct clk_hw           clk_mux;
157         struct clk_hw           clk_mul;
158         struct clk_hw           clk_pfd;
159         struct vc5_hw_data      clk_pll;
160         struct vc5_hw_data      clk_fod[VC5_MAX_FOD_NUM];
161         struct vc5_hw_data      clk_out[VC5_MAX_CLK_OUT_NUM];
162 };
163
164 static const char * const vc5_mux_names[] = {
165         "mux"
166 };
167
168 static const char * const vc5_dbl_names[] = {
169         "dbl"
170 };
171
172 static const char * const vc5_pfd_names[] = {
173         "pfd"
174 };
175
176 static const char * const vc5_pll_names[] = {
177         "pll"
178 };
179
180 static const char * const vc5_fod_names[] = {
181         "fod0", "fod1", "fod2", "fod3",
182 };
183
184 static const char * const vc5_clk_out_names[] = {
185         "out0_sel_i2cb", "out1", "out2", "out3", "out4",
186 };
187
188 /*
189  * VersaClock5 i2c regmap
190  */
191 static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
192 {
193         /* Factory reserved regs, make them read-only */
194         if (reg <= 0xf)
195                 return false;
196
197         /* Factory reserved regs, make them read-only */
198         if (reg == 0x14 || reg == 0x1c || reg == 0x1d)
199                 return false;
200
201         return true;
202 }
203
204 static const struct regmap_config vc5_regmap_config = {
205         .reg_bits = 8,
206         .val_bits = 8,
207         .cache_type = REGCACHE_RBTREE,
208         .max_register = 0x76,
209         .writeable_reg = vc5_regmap_is_writeable,
210 };
211
212 /*
213  * VersaClock5 input multiplexer between XTAL and CLKIN divider
214  */
215 static unsigned char vc5_mux_get_parent(struct clk_hw *hw)
216 {
217         struct vc5_driver_data *vc5 =
218                 container_of(hw, struct vc5_driver_data, clk_mux);
219         const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
220         unsigned int src;
221
222         regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &src);
223         src &= mask;
224
225         if (src == VC5_PRIM_SRC_SHDN_EN_XTAL)
226                 return 0;
227
228         if (src == VC5_PRIM_SRC_SHDN_EN_CLKIN)
229                 return 1;
230
231         dev_warn(&vc5->client->dev,
232                  "Invalid clock input configuration (%02x)\n", src);
233         return 0;
234 }
235
236 static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
237 {
238         struct vc5_driver_data *vc5 =
239                 container_of(hw, struct vc5_driver_data, clk_mux);
240         const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
241         u8 src;
242
243         if ((index > 1) || !vc5->clk_mux_ins)
244                 return -EINVAL;
245
246         if (vc5->clk_mux_ins == (VC5_MUX_IN_CLKIN | VC5_MUX_IN_XIN)) {
247                 if (index == 0)
248                         src = VC5_PRIM_SRC_SHDN_EN_XTAL;
249                 if (index == 1)
250                         src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
251         } else {
252                 if (index != 0)
253                         return -EINVAL;
254
255                 if (vc5->clk_mux_ins == VC5_MUX_IN_XIN)
256                         src = VC5_PRIM_SRC_SHDN_EN_XTAL;
257                 else if (vc5->clk_mux_ins == VC5_MUX_IN_CLKIN)
258                         src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
259                 else /* Invalid; should have been caught by vc5_probe() */
260                         return -EINVAL;
261         }
262
263         return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src);
264 }
265
266 static const struct clk_ops vc5_mux_ops = {
267         .set_parent     = vc5_mux_set_parent,
268         .get_parent     = vc5_mux_get_parent,
269 };
270
271 static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw,
272                                          unsigned long parent_rate)
273 {
274         struct vc5_driver_data *vc5 =
275                 container_of(hw, struct vc5_driver_data, clk_mul);
276         unsigned int premul;
277
278         regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul);
279         if (premul & VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ)
280                 parent_rate *= 2;
281
282         return parent_rate;
283 }
284
285 static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate,
286                                unsigned long *parent_rate)
287 {
288         if ((*parent_rate == rate) || ((*parent_rate * 2) == rate))
289                 return rate;
290         else
291                 return -EINVAL;
292 }
293
294 static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate,
295                             unsigned long parent_rate)
296 {
297         struct vc5_driver_data *vc5 =
298                 container_of(hw, struct vc5_driver_data, clk_mul);
299         u32 mask;
300
301         if ((parent_rate * 2) == rate)
302                 mask = VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ;
303         else
304                 mask = 0;
305
306         regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN,
307                            VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ,
308                            mask);
309
310         return 0;
311 }
312
313 static const struct clk_ops vc5_dbl_ops = {
314         .recalc_rate    = vc5_dbl_recalc_rate,
315         .round_rate     = vc5_dbl_round_rate,
316         .set_rate       = vc5_dbl_set_rate,
317 };
318
319 static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw,
320                                          unsigned long parent_rate)
321 {
322         struct vc5_driver_data *vc5 =
323                 container_of(hw, struct vc5_driver_data, clk_pfd);
324         unsigned int prediv, div;
325
326         regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv);
327
328         /* The bypass_prediv is set, PLL fed from Ref_in directly. */
329         if (prediv & VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV)
330                 return parent_rate;
331
332         regmap_read(vc5->regmap, VC5_REF_DIVIDER, &div);
333
334         /* The Sel_prediv2 is set, PLL fed from prediv2 (Ref_in / 2) */
335         if (div & VC5_REF_DIVIDER_SEL_PREDIV2)
336                 return parent_rate / 2;
337         else
338                 return parent_rate / VC5_REF_DIVIDER_REF_DIV(div);
339 }
340
341 static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
342                                unsigned long *parent_rate)
343 {
344         unsigned long idiv;
345
346         /* PLL cannot operate with input clock above 50 MHz. */
347         if (rate > 50000000)
348                 return -EINVAL;
349
350         /* CLKIN within range of PLL input, feed directly to PLL. */
351         if (*parent_rate <= 50000000)
352                 return *parent_rate;
353
354         idiv = DIV_ROUND_UP(*parent_rate, rate);
355         if (idiv > 127)
356                 return -EINVAL;
357
358         return *parent_rate / idiv;
359 }
360
361 static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
362                             unsigned long parent_rate)
363 {
364         struct vc5_driver_data *vc5 =
365                 container_of(hw, struct vc5_driver_data, clk_pfd);
366         unsigned long idiv;
367         u8 div;
368
369         /* CLKIN within range of PLL input, feed directly to PLL. */
370         if (parent_rate <= 50000000) {
371                 regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
372                                    VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV,
373                                    VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV);
374                 regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, 0x00);
375                 return 0;
376         }
377
378         idiv = DIV_ROUND_UP(parent_rate, rate);
379
380         /* We have dedicated div-2 predivider. */
381         if (idiv == 2)
382                 div = VC5_REF_DIVIDER_SEL_PREDIV2;
383         else
384                 div = VC5_REF_DIVIDER_REF_DIV(idiv);
385
386         regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, div);
387         regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
388                            VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV, 0);
389
390         return 0;
391 }
392
393 static const struct clk_ops vc5_pfd_ops = {
394         .recalc_rate    = vc5_pfd_recalc_rate,
395         .round_rate     = vc5_pfd_round_rate,
396         .set_rate       = vc5_pfd_set_rate,
397 };
398
399 /*
400  * VersaClock5 PLL/VCO
401  */
402 static unsigned long vc5_pll_recalc_rate(struct clk_hw *hw,
403                                          unsigned long parent_rate)
404 {
405         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
406         struct vc5_driver_data *vc5 = hwdata->vc5;
407         u32 div_int, div_frc;
408         u8 fb[5];
409
410         regmap_bulk_read(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
411
412         div_int = (fb[0] << 4) | (fb[1] >> 4);
413         div_frc = (fb[2] << 16) | (fb[3] << 8) | fb[4];
414
415         /* The PLL divider has 12 integer bits and 24 fractional bits */
416         return (parent_rate * div_int) + ((parent_rate * div_frc) >> 24);
417 }
418
419 static long vc5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
420                                unsigned long *parent_rate)
421 {
422         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
423         u32 div_int;
424         u64 div_frc;
425
426         if (rate < VC5_PLL_VCO_MIN)
427                 rate = VC5_PLL_VCO_MIN;
428         if (rate > VC5_PLL_VCO_MAX)
429                 rate = VC5_PLL_VCO_MAX;
430
431         /* Determine integer part, which is 12 bit wide */
432         div_int = rate / *parent_rate;
433         if (div_int > 0xfff)
434                 rate = *parent_rate * 0xfff;
435
436         /* Determine best fractional part, which is 24 bit wide */
437         div_frc = rate % *parent_rate;
438         div_frc *= BIT(24) - 1;
439         do_div(div_frc, *parent_rate);
440
441         hwdata->div_int = div_int;
442         hwdata->div_frc = (u32)div_frc;
443
444         return (*parent_rate * div_int) + ((*parent_rate * div_frc) >> 24);
445 }
446
447 static int vc5_pll_set_rate(struct clk_hw *hw, unsigned long rate,
448                             unsigned long parent_rate)
449 {
450         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
451         struct vc5_driver_data *vc5 = hwdata->vc5;
452         u8 fb[5];
453
454         fb[0] = hwdata->div_int >> 4;
455         fb[1] = hwdata->div_int << 4;
456         fb[2] = hwdata->div_frc >> 16;
457         fb[3] = hwdata->div_frc >> 8;
458         fb[4] = hwdata->div_frc;
459
460         return regmap_bulk_write(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
461 }
462
463 static const struct clk_ops vc5_pll_ops = {
464         .recalc_rate    = vc5_pll_recalc_rate,
465         .round_rate     = vc5_pll_round_rate,
466         .set_rate       = vc5_pll_set_rate,
467 };
468
469 static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw,
470                                          unsigned long parent_rate)
471 {
472         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
473         struct vc5_driver_data *vc5 = hwdata->vc5;
474         /* VCO frequency is divided by two before entering FOD */
475         u32 f_in = parent_rate / 2;
476         u32 div_int, div_frc;
477         u8 od_int[2];
478         u8 od_frc[4];
479
480         regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_INT(hwdata->num, 0),
481                          od_int, 2);
482         regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
483                          od_frc, 4);
484
485         div_int = (od_int[0] << 4) | (od_int[1] >> 4);
486         div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) |
487                   (od_frc[2] << 6) | (od_frc[3] >> 2);
488
489         /* Avoid division by zero if the output is not configured. */
490         if (div_int == 0 && div_frc == 0)
491                 return 0;
492
493         /* The PLL divider has 12 integer bits and 30 fractional bits */
494         return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
495 }
496
497 static long vc5_fod_round_rate(struct clk_hw *hw, unsigned long rate,
498                                unsigned long *parent_rate)
499 {
500         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
501         /* VCO frequency is divided by two before entering FOD */
502         u32 f_in = *parent_rate / 2;
503         u32 div_int;
504         u64 div_frc;
505
506         /* Determine integer part, which is 12 bit wide */
507         div_int = f_in / rate;
508         /*
509          * WARNING: The clock chip does not output signal if the integer part
510          *          of the divider is 0xfff and fractional part is non-zero.
511          *          Clamp the divider at 0xffe to keep the code simple.
512          */
513         if (div_int > 0xffe) {
514                 div_int = 0xffe;
515                 rate = f_in / div_int;
516         }
517
518         /* Determine best fractional part, which is 30 bit wide */
519         div_frc = f_in % rate;
520         div_frc <<= 24;
521         do_div(div_frc, rate);
522
523         hwdata->div_int = div_int;
524         hwdata->div_frc = (u32)div_frc;
525
526         return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
527 }
528
529 static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate,
530                             unsigned long parent_rate)
531 {
532         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
533         struct vc5_driver_data *vc5 = hwdata->vc5;
534         u8 data[14] = {
535                 hwdata->div_frc >> 22, hwdata->div_frc >> 14,
536                 hwdata->div_frc >> 6, hwdata->div_frc << 2,
537                 0, 0, 0, 0, 0,
538                 0, 0,
539                 hwdata->div_int >> 4, hwdata->div_int << 4,
540                 0
541         };
542
543         regmap_bulk_write(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
544                           data, 14);
545
546         /*
547          * Toggle magic bit in undocumented register for unknown reason.
548          * This is what the IDT timing commander tool does and the chip
549          * datasheet somewhat implies this is needed, but the register
550          * and the bit is not documented.
551          */
552         regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
553                            VC5_GLOBAL_REGISTER_GLOBAL_RESET, 0);
554         regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
555                            VC5_GLOBAL_REGISTER_GLOBAL_RESET,
556                            VC5_GLOBAL_REGISTER_GLOBAL_RESET);
557         return 0;
558 }
559
560 static const struct clk_ops vc5_fod_ops = {
561         .recalc_rate    = vc5_fod_recalc_rate,
562         .round_rate     = vc5_fod_round_rate,
563         .set_rate       = vc5_fod_set_rate,
564 };
565
566 static int vc5_clk_out_prepare(struct clk_hw *hw)
567 {
568         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
569         struct vc5_driver_data *vc5 = hwdata->vc5;
570         const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
571                         VC5_OUT_DIV_CONTROL_SEL_EXT |
572                         VC5_OUT_DIV_CONTROL_EN_FOD;
573         unsigned int src;
574         int ret;
575
576         /*
577          * If the input mux is disabled, enable it first and
578          * select source from matching FOD.
579          */
580         regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
581         if ((src & mask) == 0) {
582                 src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD;
583                 ret = regmap_update_bits(vc5->regmap,
584                                          VC5_OUT_DIV_CONTROL(hwdata->num),
585                                          mask | VC5_OUT_DIV_CONTROL_RESET, src);
586                 if (ret)
587                         return ret;
588         }
589
590         /* Enable the clock buffer */
591         regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
592                            VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
593                            VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
594         return 0;
595 }
596
597 static void vc5_clk_out_unprepare(struct clk_hw *hw)
598 {
599         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
600         struct vc5_driver_data *vc5 = hwdata->vc5;
601
602         /* Disable the clock buffer */
603         regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
604                            VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0);
605 }
606
607 static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
608 {
609         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
610         struct vc5_driver_data *vc5 = hwdata->vc5;
611         const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
612                         VC5_OUT_DIV_CONTROL_SEL_EXT |
613                         VC5_OUT_DIV_CONTROL_EN_FOD;
614         const u8 fodclkmask = VC5_OUT_DIV_CONTROL_SELB_NORM |
615                               VC5_OUT_DIV_CONTROL_EN_FOD;
616         const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
617                           VC5_OUT_DIV_CONTROL_SEL_EXT;
618         unsigned int src;
619
620         regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
621         src &= mask;
622
623         if (src == 0)   /* Input mux set to DISABLED */
624                 return 0;
625
626         if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD)
627                 return 0;
628
629         if (src == extclk)
630                 return 1;
631
632         dev_warn(&vc5->client->dev,
633                  "Invalid clock output configuration (%02x)\n", src);
634         return 0;
635 }
636
637 static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
638 {
639         struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
640         struct vc5_driver_data *vc5 = hwdata->vc5;
641         const u8 mask = VC5_OUT_DIV_CONTROL_RESET |
642                         VC5_OUT_DIV_CONTROL_SELB_NORM |
643                         VC5_OUT_DIV_CONTROL_SEL_EXT |
644                         VC5_OUT_DIV_CONTROL_EN_FOD;
645         const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
646                           VC5_OUT_DIV_CONTROL_SEL_EXT;
647         u8 src = VC5_OUT_DIV_CONTROL_RESET;
648
649         if (index == 0)
650                 src |= VC5_OUT_DIV_CONTROL_EN_FOD;
651         else
652                 src |= extclk;
653
654         return regmap_update_bits(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num),
655                                   mask, src);
656 }
657
658 static const struct clk_ops vc5_clk_out_ops = {
659         .prepare        = vc5_clk_out_prepare,
660         .unprepare      = vc5_clk_out_unprepare,
661         .set_parent     = vc5_clk_out_set_parent,
662         .get_parent     = vc5_clk_out_get_parent,
663 };
664
665 static struct clk_hw *vc5_of_clk_get(struct of_phandle_args *clkspec,
666                                      void *data)
667 {
668         struct vc5_driver_data *vc5 = data;
669         unsigned int idx = clkspec->args[0];
670
671         if (idx >= vc5->chip_info->clk_out_cnt)
672                 return ERR_PTR(-EINVAL);
673
674         return &vc5->clk_out[idx].hw;
675 }
676
677 static int vc5_map_index_to_output(const enum vc5_model model,
678                                    const unsigned int n)
679 {
680         switch (model) {
681         case IDT_VC5_5P49V5933:
682                 return (n == 0) ? 0 : 3;
683         case IDT_VC5_5P49V5923:
684         case IDT_VC5_5P49V5925:
685         case IDT_VC5_5P49V5935:
686         case IDT_VC6_5P49V6901:
687         case IDT_VC6_5P49V6965:
688         default:
689                 return n;
690         }
691 }
692
693 static const struct of_device_id clk_vc5_of_match[];
694
695 static int vc5_probe(struct i2c_client *client,
696                      const struct i2c_device_id *id)
697 {
698         struct vc5_driver_data *vc5;
699         struct clk_init_data init;
700         const char *parent_names[2];
701         unsigned int n, idx = 0;
702         int ret;
703
704         vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
705         if (vc5 == NULL)
706                 return -ENOMEM;
707
708         i2c_set_clientdata(client, vc5);
709         vc5->client = client;
710         vc5->chip_info = of_device_get_match_data(&client->dev);
711
712         vc5->pin_xin = devm_clk_get(&client->dev, "xin");
713         if (PTR_ERR(vc5->pin_xin) == -EPROBE_DEFER)
714                 return -EPROBE_DEFER;
715
716         vc5->pin_clkin = devm_clk_get(&client->dev, "clkin");
717         if (PTR_ERR(vc5->pin_clkin) == -EPROBE_DEFER)
718                 return -EPROBE_DEFER;
719
720         vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
721         if (IS_ERR(vc5->regmap)) {
722                 dev_err(&client->dev, "failed to allocate register map\n");
723                 return PTR_ERR(vc5->regmap);
724         }
725
726         /* Register clock input mux */
727         memset(&init, 0, sizeof(init));
728
729         if (!IS_ERR(vc5->pin_xin)) {
730                 vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
731                 parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
732         } else if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL) {
733                 vc5->pin_xin = clk_register_fixed_rate(&client->dev,
734                                                        "internal-xtal", NULL,
735                                                        0, 25000000);
736                 if (IS_ERR(vc5->pin_xin))
737                         return PTR_ERR(vc5->pin_xin);
738                 vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
739                 parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
740         }
741
742         if (!IS_ERR(vc5->pin_clkin)) {
743                 vc5->clk_mux_ins |= VC5_MUX_IN_CLKIN;
744                 parent_names[init.num_parents++] =
745                         __clk_get_name(vc5->pin_clkin);
746         }
747
748         if (!init.num_parents) {
749                 dev_err(&client->dev, "no input clock specified!\n");
750                 return -EINVAL;
751         }
752
753         init.name = vc5_mux_names[0];
754         init.ops = &vc5_mux_ops;
755         init.flags = 0;
756         init.parent_names = parent_names;
757         vc5->clk_mux.init = &init;
758         ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
759         if (ret) {
760                 dev_err(&client->dev, "unable to register %s\n", init.name);
761                 goto err_clk;
762         }
763
764         if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) {
765                 /* Register frequency doubler */
766                 memset(&init, 0, sizeof(init));
767                 init.name = vc5_dbl_names[0];
768                 init.ops = &vc5_dbl_ops;
769                 init.flags = CLK_SET_RATE_PARENT;
770                 init.parent_names = vc5_mux_names;
771                 init.num_parents = 1;
772                 vc5->clk_mul.init = &init;
773                 ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul);
774                 if (ret) {
775                         dev_err(&client->dev, "unable to register %s\n",
776                                 init.name);
777                         goto err_clk;
778                 }
779         }
780
781         /* Register PFD */
782         memset(&init, 0, sizeof(init));
783         init.name = vc5_pfd_names[0];
784         init.ops = &vc5_pfd_ops;
785         init.flags = CLK_SET_RATE_PARENT;
786         if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL)
787                 init.parent_names = vc5_dbl_names;
788         else
789                 init.parent_names = vc5_mux_names;
790         init.num_parents = 1;
791         vc5->clk_pfd.init = &init;
792         ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd);
793         if (ret) {
794                 dev_err(&client->dev, "unable to register %s\n", init.name);
795                 goto err_clk;
796         }
797
798         /* Register PLL */
799         memset(&init, 0, sizeof(init));
800         init.name = vc5_pll_names[0];
801         init.ops = &vc5_pll_ops;
802         init.flags = CLK_SET_RATE_PARENT;
803         init.parent_names = vc5_pfd_names;
804         init.num_parents = 1;
805         vc5->clk_pll.num = 0;
806         vc5->clk_pll.vc5 = vc5;
807         vc5->clk_pll.hw.init = &init;
808         ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
809         if (ret) {
810                 dev_err(&client->dev, "unable to register %s\n", init.name);
811                 goto err_clk;
812         }
813
814         /* Register FODs */
815         for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
816                 idx = vc5_map_index_to_output(vc5->chip_info->model, n);
817                 memset(&init, 0, sizeof(init));
818                 init.name = vc5_fod_names[idx];
819                 init.ops = &vc5_fod_ops;
820                 init.flags = CLK_SET_RATE_PARENT;
821                 init.parent_names = vc5_pll_names;
822                 init.num_parents = 1;
823                 vc5->clk_fod[n].num = idx;
824                 vc5->clk_fod[n].vc5 = vc5;
825                 vc5->clk_fod[n].hw.init = &init;
826                 ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
827                 if (ret) {
828                         dev_err(&client->dev, "unable to register %s\n",
829                                 init.name);
830                         goto err_clk;
831                 }
832         }
833
834         /* Register MUX-connected OUT0_I2C_SELB output */
835         memset(&init, 0, sizeof(init));
836         init.name = vc5_clk_out_names[0];
837         init.ops = &vc5_clk_out_ops;
838         init.flags = CLK_SET_RATE_PARENT;
839         init.parent_names = vc5_mux_names;
840         init.num_parents = 1;
841         vc5->clk_out[0].num = idx;
842         vc5->clk_out[0].vc5 = vc5;
843         vc5->clk_out[0].hw.init = &init;
844         ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
845         if (ret) {
846                 dev_err(&client->dev, "unable to register %s\n",
847                         init.name);
848                 goto err_clk;
849         }
850
851         /* Register FOD-connected OUTx outputs */
852         for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
853                 idx = vc5_map_index_to_output(vc5->chip_info->model, n - 1);
854                 parent_names[0] = vc5_fod_names[idx];
855                 if (n == 1)
856                         parent_names[1] = vc5_mux_names[0];
857                 else
858                         parent_names[1] = vc5_clk_out_names[n - 1];
859
860                 memset(&init, 0, sizeof(init));
861                 init.name = vc5_clk_out_names[idx + 1];
862                 init.ops = &vc5_clk_out_ops;
863                 init.flags = CLK_SET_RATE_PARENT;
864                 init.parent_names = parent_names;
865                 init.num_parents = 2;
866                 vc5->clk_out[n].num = idx;
867                 vc5->clk_out[n].vc5 = vc5;
868                 vc5->clk_out[n].hw.init = &init;
869                 ret = devm_clk_hw_register(&client->dev,
870                                            &vc5->clk_out[n].hw);
871                 if (ret) {
872                         dev_err(&client->dev, "unable to register %s\n",
873                                 init.name);
874                         goto err_clk;
875                 }
876         }
877
878         ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
879         if (ret) {
880                 dev_err(&client->dev, "unable to add clk provider\n");
881                 goto err_clk;
882         }
883
884         return 0;
885
886 err_clk:
887         if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
888                 clk_unregister_fixed_rate(vc5->pin_xin);
889         return ret;
890 }
891
892 static int vc5_remove(struct i2c_client *client)
893 {
894         struct vc5_driver_data *vc5 = i2c_get_clientdata(client);
895
896         of_clk_del_provider(client->dev.of_node);
897
898         if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
899                 clk_unregister_fixed_rate(vc5->pin_xin);
900
901         return 0;
902 }
903
904 static int __maybe_unused vc5_suspend(struct device *dev)
905 {
906         struct vc5_driver_data *vc5 = dev_get_drvdata(dev);
907
908         regcache_cache_only(vc5->regmap, true);
909         regcache_mark_dirty(vc5->regmap);
910
911         return 0;
912 }
913
914 static int __maybe_unused vc5_resume(struct device *dev)
915 {
916         struct vc5_driver_data *vc5 = dev_get_drvdata(dev);
917         int ret;
918
919         regcache_cache_only(vc5->regmap, false);
920         ret = regcache_sync(vc5->regmap);
921         if (ret)
922                 dev_err(dev, "Failed to restore register map: %d\n", ret);
923         return ret;
924 }
925
926 static const struct vc5_chip_info idt_5p49v5923_info = {
927         .model = IDT_VC5_5P49V5923,
928         .clk_fod_cnt = 2,
929         .clk_out_cnt = 3,
930         .flags = 0,
931 };
932
933 static const struct vc5_chip_info idt_5p49v5925_info = {
934         .model = IDT_VC5_5P49V5925,
935         .clk_fod_cnt = 4,
936         .clk_out_cnt = 5,
937         .flags = 0,
938 };
939
940 static const struct vc5_chip_info idt_5p49v5933_info = {
941         .model = IDT_VC5_5P49V5933,
942         .clk_fod_cnt = 2,
943         .clk_out_cnt = 3,
944         .flags = VC5_HAS_INTERNAL_XTAL,
945 };
946
947 static const struct vc5_chip_info idt_5p49v5935_info = {
948         .model = IDT_VC5_5P49V5935,
949         .clk_fod_cnt = 4,
950         .clk_out_cnt = 5,
951         .flags = VC5_HAS_INTERNAL_XTAL,
952 };
953
954 static const struct vc5_chip_info idt_5p49v6901_info = {
955         .model = IDT_VC6_5P49V6901,
956         .clk_fod_cnt = 4,
957         .clk_out_cnt = 5,
958         .flags = VC5_HAS_PFD_FREQ_DBL,
959 };
960
961 static const struct vc5_chip_info idt_5p49v6965_info = {
962         .model = IDT_VC6_5P49V6965,
963         .clk_fod_cnt = 4,
964         .clk_out_cnt = 5,
965         .flags = 0,
966 };
967
968 static const struct i2c_device_id vc5_id[] = {
969         { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
970         { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
971         { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
972         { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
973         { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
974         { "5p49v6965", .driver_data = IDT_VC6_5P49V6965 },
975         { }
976 };
977 MODULE_DEVICE_TABLE(i2c, vc5_id);
978
979 static const struct of_device_id clk_vc5_of_match[] = {
980         { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info },
981         { .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info },
982         { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info },
983         { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
984         { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
985         { .compatible = "idt,5p49v6965", .data = &idt_5p49v6965_info },
986         { },
987 };
988 MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
989
990 static SIMPLE_DEV_PM_OPS(vc5_pm_ops, vc5_suspend, vc5_resume);
991
992 static struct i2c_driver vc5_driver = {
993         .driver = {
994                 .name = "vc5",
995                 .pm     = &vc5_pm_ops,
996                 .of_match_table = clk_vc5_of_match,
997         },
998         .probe          = vc5_probe,
999         .remove         = vc5_remove,
1000         .id_table       = vc5_id,
1001 };
1002 module_i2c_driver(vc5_driver);
1003
1004 MODULE_AUTHOR("Marek Vasut <[email protected]>");
1005 MODULE_DESCRIPTION("IDT VersaClock 5 driver");
1006 MODULE_LICENSE("GPL");
This page took 0.091483 seconds and 4 git commands to generate.