phy: rockchip-inno-mipi-dphy: enable PLL only when the PHY is power on
[firefly-linux-kernel-4.4.55.git] / drivers / phy / phy-rockchip-inno-mipi-dphy.c
1 /*
2  * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <linux/kernel.h>
16 #include <linux/clk.h>
17 #include <linux/clk-provider.h>
18 #include <linux/delay.h>
19 #include <linux/init.h>
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/regmap.h>
23 #include <linux/reset.h>
24 #include <linux/phy/phy.h>
25
26 #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l)))
27
28 /* Innosilicon MIPI D-PHY registers */
29 #define INNO_PHY_LANE_CTRL      0x00000
30 #define INNO_PHY_POWER_CTRL     0x00004
31 #define ANALOG_RESET_MASK       BIT(2)
32 #define ANALOG_RESET            BIT(2)
33 #define ANALOG_NORMAL           0
34 #define LDO_POWER_MASK          BIT(1)
35 #define LDO_POWER_DOWN          BIT(1)
36 #define LDO_POWER_ON            0
37 #define PLL_POWER_MASK          BIT(0)
38 #define PLL_POWER_DOWN          BIT(0)
39 #define PLL_POWER_ON            0
40 #define INNO_PHY_PLL_CTRL_0     0x0000c
41 #define FBDIV_HI_MASK           BIT(5)
42 #define FBDIV_HI(x)             UPDATE(x, 5, 5)
43 #define PREDIV_MASK             GENMASK(4, 0)
44 #define PREDIV(x)               UPDATE(x, 4, 0)
45 #define INNO_PHY_PLL_CTRL_1     0x00010
46 #define FBDIV_LO_MASK           GENMASK(7, 0)
47 #define FBDIV_LO(x)             UPDATE(x, 7, 0)
48 #define INNO_PHY_DIG_CTRL       0x00080
49 #define DIGITAL_RESET_MASK      BIT(0)
50 #define DIGITAL_NORMAL          BIT(0)
51 #define DIGITAL_RESET           0
52
53 #define INNO_CLOCK_LANE_REG_BASE        0x00100
54 #define INNO_DATA_LANE_0_REG_BASE       0x00180
55 #define INNO_DATA_LANE_1_REG_BASE       0x00200
56 #define INNO_DATA_LANE_2_REG_BASE       0x00280
57 #define INNO_DATA_LANE_3_REG_BASE       0x00300
58 #define INNO_MIPI_DPHY_MAX_REGISTER     (INNO_DATA_LANE_3_REG_BASE + \
59                                          T_TA_WAIT_OFFSET)
60
61 #define T_LPX_OFFSET            0x00014
62 #define T_HS_PREPARE_OFFSET     0x00018
63 #define T_HS_ZERO_OFFSET        0x0001c
64 #define T_HS_TRAIL_OFFSET       0x00020
65 #define T_HS_EXIT_OFFSET        0x00024
66 #define T_CLK_POST_OFFSET       0x00028
67 #define T_WAKUP_H_OFFSET        0x00030
68 #define T_WAKUP_L_OFFSET        0x00034
69 #define T_CLK_PRE_OFFSET        0x00038
70 #define T_TA_GO_OFFSET          0x00040
71 #define T_TA_SURE_OFFSET        0x00044
72 #define T_TA_WAIT_OFFSET        0x00048
73
74 #define T_LPX_MASK              GENMASK(5, 0)
75 #define T_LPX(x)                UPDATE(x, 5, 0)
76 #define T_HS_PREPARE_MASK       GENMASK(6, 0)
77 #define T_HS_PREPARE(x)         UPDATE(x, 6, 0)
78 #define T_HS_ZERO_MASK          GENMASK(5, 0)
79 #define T_HS_ZERO(x)            UPDATE(x, 5, 0)
80 #define T_HS_TRAIL_MASK         GENMASK(6, 0)
81 #define T_HS_TRAIL(x)           UPDATE(x, 6, 0)
82 #define T_HS_EXIT_MASK          GENMASK(4, 0)
83 #define T_HS_EXIT(x)            UPDATE(x, 4, 0)
84 #define T_CLK_POST_MASK         GENMASK(3, 0)
85 #define T_CLK_POST(x)           UPDATE(x, 3, 0)
86 #define T_WAKUP_H_MASK          GENMASK(1, 0)
87 #define T_WAKUP_H(x)            UPDATE(x, 1, 0)
88 #define T_WAKUP_L_MASK          GENMASK(7, 0)
89 #define T_WAKUP_L(x)            UPDATE(x, 7, 0)
90 #define T_CLK_PRE_MASK          GENMASK(3, 0)
91 #define T_CLK_PRE(x)            UPDATE(x, 3, 0)
92 #define T_TA_GO_MASK            GENMASK(5, 0)
93 #define T_TA_GO(x)              UPDATE(x, 5, 0)
94 #define T_TA_SURE_MASK          GENMASK(5, 0)
95 #define T_TA_SURE(x)            UPDATE(x, 5, 0)
96 #define T_TA_WAIT_MASK          GENMASK(5, 0)
97 #define T_TA_WAIT(x)            UPDATE(x, 5, 0)
98
99 enum lane_type {
100         CLOCK_LANE,
101         DATA_LANE_0,
102         DATA_LANE_1,
103         DATA_LANE_2,
104         DATA_LANE_3,
105 };
106
107 struct mipi_dphy_timing {
108         unsigned int clkmiss;
109         unsigned int clkpost;
110         unsigned int clkpre;
111         unsigned int clkprepare;
112         unsigned int clksettle;
113         unsigned int clktermen;
114         unsigned int clktrail;
115         unsigned int clkzero;
116         unsigned int dtermen;
117         unsigned int eot;
118         unsigned int hsexit;
119         unsigned int hsprepare;
120         unsigned int hszero;
121         unsigned int hssettle;
122         unsigned int hsskip;
123         unsigned int hstrail;
124         unsigned int init;
125         unsigned int lpx;
126         unsigned int taget;
127         unsigned int tago;
128         unsigned int tasure;
129         unsigned int wakeup;
130 };
131
132 struct inno_mipi_dphy_timing {
133         u8 lpx;
134         u8 hs_prepare;
135         u8 hs_zero;
136         u8 hs_trail;
137         u8 hs_exit;
138         u8 clk_post;
139         u8 wakup_h;
140         u8 wakup_l;
141         u8 clk_pre;
142         u8 ta_go;
143         u8 ta_sure;
144         u8 ta_wait;
145 };
146
147 struct inno_mipi_dphy {
148         struct device *dev;
149         struct clk *ref_clk;
150         struct regmap *regmap;
151         struct reset_control *rst;
152
153         unsigned int lanes;
154         unsigned long lane_rate;
155
156         struct {
157                 struct clk_hw hw;
158                 u8 prediv;
159                 u16 fbdiv;
160         } pll;
161 };
162
163 static const u32 lane_reg_offset[] = {
164         [CLOCK_LANE]  = INNO_CLOCK_LANE_REG_BASE,
165         [DATA_LANE_0] = INNO_DATA_LANE_0_REG_BASE,
166         [DATA_LANE_1] = INNO_DATA_LANE_1_REG_BASE,
167         [DATA_LANE_2] = INNO_DATA_LANE_2_REG_BASE,
168         [DATA_LANE_3] = INNO_DATA_LANE_3_REG_BASE,
169 };
170
171 #define FIXED_PARAM(_freq, _prepare, _clk_zero, _data_zero, _trail)     \
172 {       \
173         .max_freq = _freq,      \
174         .hs_prepare = _prepare, \
175         .clk_lane = {   \
176                 .hs_zero = _clk_zero,   \
177         },      \
178         .data_lane = {  \
179                 .hs_zero = _data_zero,  \
180         },      \
181         .hs_trail = _trail,     \
182 }
183
184 static const struct {
185         unsigned long max_freq;
186         u8 hs_prepare;
187         struct {
188                 u8 hs_zero;
189         } clk_lane;
190         struct {
191                 u8 hs_zero;
192         } data_lane;
193         u8 hs_trail;
194 } fixed_param_table[] = {
195         FIXED_PARAM(110,  0x20, 0x16, 0x02, 0x22),
196         FIXED_PARAM(150,  0x06, 0x16, 0x03, 0x45),
197         FIXED_PARAM(200,  0x18, 0x17, 0x04, 0x0b),
198         FIXED_PARAM(250,  0x05, 0x17, 0x05, 0x16),
199         FIXED_PARAM(300,  0x51, 0x18, 0x06, 0x2c),
200         FIXED_PARAM(400,  0x64, 0x19, 0x07, 0x33),
201         FIXED_PARAM(500,  0x20, 0x1b, 0x07, 0x4e),
202         FIXED_PARAM(600,  0x6a, 0x1d, 0x08, 0x3a),
203         FIXED_PARAM(700,  0x3e, 0x1e, 0x08, 0x6a),
204         FIXED_PARAM(800,  0x21, 0x1f, 0x09, 0x29),
205         FIXED_PARAM(1000, 0x09, 0x20, 0x09, 0x27),
206 };
207
208 static inline struct inno_mipi_dphy *hw_to_inno(struct clk_hw *hw)
209 {
210         return container_of(hw, struct inno_mipi_dphy, pll.hw);
211 }
212
213 static inline void inno_mipi_dphy_reset(struct inno_mipi_dphy *inno)
214 {
215         /* Reset analog */
216         regmap_update_bits(inno->regmap, INNO_PHY_POWER_CTRL,
217                            ANALOG_RESET_MASK, ANALOG_RESET);
218         udelay(1);
219         regmap_update_bits(inno->regmap, INNO_PHY_POWER_CTRL,
220                            ANALOG_RESET_MASK, ANALOG_NORMAL);
221         /* Reset digital */
222         regmap_update_bits(inno->regmap, INNO_PHY_DIG_CTRL,
223                            DIGITAL_RESET_MASK, DIGITAL_RESET);
224         udelay(1);
225         regmap_update_bits(inno->regmap, INNO_PHY_DIG_CTRL,
226                            DIGITAL_RESET_MASK, DIGITAL_NORMAL);
227 }
228
229 static inline void inno_mipi_dphy_lane_enable(struct inno_mipi_dphy *inno)
230 {
231         u8 map[] = {0x44, 0x4c, 0x5c, 0x7c};
232
233         regmap_update_bits(inno->regmap, INNO_PHY_LANE_CTRL,
234                            0x7c, map[inno->lanes - 1]);
235 }
236
237 static inline void inno_mipi_dphy_lane_disable(struct inno_mipi_dphy *inno)
238 {
239         regmap_update_bits(inno->regmap, INNO_PHY_LANE_CTRL, 0x7c, 0x00);
240 }
241
242 static void inno_mipi_dphy_pll_enable(struct inno_mipi_dphy *inno)
243 {
244         regmap_update_bits(inno->regmap, INNO_PHY_PLL_CTRL_0, FBDIV_HI_MASK |
245                            PREDIV_MASK, FBDIV_HI(inno->pll.fbdiv >> 8) |
246                            PREDIV(inno->pll.prediv));
247         regmap_update_bits(inno->regmap, INNO_PHY_PLL_CTRL_1,
248                            FBDIV_LO_MASK, FBDIV_LO(inno->pll.fbdiv));
249         regmap_update_bits(inno->regmap, INNO_PHY_POWER_CTRL,
250                            PLL_POWER_MASK | LDO_POWER_MASK,
251                            PLL_POWER_ON | LDO_POWER_ON);
252 }
253
254 static void inno_mipi_dphy_pll_disable(struct inno_mipi_dphy *inno)
255 {
256         regmap_update_bits(inno->regmap, INNO_PHY_POWER_CTRL,
257                            PLL_POWER_MASK | LDO_POWER_MASK,
258                            PLL_POWER_DOWN | LDO_POWER_DOWN);
259 }
260
261 static void mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
262                                          unsigned long period)
263 {
264         /* Global Operation Timing Parameters */
265         timing->clkmiss = 0;
266         timing->clkpost = 70 + 52 * period;
267         timing->clkpre = 8 * period;
268         timing->clkprepare = 65;
269         timing->clksettle = 95;
270         timing->clktermen = 0;
271         timing->clktrail = 80;
272         timing->clkzero = 260;
273         timing->dtermen = 0;
274         timing->eot = 0;
275         timing->hsexit = 120;
276         timing->hsprepare = 65 + 4 * period;
277         timing->hszero = 145 + 6 * period;
278         timing->hssettle = 85 + 6 * period;
279         timing->hsskip = 40;
280         timing->hstrail = max(8 * period, 60 + 4 * period);
281         timing->init = 100000;
282         timing->lpx = 60;
283         timing->taget = 5 * timing->lpx;
284         timing->tago = 4 * timing->lpx;
285         timing->tasure = 2 * timing->lpx;
286         timing->wakeup = 1000000;
287 }
288
289 static void inno_mipi_dphy_timing_update(struct inno_mipi_dphy *inno,
290                                          enum lane_type lane_type,
291                                          struct inno_mipi_dphy_timing *t)
292 {
293         u32 base = lane_reg_offset[lane_type];
294
295         regmap_update_bits(inno->regmap, base + T_HS_PREPARE_OFFSET,
296                            T_HS_PREPARE_MASK, T_HS_PREPARE(t->hs_prepare));
297         regmap_update_bits(inno->regmap, base + T_HS_ZERO_OFFSET,
298                            T_HS_ZERO_MASK, T_HS_ZERO(t->hs_zero));
299         regmap_update_bits(inno->regmap, base + T_HS_TRAIL_OFFSET,
300                            T_HS_TRAIL_MASK, T_HS_TRAIL(t->hs_trail));
301         regmap_update_bits(inno->regmap, base + T_HS_EXIT_OFFSET,
302                            T_HS_EXIT_MASK, T_HS_EXIT(t->hs_exit));
303
304         if (lane_type == CLOCK_LANE) {
305                 regmap_update_bits(inno->regmap, base + T_CLK_POST_OFFSET,
306                                    T_CLK_POST_MASK, T_CLK_POST(t->clk_post));
307                 regmap_update_bits(inno->regmap, base + T_CLK_PRE_OFFSET,
308                                    T_CLK_PRE_MASK, T_CLK_PRE(t->clk_pre));
309         }
310
311         regmap_update_bits(inno->regmap, base + T_WAKUP_H_OFFSET,
312                            T_WAKUP_H_MASK, T_WAKUP_H(t->wakup_h));
313         regmap_update_bits(inno->regmap, base + T_WAKUP_L_OFFSET,
314                            T_WAKUP_L_MASK, T_WAKUP_L(t->wakup_l));
315         regmap_update_bits(inno->regmap, base + T_LPX_OFFSET,
316                            T_LPX_MASK, T_LPX(t->lpx));
317         regmap_update_bits(inno->regmap, base + T_TA_GO_OFFSET,
318                            T_TA_GO_MASK, T_TA_GO(t->ta_go));
319         regmap_update_bits(inno->regmap, base + T_TA_SURE_OFFSET,
320                            T_TA_SURE_MASK, T_TA_SURE(t->ta_sure));
321         regmap_update_bits(inno->regmap, base + T_TA_WAIT_OFFSET,
322                            T_TA_WAIT_MASK, T_TA_WAIT(t->ta_wait));
323 }
324
325 static void inno_mipi_dphy_get_fixed_param(struct inno_mipi_dphy_timing *t,
326                                            unsigned long freq,
327                                            enum lane_type lane_type)
328 {
329         int i;
330
331         for (i = 0; i < ARRAY_SIZE(fixed_param_table); i++)
332                 if (freq <= fixed_param_table[i].max_freq)
333                         break;
334
335         if (i == ARRAY_SIZE(fixed_param_table))
336                 --i;
337
338         if (lane_type == CLOCK_LANE)
339                 t->hs_zero = fixed_param_table[i].clk_lane.hs_zero;
340         else
341                 t->hs_zero = fixed_param_table[i].data_lane.hs_zero;
342
343         t->hs_prepare = fixed_param_table[i].hs_prepare;
344         t->hs_trail = fixed_param_table[i].hs_trail;
345 }
346
347 static void inno_mipi_dphy_lane_timing_init(struct inno_mipi_dphy *inno,
348                                             enum lane_type lane_type)
349 {
350         struct mipi_dphy_timing timing;
351         struct inno_mipi_dphy_timing data;
352         unsigned long txbyteclk, txclkesc, UI;
353         unsigned int esc_clk_div;
354
355         memset(&timing, 0, sizeof(timing));
356         memset(&data, 0, sizeof(data));
357
358         txbyteclk = inno->lane_rate / 8;
359         esc_clk_div = DIV_ROUND_UP(txbyteclk, 20000000);
360         txclkesc = txbyteclk / esc_clk_div;
361         UI = DIV_ROUND_CLOSEST_ULL(NSEC_PER_SEC, inno->lane_rate);
362
363         mipi_dphy_timing_get_default(&timing, UI);
364         inno_mipi_dphy_get_fixed_param(&data, inno->lane_rate / USEC_PER_SEC,
365                                        lane_type);
366
367         data.hs_exit = DIV_ROUND_UP(timing.hsexit * txbyteclk, NSEC_PER_SEC);
368         data.clk_post = DIV_ROUND_UP(timing.clkpost * txbyteclk, NSEC_PER_SEC);
369         data.clk_pre = DIV_ROUND_UP(timing.clkpre * txbyteclk, NSEC_PER_SEC);
370         data.wakup_h = 0x3;
371         data.wakup_l = 0xff;
372         data.lpx = DIV_ROUND_UP(txbyteclk * timing.lpx, NSEC_PER_SEC);
373         if (data.lpx >= 2)
374                 data.lpx -= 2;
375         data.ta_go = DIV_ROUND_UP(timing.tago * txclkesc, NSEC_PER_SEC);
376         data.ta_sure = DIV_ROUND_UP(timing.tasure * txclkesc, NSEC_PER_SEC);
377         data.ta_wait = DIV_ROUND_UP(timing.taget * txclkesc, NSEC_PER_SEC);
378
379         inno_mipi_dphy_timing_update(inno, lane_type, &data);
380
381 #define TIMING_NS(x, freq) (((x) * (DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq))))
382         dev_dbg(inno->dev, "hs-exit=%lu, clk-post=%lu, clk-pre=%lu, lpx=%lu\n",
383                 TIMING_NS(data.hs_exit, txbyteclk),
384                 TIMING_NS(data.clk_post, txbyteclk),
385                 TIMING_NS(data.clk_pre, txbyteclk),
386                 TIMING_NS(data.lpx + 2, txbyteclk));
387         dev_dbg(inno->dev, "ta-go=%lu, ta-sure=%lu, ta-wait=%lu\n",
388                 TIMING_NS(data.ta_go, txclkesc),
389                 TIMING_NS(data.ta_sure, txclkesc),
390                 TIMING_NS(data.ta_wait, txclkesc));
391 }
392
393 static unsigned long inno_mipi_dphy_pll_rate_fixup(unsigned long fin,
394                                                    unsigned long rate,
395                                                    u8 *prediv, u16 *fbdiv)
396 {
397         unsigned long best_freq = 0;
398         unsigned long fout;
399         u8 min_prediv, max_prediv;
400         u8 _prediv, uninitialized_var(best_prediv);
401         u16 _fbdiv, uninitialized_var(best_fbdiv);
402         u32 min_delta = UINT_MAX;
403
404         /*
405          * The PLL output frequency can be calculated using a simple formula:
406          * PLL_Output_Frequency = (FREF / PREDIV * FBDIV) / 2
407          * PLL_Output_Frequency: it is equal to DDR-Clock-Frequency * 2
408          */
409         fout = 2 * rate;
410
411         /* constraint: 5Mhz < Fref / prediv < 40MHz */
412         min_prediv = DIV_ROUND_UP(fin, 40000000);
413         max_prediv = fin / 5000000;
414
415         for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
416                 u64 tmp;
417                 u32 delta;
418
419                 tmp = (u64)fout * _prediv;
420                 do_div(tmp, fin);
421                 _fbdiv = tmp;
422                 /*
423                  * The all possible settings of feedback divider are
424                  * 12, 13, 14, 16, ~ 511
425                  */
426                 if ((_fbdiv == 15) || (_fbdiv < 12) || (_fbdiv > 511))
427                         continue;
428                 tmp = (u64)_fbdiv * fin;
429                 do_div(tmp, _prediv);
430
431                 delta = abs(fout - tmp);
432                 if (delta < min_delta) {
433                         best_prediv = _prediv;
434                         best_fbdiv = _fbdiv;
435                         min_delta = delta;
436                         best_freq = tmp;
437                 }
438         }
439
440         if (best_freq) {
441                 *prediv = best_prediv;
442                 *fbdiv = best_fbdiv;
443         }
444
445         return best_freq / 2;
446 }
447
448 static void inno_mipi_dphy_timing_init(struct inno_mipi_dphy *inno)
449 {
450         switch (inno->lanes) {
451         case 4:
452                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_3);
453                 /* Fall through */
454         case 3:
455                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_2);
456                 /* Fall through */
457         case 2:
458                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_1);
459                 /* Fall through */
460         case 1:
461         default:
462                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_0);
463                 inno_mipi_dphy_lane_timing_init(inno, CLOCK_LANE);
464                 break;
465         }
466 }
467
468 static int inno_mipi_dphy_power_on(struct phy *phy)
469 {
470         struct inno_mipi_dphy *inno = phy_get_drvdata(phy);
471
472         inno_mipi_dphy_pll_enable(inno);
473         inno_mipi_dphy_lane_enable(inno);
474         inno_mipi_dphy_reset(inno);
475         inno_mipi_dphy_timing_init(inno);
476         udelay(1);
477
478         return 0;
479 }
480
481 static int inno_mipi_dphy_power_off(struct phy *phy)
482 {
483         struct inno_mipi_dphy *inno = phy_get_drvdata(phy);
484
485         inno_mipi_dphy_lane_disable(inno);
486         inno_mipi_dphy_pll_disable(inno);
487
488         return 0;
489 }
490
491 static const struct phy_ops inno_mipi_dphy_ops = {
492         .power_on  = inno_mipi_dphy_power_on,
493         .power_off = inno_mipi_dphy_power_off,
494         .owner     = THIS_MODULE,
495 };
496
497 static long inno_mipi_dphy_pll_clk_round_rate(struct clk_hw *hw,
498                                               unsigned long rate,
499                                               unsigned long *prate)
500 {
501         struct inno_mipi_dphy *inno = hw_to_inno(hw);
502         unsigned long fin = *prate;
503         unsigned long fout;
504         u16 fbdiv;
505         u8 prediv;
506
507         fout = inno_mipi_dphy_pll_rate_fixup(fin, rate, &prediv, &fbdiv);
508
509         dev_dbg(inno->dev, "%s: fin=%lu, req_rate=%lu\n",
510                 __func__, *prate, rate);
511         dev_dbg(inno->dev, "%s: fout=%lu, prediv=%u, fbdiv=%u\n",
512                 __func__, fout, prediv, fbdiv);
513
514         inno->pll.prediv = prediv;
515         inno->pll.fbdiv = fbdiv;
516
517         return fout;
518 }
519
520 static int inno_mipi_dphy_pll_clk_set_rate(struct clk_hw *hw,
521                                            unsigned long rate,
522                                            unsigned long parent_rate)
523 {
524         struct inno_mipi_dphy *inno = hw_to_inno(hw);
525
526         dev_dbg(inno->dev, "%s: rate: %lu Hz\n", __func__, rate);
527
528         inno->lane_rate = rate;
529
530         return 0;
531 }
532
533 static unsigned long
534 inno_mipi_dphy_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
535 {
536         struct inno_mipi_dphy *inno = hw_to_inno(hw);
537
538         dev_dbg(inno->dev, "%s: rate: %lu Hz\n", __func__, inno->lane_rate);
539
540         return inno->lane_rate;
541 }
542
543 static const struct clk_ops inno_mipi_dphy_pll_clk_ops = {
544         .round_rate = inno_mipi_dphy_pll_clk_round_rate,
545         .set_rate = inno_mipi_dphy_pll_clk_set_rate,
546         .recalc_rate = inno_mipi_dphy_pll_clk_recalc_rate,
547 };
548
549 static int inno_mipi_dphy_pll_register(struct inno_mipi_dphy *inno)
550 {
551         struct device *dev = inno->dev;
552         struct device_node *np = dev->of_node;
553         struct clk *clk;
554         const char *parent_name;
555         struct clk_init_data init;
556         int ret;
557
558         parent_name = __clk_get_name(inno->ref_clk);
559
560         ret = of_property_read_string(np, "clock-output-names", &init.name);
561         if (ret < 0) {
562                 dev_err(dev, "Missing clock-output-names property: %d\n", ret);
563                 return ret;
564         }
565
566         init.ops = &inno_mipi_dphy_pll_clk_ops;
567         init.parent_names = (const char * const *)&parent_name;
568         init.num_parents = 1;
569         init.flags = 0;
570
571         inno->pll.hw.init = &init;
572         clk = devm_clk_register(dev, &inno->pll.hw);
573         if (IS_ERR(clk)) {
574                 ret = PTR_ERR(clk);
575                 dev_err(dev, "failed to register PLL: %d\n", ret);
576                 return ret;
577         }
578
579         return of_clk_add_provider(np, of_clk_src_simple_get, clk);
580 }
581
582 static int inno_mipi_dphy_parse_dt(struct device_node *np,
583                                    struct inno_mipi_dphy *inno)
584 {
585         if (of_property_read_u32(np, "inno,lanes", &inno->lanes))
586                 inno->lanes = 4;
587
588         return 0;
589 }
590
591 static struct regmap_config inno_mipi_dphy_regmap_cfg = {
592         .reg_bits = 32,
593         .val_bits = 32,
594         .reg_stride = 4,
595         .max_register = INNO_MIPI_DPHY_MAX_REGISTER,
596 };
597
598 static int inno_mipi_dphy_probe(struct platform_device *pdev)
599 {
600         struct device *dev = &pdev->dev;
601         struct inno_mipi_dphy *inno;
602         struct phy_provider *phy_provider;
603         struct phy *phy;
604         struct resource *res;
605         void __iomem *regs;
606         int ret;
607
608         inno = devm_kzalloc(dev, sizeof(*inno), GFP_KERNEL);
609         if (!inno)
610                 return -ENOMEM;
611
612         inno->dev = dev;
613         platform_set_drvdata(pdev, inno);
614
615         ret = inno_mipi_dphy_parse_dt(dev->of_node, inno);
616         if (ret) {
617                 dev_err(dev, "failed to parse DT\n");
618                 return ret;
619         }
620
621         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
622         regs = devm_ioremap_resource(dev, res);
623         if (IS_ERR(regs))
624                 return PTR_ERR(regs);
625
626         inno->regmap = devm_regmap_init_mmio_clk(dev, "pclk", regs,
627                                                  &inno_mipi_dphy_regmap_cfg);
628         if (IS_ERR(inno->regmap)) {
629                 ret = PTR_ERR(inno->regmap);
630                 dev_err(dev, "failed to init regmap: %d\n", ret);
631                 return ret;
632         }
633
634         inno->ref_clk = devm_clk_get(dev, "ref");
635         if (IS_ERR(inno->ref_clk)) {
636                 dev_err(dev, "failed to get reference clock\n");
637                 return PTR_ERR(inno->ref_clk);
638         }
639
640         inno->rst = devm_reset_control_get(dev, "apb");
641         if (IS_ERR(inno->rst)) {
642                 dev_err(dev, "failed to get system reset control\n");
643                 return PTR_ERR(inno->rst);
644         }
645
646         phy = devm_phy_create(dev, NULL, &inno_mipi_dphy_ops);
647         if (IS_ERR(phy)) {
648                 dev_err(dev, "failed to create MIPI D-PHY\n");
649                 return PTR_ERR(phy);
650         }
651
652         phy_set_drvdata(phy, inno);
653
654         phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
655         if (IS_ERR(phy_provider)) {
656                 dev_err(dev, "failed to register phy provider\n");
657                 return PTR_ERR(phy_provider);
658         }
659
660         clk_prepare_enable(inno->ref_clk);
661
662         ret = inno_mipi_dphy_pll_register(inno);
663         if (ret) {
664                 clk_disable_unprepare(inno->ref_clk);
665                 return ret;
666         }
667
668         return 0;
669 }
670
671 static int inno_mipi_dphy_remove(struct platform_device *pdev)
672 {
673         struct inno_mipi_dphy *inno = platform_get_drvdata(pdev);
674
675         of_clk_del_provider(inno->dev->of_node);
676         clk_disable_unprepare(inno->ref_clk);
677
678         return 0;
679 }
680
681 static const struct of_device_id inno_mipi_dphy_of_match[] = {
682         { .compatible = "rockchip,rk3366-mipi-dphy", },
683         { .compatible = "rockchip,rk3368-mipi-dphy", },
684         { /* Sentinel */ }
685 };
686 MODULE_DEVICE_TABLE(of, inno_mipi_dphy_of_match);
687
688 static struct platform_driver inno_mipi_dphy_driver = {
689         .driver = {
690                 .name = "inno-mipi-dphy",
691                 .of_match_table = of_match_ptr(inno_mipi_dphy_of_match),
692         },
693         .probe  = inno_mipi_dphy_probe,
694         .remove = inno_mipi_dphy_remove,
695 };
696
697 module_platform_driver(inno_mipi_dphy_driver);
698
699 MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
700 MODULE_DESCRIPTION("Innosilicon MIPI D-PHY Driver");
701 MODULE_LICENSE("GPL v2");