phy: rockchip-inno-mipi-dphy: export PLL clock
[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 mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
243                                          unsigned long period)
244 {
245         /* Global Operation Timing Parameters */
246         timing->clkmiss = 0;
247         timing->clkpost = 70 + 52 * period;
248         timing->clkpre = 8 * period;
249         timing->clkprepare = 65;
250         timing->clksettle = 95;
251         timing->clktermen = 0;
252         timing->clktrail = 80;
253         timing->clkzero = 260;
254         timing->dtermen = 0;
255         timing->eot = 0;
256         timing->hsexit = 120;
257         timing->hsprepare = 65 + 4 * period;
258         timing->hszero = 145 + 6 * period;
259         timing->hssettle = 85 + 6 * period;
260         timing->hsskip = 40;
261         timing->hstrail = max(8 * period, 60 + 4 * period);
262         timing->init = 100000;
263         timing->lpx = 60;
264         timing->taget = 5 * timing->lpx;
265         timing->tago = 4 * timing->lpx;
266         timing->tasure = 2 * timing->lpx;
267         timing->wakeup = 1000000;
268 }
269
270 static void inno_mipi_dphy_timing_update(struct inno_mipi_dphy *inno,
271                                          enum lane_type lane_type,
272                                          struct inno_mipi_dphy_timing *t)
273 {
274         u32 base = lane_reg_offset[lane_type];
275
276         regmap_update_bits(inno->regmap, base + T_HS_PREPARE_OFFSET,
277                            T_HS_PREPARE_MASK, T_HS_PREPARE(t->hs_prepare));
278         regmap_update_bits(inno->regmap, base + T_HS_ZERO_OFFSET,
279                            T_HS_ZERO_MASK, T_HS_ZERO(t->hs_zero));
280         regmap_update_bits(inno->regmap, base + T_HS_TRAIL_OFFSET,
281                            T_HS_TRAIL_MASK, T_HS_TRAIL(t->hs_trail));
282         regmap_update_bits(inno->regmap, base + T_HS_EXIT_OFFSET,
283                            T_HS_EXIT_MASK, T_HS_EXIT(t->hs_exit));
284
285         if (lane_type == CLOCK_LANE) {
286                 regmap_update_bits(inno->regmap, base + T_CLK_POST_OFFSET,
287                                    T_CLK_POST_MASK, T_CLK_POST(t->clk_post));
288                 regmap_update_bits(inno->regmap, base + T_CLK_PRE_OFFSET,
289                                    T_CLK_PRE_MASK, T_CLK_PRE(t->clk_pre));
290         }
291
292         regmap_update_bits(inno->regmap, base + T_WAKUP_H_OFFSET,
293                            T_WAKUP_H_MASK, T_WAKUP_H(t->wakup_h));
294         regmap_update_bits(inno->regmap, base + T_WAKUP_L_OFFSET,
295                            T_WAKUP_L_MASK, T_WAKUP_L(t->wakup_l));
296         regmap_update_bits(inno->regmap, base + T_LPX_OFFSET,
297                            T_LPX_MASK, T_LPX(t->lpx));
298         regmap_update_bits(inno->regmap, base + T_TA_GO_OFFSET,
299                            T_TA_GO_MASK, T_TA_GO(t->ta_go));
300         regmap_update_bits(inno->regmap, base + T_TA_SURE_OFFSET,
301                            T_TA_SURE_MASK, T_TA_SURE(t->ta_sure));
302         regmap_update_bits(inno->regmap, base + T_TA_WAIT_OFFSET,
303                            T_TA_WAIT_MASK, T_TA_WAIT(t->ta_wait));
304 }
305
306 static void inno_mipi_dphy_get_fixed_param(struct inno_mipi_dphy_timing *t,
307                                            unsigned long freq,
308                                            enum lane_type lane_type)
309 {
310         int i;
311
312         for (i = 0; i < ARRAY_SIZE(fixed_param_table); i++)
313                 if (freq <= fixed_param_table[i].max_freq)
314                         break;
315
316         if (i == ARRAY_SIZE(fixed_param_table))
317                 --i;
318
319         if (lane_type == CLOCK_LANE)
320                 t->hs_zero = fixed_param_table[i].clk_lane.hs_zero;
321         else
322                 t->hs_zero = fixed_param_table[i].data_lane.hs_zero;
323
324         t->hs_prepare = fixed_param_table[i].hs_prepare;
325         t->hs_trail = fixed_param_table[i].hs_trail;
326 }
327
328 static void inno_mipi_dphy_lane_timing_init(struct inno_mipi_dphy *inno,
329                                             enum lane_type lane_type)
330 {
331         struct mipi_dphy_timing timing;
332         struct inno_mipi_dphy_timing data;
333         unsigned long txbyteclk, txclkesc, UI;
334         unsigned int esc_clk_div;
335
336         memset(&timing, 0, sizeof(timing));
337         memset(&data, 0, sizeof(data));
338
339         txbyteclk = inno->lane_rate / 8;
340         esc_clk_div = DIV_ROUND_UP(txbyteclk, 20000000);
341         txclkesc = txbyteclk / esc_clk_div;
342         UI = DIV_ROUND_CLOSEST_ULL(NSEC_PER_SEC, inno->lane_rate);
343
344         mipi_dphy_timing_get_default(&timing, UI);
345         inno_mipi_dphy_get_fixed_param(&data, inno->lane_rate / USEC_PER_SEC,
346                                        lane_type);
347
348         data.hs_exit = DIV_ROUND_UP(timing.hsexit * txbyteclk, NSEC_PER_SEC);
349         data.clk_post = DIV_ROUND_UP(timing.clkpost * txbyteclk, NSEC_PER_SEC);
350         data.clk_pre = DIV_ROUND_UP(timing.clkpre * txbyteclk, NSEC_PER_SEC);
351         data.wakup_h = 0x3;
352         data.wakup_l = 0xff;
353         data.lpx = DIV_ROUND_UP(txbyteclk * timing.lpx, NSEC_PER_SEC);
354         if (data.lpx >= 2)
355                 data.lpx -= 2;
356         data.ta_go = DIV_ROUND_UP(timing.tago * txclkesc, NSEC_PER_SEC);
357         data.ta_sure = DIV_ROUND_UP(timing.tasure * txclkesc, NSEC_PER_SEC);
358         data.ta_wait = DIV_ROUND_UP(timing.taget * txclkesc, NSEC_PER_SEC);
359
360         inno_mipi_dphy_timing_update(inno, lane_type, &data);
361
362 #define TIMING_NS(x, freq) (((x) * (DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq))))
363         dev_dbg(inno->dev, "hs-exit=%lu, clk-post=%lu, clk-pre=%lu, lpx=%lu\n",
364                 TIMING_NS(data.hs_exit, txbyteclk),
365                 TIMING_NS(data.clk_post, txbyteclk),
366                 TIMING_NS(data.clk_pre, txbyteclk),
367                 TIMING_NS(data.lpx + 2, txbyteclk));
368         dev_dbg(inno->dev, "ta-go=%lu, ta-sure=%lu, ta-wait=%lu\n",
369                 TIMING_NS(data.ta_go, txclkesc),
370                 TIMING_NS(data.ta_sure, txclkesc),
371                 TIMING_NS(data.ta_wait, txclkesc));
372 }
373
374 static unsigned long inno_mipi_dphy_pll_rate_fixup(unsigned long fin,
375                                                    unsigned long rate,
376                                                    u8 *prediv, u16 *fbdiv)
377 {
378         unsigned long best_freq = 0;
379         unsigned long fout;
380         u8 min_prediv, max_prediv;
381         u8 _prediv, uninitialized_var(best_prediv);
382         u16 _fbdiv, uninitialized_var(best_fbdiv);
383         u32 min_delta = UINT_MAX;
384
385         /*
386          * The PLL output frequency can be calculated using a simple formula:
387          * PLL_Output_Frequency = (FREF / PREDIV * FBDIV) / 2
388          * PLL_Output_Frequency: it is equal to DDR-Clock-Frequency * 2
389          */
390         fout = 2 * rate;
391
392         /* constraint: 5Mhz < Fref / prediv < 40MHz */
393         min_prediv = DIV_ROUND_UP(fin, 40000000);
394         max_prediv = fin / 5000000;
395
396         for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
397                 u64 tmp;
398                 u32 delta;
399
400                 tmp = (u64)fout * _prediv;
401                 do_div(tmp, fin);
402                 _fbdiv = tmp;
403                 /*
404                  * The all possible settings of feedback divider are
405                  * 12, 13, 14, 16, ~ 511
406                  */
407                 if ((_fbdiv == 15) || (_fbdiv < 12) || (_fbdiv > 511))
408                         continue;
409                 tmp = (u64)_fbdiv * fin;
410                 do_div(tmp, _prediv);
411
412                 delta = abs(fout - tmp);
413                 if (delta < min_delta) {
414                         best_prediv = _prediv;
415                         best_fbdiv = _fbdiv;
416                         min_delta = delta;
417                         best_freq = tmp;
418                 }
419         }
420
421         if (best_freq) {
422                 *prediv = best_prediv;
423                 *fbdiv = best_fbdiv;
424         }
425
426         return best_freq / 2;
427 }
428
429 static void inno_mipi_dphy_timing_init(struct inno_mipi_dphy *inno)
430 {
431         switch (inno->lanes) {
432         case 4:
433                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_3);
434                 /* Fall through */
435         case 3:
436                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_2);
437                 /* Fall through */
438         case 2:
439                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_1);
440                 /* Fall through */
441         case 1:
442         default:
443                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_0);
444                 inno_mipi_dphy_lane_timing_init(inno, CLOCK_LANE);
445                 break;
446         }
447 }
448
449 static int inno_mipi_dphy_power_on(struct phy *phy)
450 {
451         struct inno_mipi_dphy *inno = phy_get_drvdata(phy);
452
453         inno_mipi_dphy_lane_enable(inno);
454         inno_mipi_dphy_reset(inno);
455         inno_mipi_dphy_timing_init(inno);
456         udelay(1);
457
458         return 0;
459 }
460
461 static int inno_mipi_dphy_power_off(struct phy *phy)
462 {
463         struct inno_mipi_dphy *inno = phy_get_drvdata(phy);
464
465         inno_mipi_dphy_lane_disable(inno);
466
467         return 0;
468 }
469
470 static const struct phy_ops inno_mipi_dphy_ops = {
471         .power_on  = inno_mipi_dphy_power_on,
472         .power_off = inno_mipi_dphy_power_off,
473         .owner     = THIS_MODULE,
474 };
475
476 static long inno_mipi_dphy_pll_clk_round_rate(struct clk_hw *hw,
477                                               unsigned long rate,
478                                               unsigned long *prate)
479 {
480         struct inno_mipi_dphy *inno = hw_to_inno(hw);
481         unsigned long fin = *prate;
482         unsigned long fout;
483         u16 fbdiv;
484         u8 prediv;
485
486         fout = inno_mipi_dphy_pll_rate_fixup(fin, rate, &prediv, &fbdiv);
487
488         dev_dbg(inno->dev, "%s: fin=%lu, req_rate=%lu\n",
489                 __func__, *prate, rate);
490         dev_dbg(inno->dev, "%s: fout=%lu, prediv=%u, fbdiv=%u\n",
491                 __func__, fout, prediv, fbdiv);
492
493         inno->pll.prediv = prediv;
494         inno->pll.fbdiv = fbdiv;
495
496         return fout;
497 }
498
499 static int inno_mipi_dphy_pll_clk_set_rate(struct clk_hw *hw,
500                                            unsigned long rate,
501                                            unsigned long parent_rate)
502 {
503         struct inno_mipi_dphy *inno = hw_to_inno(hw);
504
505         dev_dbg(inno->dev, "%s: rate: %lu Hz\n", __func__, rate);
506
507         inno->lane_rate = rate;
508
509         return 0;
510 }
511
512 static unsigned long
513 inno_mipi_dphy_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
514 {
515         struct inno_mipi_dphy *inno = hw_to_inno(hw);
516
517         dev_dbg(inno->dev, "%s: rate: %lu Hz\n", __func__, inno->lane_rate);
518
519         return inno->lane_rate;
520 }
521
522 static int inno_mipi_dphy_pll_clk_enable(struct clk_hw *hw)
523 {
524         struct inno_mipi_dphy *inno = hw_to_inno(hw);
525
526         regmap_update_bits(inno->regmap, INNO_PHY_PLL_CTRL_0, FBDIV_HI_MASK |
527                            PREDIV_MASK, FBDIV_HI(inno->pll.fbdiv >> 8) |
528                            PREDIV(inno->pll.prediv));
529         regmap_update_bits(inno->regmap, INNO_PHY_PLL_CTRL_1,
530                            FBDIV_LO_MASK, FBDIV_LO(inno->pll.fbdiv));
531         regmap_update_bits(inno->regmap, INNO_PHY_POWER_CTRL,
532                            PLL_POWER_MASK | LDO_POWER_MASK,
533                            PLL_POWER_ON | LDO_POWER_ON);
534
535         return 0;
536 }
537
538 static void inno_mipi_dphy_pll_clk_disable(struct clk_hw *hw)
539 {
540         struct inno_mipi_dphy *inno = hw_to_inno(hw);
541
542         regmap_update_bits(inno->regmap, INNO_PHY_POWER_CTRL,
543                            PLL_POWER_MASK | LDO_POWER_MASK,
544                            PLL_POWER_DOWN | LDO_POWER_DOWN);
545 }
546
547 static const struct clk_ops inno_mipi_dphy_pll_clk_ops = {
548         .enable = inno_mipi_dphy_pll_clk_enable,
549         .disable = inno_mipi_dphy_pll_clk_disable,
550         .round_rate = inno_mipi_dphy_pll_clk_round_rate,
551         .set_rate = inno_mipi_dphy_pll_clk_set_rate,
552         .recalc_rate = inno_mipi_dphy_pll_clk_recalc_rate,
553 };
554
555 static int inno_mipi_dphy_pll_register(struct inno_mipi_dphy *inno)
556 {
557         struct device *dev = inno->dev;
558         struct device_node *np = dev->of_node;
559         struct clk *clk;
560         const char *parent_name;
561         struct clk_init_data init;
562         int ret;
563
564         parent_name = __clk_get_name(inno->ref_clk);
565
566         ret = of_property_read_string(np, "clock-output-names", &init.name);
567         if (ret < 0) {
568                 dev_err(dev, "Missing clock-output-names property: %d\n", ret);
569                 return ret;
570         }
571
572         init.ops = &inno_mipi_dphy_pll_clk_ops;
573         init.parent_names = (const char * const *)&parent_name;
574         init.num_parents = 1;
575         init.flags = 0;
576
577         inno->pll.hw.init = &init;
578         clk = devm_clk_register(dev, &inno->pll.hw);
579         if (IS_ERR(clk)) {
580                 ret = PTR_ERR(clk);
581                 dev_err(dev, "failed to register PLL: %d\n", ret);
582                 return ret;
583         }
584
585         return of_clk_add_provider(np, of_clk_src_simple_get, clk);
586 }
587
588 static int inno_mipi_dphy_parse_dt(struct device_node *np,
589                                    struct inno_mipi_dphy *inno)
590 {
591         if (of_property_read_u32(np, "inno,lanes", &inno->lanes))
592                 inno->lanes = 4;
593
594         return 0;
595 }
596
597 static struct regmap_config inno_mipi_dphy_regmap_cfg = {
598         .reg_bits = 32,
599         .val_bits = 32,
600         .reg_stride = 4,
601         .max_register = INNO_MIPI_DPHY_MAX_REGISTER,
602 };
603
604 static int inno_mipi_dphy_probe(struct platform_device *pdev)
605 {
606         struct device *dev = &pdev->dev;
607         struct inno_mipi_dphy *inno;
608         struct phy_provider *phy_provider;
609         struct phy *phy;
610         struct resource *res;
611         void __iomem *regs;
612         int ret;
613
614         inno = devm_kzalloc(dev, sizeof(*inno), GFP_KERNEL);
615         if (!inno)
616                 return -ENOMEM;
617
618         inno->dev = dev;
619         platform_set_drvdata(pdev, inno);
620
621         ret = inno_mipi_dphy_parse_dt(dev->of_node, inno);
622         if (ret) {
623                 dev_err(dev, "failed to parse DT\n");
624                 return ret;
625         }
626
627         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
628         regs = devm_ioremap_resource(dev, res);
629         if (IS_ERR(regs))
630                 return PTR_ERR(regs);
631
632         inno->regmap = devm_regmap_init_mmio_clk(dev, "pclk", regs,
633                                                  &inno_mipi_dphy_regmap_cfg);
634         if (IS_ERR(inno->regmap)) {
635                 ret = PTR_ERR(inno->regmap);
636                 dev_err(dev, "failed to init regmap: %d\n", ret);
637                 return ret;
638         }
639
640         inno->ref_clk = devm_clk_get(dev, "ref");
641         if (IS_ERR(inno->ref_clk)) {
642                 dev_err(dev, "failed to get reference clock\n");
643                 return PTR_ERR(inno->ref_clk);
644         }
645
646         inno->rst = devm_reset_control_get(dev, "apb");
647         if (IS_ERR(inno->rst)) {
648                 dev_err(dev, "failed to get system reset control\n");
649                 return PTR_ERR(inno->rst);
650         }
651
652         phy = devm_phy_create(dev, NULL, &inno_mipi_dphy_ops);
653         if (IS_ERR(phy)) {
654                 dev_err(dev, "failed to create MIPI D-PHY\n");
655                 return PTR_ERR(phy);
656         }
657
658         phy_set_drvdata(phy, inno);
659
660         phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
661         if (IS_ERR(phy_provider)) {
662                 dev_err(dev, "failed to register phy provider\n");
663                 return PTR_ERR(phy_provider);
664         }
665
666         clk_prepare_enable(inno->ref_clk);
667
668         ret = inno_mipi_dphy_pll_register(inno);
669         if (ret) {
670                 clk_disable_unprepare(inno->ref_clk);
671                 return ret;
672         }
673
674         return 0;
675 }
676
677 static int inno_mipi_dphy_remove(struct platform_device *pdev)
678 {
679         struct inno_mipi_dphy *inno = platform_get_drvdata(pdev);
680
681         of_clk_del_provider(inno->dev->of_node);
682         clk_disable_unprepare(inno->ref_clk);
683
684         return 0;
685 }
686
687 static const struct of_device_id inno_mipi_dphy_of_match[] = {
688         { .compatible = "rockchip,rk3366-mipi-dphy", },
689         { .compatible = "rockchip,rk3368-mipi-dphy", },
690         { /* Sentinel */ }
691 };
692 MODULE_DEVICE_TABLE(of, inno_mipi_dphy_of_match);
693
694 static struct platform_driver inno_mipi_dphy_driver = {
695         .driver = {
696                 .name = "inno-mipi-dphy",
697                 .of_match_table = of_match_ptr(inno_mipi_dphy_of_match),
698         },
699         .probe  = inno_mipi_dphy_probe,
700         .remove = inno_mipi_dphy_remove,
701 };
702
703 module_platform_driver(inno_mipi_dphy_driver);
704
705 MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
706 MODULE_DESCRIPTION("Innosilicon MIPI D-PHY Driver");
707 MODULE_LICENSE("GPL v2");