phy: rockchip-inno-mipi-dphy: fix code style and removed unneeded code
[firefly-linux-kernel-4.4.55.git] / drivers / phy / phy-rockchip-inno-mipi-dphy.c
1 /*
2  * Copyright (c) 2017 Rockchip Inc.
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 version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <linux/clk.h>
15 #include <linux/delay.h>
16 #include <linux/init.h>
17 #include <linux/io.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/phy/phy.h>
21 #include <linux/platform_device.h>
22 #include <linux/regmap.h>
23 #include <linux/reset.h>
24
25 #include <drm/drm_mipi_dsi.h>
26
27 #include <video/mipi_display.h>
28 #include <video/of_videomode.h>
29 #include <video/videomode.h>
30
31 #define DRV_NAME        "inno-mipi-dphy"
32
33 #define INNO_PHY_LANE_CTRL      0x00000
34 #define INNO_PHY_POWER_CTRL     0x00004
35 #define INNO_PHY_PLL_CTRL_0     0x0000c
36 #define INNO_PHY_PLL_CTRL_1     0x00010
37 #define INNO_PHY_DIG_CTRL       0x00080
38 #define INNO_PHY_PIN_CTRL       0x00084
39
40 #define INNO_CLOCK_LANE_REG_BASE        0x00100
41 #define INNO_DATA_LANE_0_REG_BASE       0x00180
42 #define INNO_DATA_LANE_1_REG_BASE       0x00200
43 #define INNO_DATA_LANE_2_REG_BASE       0x00280
44 #define INNO_DATA_LANE_3_REG_BASE       0x00300
45
46 #define T_LPX_OFFSET            0x00014
47 #define T_HS_PREPARE_OFFSET     0x00018
48 #define T_HS_ZERO_OFFSET        0x0001c
49 #define T_HS_TRAIL_OFFSET       0x00020
50 #define T_HS_EXIT_OFFSET        0x00024
51 #define T_CLK_POST_OFFSET       0x00028
52 #define T_WAKUP_H_OFFSET        0x00030
53 #define T_WAKUP_L_OFFSET        0x00034
54 #define T_CLK_PRE_OFFSET        0x00038
55 #define T_TA_GO_OFFSET          0x00040
56 #define T_TA_SURE_OFFSET        0x00044
57 #define T_TA_WAIT_OFFSET        0x00048
58
59 #define CLK_LANE_EN_MASK        BIT(6)
60 #define DATA_LANE_3_EN_MASK     BIT(5)
61 #define DATA_LANE_2_EN_MASK     BIT(4)
62 #define DATA_LANE_1_EN_MASK     BIT(3)
63 #define DATA_LANE_0_EN_MASK     BIT(2)
64 #define CLK_LANE_EN             BIT(6)
65 #define DATA_LANE_3_EN          BIT(5)
66 #define DATA_LANE_2_EN          BIT(4)
67 #define DATA_LANE_1_EN          BIT(3)
68 #define DATA_LANE_0_EN          BIT(2)
69 #define FBDIV_8(x)              (((x) & 0x1) << 5)
70 #define PREDIV(x)               (((x) & 0x1f) << 0)
71 #define FBDIV_7_0(x)            (((x) & 0xff) << 0)
72 #define T_LPX(x)                (((x) & 0x3f) << 0)
73 #define T_HS_PREPARE(x)         (((x) & 0x7f) << 0)
74 #define T_HS_ZERO(x)            (((x) & 0x3f) << 0)
75 #define T_HS_TRAIL(x)           (((x) & 0x7f) << 0)
76 #define T_HS_EXIT(x)            (((x) & 0x1f) << 0)
77 #define T_CLK_POST(x)           (((x) & 0xf) << 0)
78 #define T_WAKUP_H(x)            (((x) & 0x3) << 0)
79 #define T_WAKUP_L(x)            (((x) & 0xff) << 0)
80 #define T_CLK_PRE(x)            (((x) & 0xf) << 0)
81 #define T_TA_GO(x)              (((x) & 0x3f) << 0)
82 #define T_TA_SURE(x)            (((x) & 0x3f) << 0)
83 #define T_TA_WAIT(x)            (((x) & 0x3f) << 0)
84
85 enum lane_type {
86         CLOCK_LANE,
87         DATA_LANE_0,
88         DATA_LANE_1,
89         DATA_LANE_2,
90         DATA_LANE_3,
91 };
92
93 static const u32 lane_reg_offset[] = {
94         [CLOCK_LANE] = INNO_CLOCK_LANE_REG_BASE,
95         [DATA_LANE_0] = INNO_DATA_LANE_0_REG_BASE,
96         [DATA_LANE_1] = INNO_DATA_LANE_1_REG_BASE,
97         [DATA_LANE_2] = INNO_DATA_LANE_2_REG_BASE,
98         [DATA_LANE_3] = INNO_DATA_LANE_3_REG_BASE,
99 };
100
101 enum hs_clk_range {
102         HS_CLK_RANGE_80_110_MHZ,
103         HS_CLK_RANGE_110_150_MHZ,
104         HS_CLK_RANGE_150_200_MHZ,
105         HS_CLK_RANGE_200_250_MHZ,
106         HS_CLK_RANGE_250_300_MHZ,
107         HS_CLK_RANGE_300_400_MHZ,
108         HS_CLK_RANGE_400_500_MHZ,
109         HS_CLK_RANGE_500_600_MHZ,
110         HS_CLK_RANGE_600_700_MHZ,
111         HS_CLK_RANGE_700_800_MHZ,
112         HS_CLK_RANGE_800_1000_MHZ,
113 };
114
115 static const u8 t_hs_prepare_val[] = {
116         [HS_CLK_RANGE_80_110_MHZ] = 0x20,
117         [HS_CLK_RANGE_110_150_MHZ] = 0x06,
118         [HS_CLK_RANGE_150_200_MHZ] = 0x18,
119         [HS_CLK_RANGE_200_250_MHZ] = 0x05,
120         [HS_CLK_RANGE_250_300_MHZ] = 0x51,
121         [HS_CLK_RANGE_300_400_MHZ] = 0x64,
122         [HS_CLK_RANGE_400_500_MHZ] = 0x20,
123         [HS_CLK_RANGE_500_600_MHZ] = 0x6a,
124         [HS_CLK_RANGE_600_700_MHZ] = 0x3e,
125         [HS_CLK_RANGE_700_800_MHZ] = 0x21,
126         [HS_CLK_RANGE_800_1000_MHZ] = 0x09,
127 };
128
129 static const u8 clock_lane_t_hs_zero_val[] = {
130         [HS_CLK_RANGE_80_110_MHZ] = 0x16,
131         [HS_CLK_RANGE_110_150_MHZ] = 0x16,
132         [HS_CLK_RANGE_150_200_MHZ] = 0x17,
133         [HS_CLK_RANGE_200_250_MHZ] = 0x17,
134         [HS_CLK_RANGE_250_300_MHZ] = 0x18,
135         [HS_CLK_RANGE_300_400_MHZ] = 0x19,
136         [HS_CLK_RANGE_400_500_MHZ] = 0x1b,
137         [HS_CLK_RANGE_500_600_MHZ] = 0x1d,
138         [HS_CLK_RANGE_600_700_MHZ] = 0x1e,
139         [HS_CLK_RANGE_700_800_MHZ] = 0x1f,
140         [HS_CLK_RANGE_800_1000_MHZ] = 0x20,
141 };
142
143 static const u8 data_lane_t_hs_zero_val[] = {
144         [HS_CLK_RANGE_80_110_MHZ] = 2,
145         [HS_CLK_RANGE_110_150_MHZ] = 3,
146         [HS_CLK_RANGE_150_200_MHZ] = 4,
147         [HS_CLK_RANGE_200_250_MHZ] = 5,
148         [HS_CLK_RANGE_250_300_MHZ] = 6,
149         [HS_CLK_RANGE_300_400_MHZ] = 7,
150         [HS_CLK_RANGE_400_500_MHZ] = 7,
151         [HS_CLK_RANGE_500_600_MHZ] = 8,
152         [HS_CLK_RANGE_600_700_MHZ] = 8,
153         [HS_CLK_RANGE_700_800_MHZ] = 9,
154         [HS_CLK_RANGE_800_1000_MHZ] = 9,
155 };
156
157 static const u8 t_hs_trail_val[] = {
158         [HS_CLK_RANGE_80_110_MHZ] = 0x22,
159         [HS_CLK_RANGE_110_150_MHZ] = 0x45,
160         [HS_CLK_RANGE_150_200_MHZ] = 0x0b,
161         [HS_CLK_RANGE_200_250_MHZ] = 0x16,
162         [HS_CLK_RANGE_250_300_MHZ] = 0x2c,
163         [HS_CLK_RANGE_300_400_MHZ] = 0x33,
164         [HS_CLK_RANGE_400_500_MHZ] = 0x4e,
165         [HS_CLK_RANGE_500_600_MHZ] = 0x3a,
166         [HS_CLK_RANGE_600_700_MHZ] = 0x6a,
167         [HS_CLK_RANGE_700_800_MHZ] = 0x29,
168         [HS_CLK_RANGE_800_1000_MHZ] = 0x27,
169 };
170
171 struct mipi_dphy_timing {
172         unsigned int clkmiss;
173         unsigned int clkpost;
174         unsigned int clkpre;
175         unsigned int clkprepare;
176         unsigned int clksettle;
177         unsigned int clktermen;
178         unsigned int clktrail;
179         unsigned int clkzero;
180         unsigned int dtermen;
181         unsigned int eot;
182         unsigned int hsexit;
183         unsigned int hsprepare;
184         unsigned int hszero;
185         unsigned int hssettle;
186         unsigned int hsskip;
187         unsigned int hstrail;
188         unsigned int init;
189         unsigned int lpx;
190         unsigned int taget;
191         unsigned int tago;
192         unsigned int tasure;
193         unsigned int wakeup;
194 };
195
196 struct inno_mipi_dphy_timing {
197         u8 t_lpx;
198         u8 t_hs_prepare;
199         u8 t_hs_zero;
200         u8 t_hs_trail;
201         u8 t_hs_exit;
202         u8 t_clk_post;
203         u8 t_wakup_h;
204         u8 t_wakup_l;
205         u8 t_clk_pre;
206         u8 t_ta_go;
207         u8 t_ta_sure;
208         u8 t_ta_wait;
209 };
210
211 struct dsi_panel {
212         struct videomode vm;
213         int bpp;
214 };
215
216 struct inno_mipi_dphy {
217         struct device *dev;
218         struct phy *phy;
219         void __iomem *regs;
220         struct clk *ref_clk;
221         struct clk *pclk;
222         struct reset_control *rst;
223
224         struct dsi_panel *panel;
225         u32 lanes;
226         u32 lane_mbps;
227 };
228
229 static inline void inno_write(struct inno_mipi_dphy *inno, u32 reg, u32 val)
230 {
231         writel_relaxed(val, inno->regs + reg);
232 }
233
234 static inline u32 inno_read(struct inno_mipi_dphy *inno, u32 reg)
235 {
236         return readl_relaxed(inno->regs + reg);
237 }
238
239 static inline void inno_update_bits(struct inno_mipi_dphy *inno, u32 reg,
240                                     u32 mask, u32 val)
241 {
242         u32 tmp, orig;
243
244         orig = inno_read(inno, reg);
245         tmp = orig & ~mask;
246         tmp |= val & mask;
247         inno_write(inno, reg, tmp);
248 }
249
250 static void mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing,
251                                          unsigned long period)
252 {
253         /* Global Operation Timing Parameters */
254         timing->clkmiss = 0;
255         timing->clkpost = 70 + 52 * period;
256         timing->clkpre = 8;
257         timing->clkprepare = 65;
258         timing->clksettle = 95;
259         timing->clktermen = 0;
260         timing->clktrail = 80;
261         timing->clkzero = 260;
262         timing->dtermen = 0;
263         timing->eot = 0;
264         timing->hsexit = 120;
265         timing->hsprepare = 65 + 5 * period;
266         timing->hszero = 145 + 5 * period;
267         timing->hssettle = 85 + 6 * period;
268         timing->hsskip = 40;
269         timing->hstrail = max(4 * 8 * period, 60 + 4 * 4 * period);
270         timing->init = 100000;
271         timing->lpx = 60;
272         timing->taget = 5 * timing->lpx;
273         timing->tago = 4 * timing->lpx;
274         timing->tasure = timing->lpx;
275         timing->wakeup = 1000000;
276 }
277
278 static void inno_mipi_dphy_timing_update(struct inno_mipi_dphy *inno,
279                                          enum lane_type lane_type,
280                                          struct inno_mipi_dphy_timing *t)
281 {
282         u32 base = lane_reg_offset[lane_type];
283
284         inno_write(inno, base + T_HS_PREPARE_OFFSET,
285                    T_HS_PREPARE(t->t_hs_prepare));
286         inno_write(inno, base + T_HS_ZERO_OFFSET, T_HS_ZERO(t->t_hs_zero));
287         inno_write(inno, base + T_HS_TRAIL_OFFSET, T_HS_TRAIL(t->t_hs_trail));
288         inno_write(inno, base + T_HS_EXIT_OFFSET, T_HS_EXIT(t->t_hs_exit));
289         inno_write(inno, base + T_CLK_POST_OFFSET, T_CLK_POST(t->t_clk_post));
290         inno_write(inno, base + T_CLK_PRE_OFFSET, T_CLK_PRE(t->t_clk_pre));
291         inno_write(inno, base + T_WAKUP_H_OFFSET, T_WAKUP_H(t->t_wakup_h));
292         inno_write(inno, base + T_WAKUP_L_OFFSET, T_WAKUP_L(t->t_wakup_l));
293         inno_write(inno, base + T_LPX_OFFSET, T_LPX(t->t_lpx));
294         inno_write(inno, base + T_TA_GO_OFFSET, T_TA_GO(t->t_ta_go));
295         inno_write(inno, base + T_TA_SURE_OFFSET, T_TA_SURE(t->t_ta_sure));
296         inno_write(inno, base + T_TA_WAIT_OFFSET, T_TA_WAIT(t->t_ta_wait));
297 }
298
299 static enum hs_clk_range inno_mipi_dphy_get_hs_clk_range(u32 lane_mbps)
300 {
301         if (lane_mbps < 110)
302                 return HS_CLK_RANGE_80_110_MHZ;
303         else if (lane_mbps < 150)
304                 return HS_CLK_RANGE_110_150_MHZ;
305         else if (lane_mbps < 200)
306                 return HS_CLK_RANGE_150_200_MHZ;
307         else if (lane_mbps < 250)
308                 return HS_CLK_RANGE_200_250_MHZ;
309         else if (lane_mbps < 300)
310                 return HS_CLK_RANGE_250_300_MHZ;
311         else if (lane_mbps < 400)
312                 return HS_CLK_RANGE_400_500_MHZ;
313         else if (lane_mbps < 500)
314                 return HS_CLK_RANGE_400_500_MHZ;
315         else if (lane_mbps < 600)
316                 return HS_CLK_RANGE_500_600_MHZ;
317         else if (lane_mbps < 700)
318                 return HS_CLK_RANGE_600_700_MHZ;
319         else if (lane_mbps < 800)
320                 return HS_CLK_RANGE_700_800_MHZ;
321         else
322                 return HS_CLK_RANGE_800_1000_MHZ;
323 }
324
325 static void inno_mipi_dphy_lane_timing_init(struct inno_mipi_dphy *inno,
326                                             enum lane_type lane_type)
327 {
328         struct mipi_dphy_timing timing;
329         struct inno_mipi_dphy_timing data;
330         u32 txbyteclkhs = inno->lane_mbps / 8;  /* MHz */
331         u32 txclkesc = 20;      /* MHz */
332         u32 UI = DIV_ROUND_CLOSEST(NSEC_PER_USEC, inno->lane_mbps);     /* ns */
333         enum hs_clk_range range;
334
335         memset(&timing, 0, sizeof(timing));
336         memset(&data, 0, sizeof(data));
337
338         mipi_dphy_timing_get_default(&timing, UI);
339
340         range = inno_mipi_dphy_get_hs_clk_range(inno->lane_mbps);
341
342         if (lane_type == CLOCK_LANE)
343                 data.t_hs_zero = clock_lane_t_hs_zero_val[range];
344         else
345                 data.t_hs_zero = data_lane_t_hs_zero_val[range];
346
347         data.t_hs_prepare = t_hs_prepare_val[range];
348         data.t_hs_trail = t_hs_trail_val[range];
349
350         /* txbyteclkhs domain */
351         data.t_hs_exit = DIV_ROUND_UP(txbyteclkhs * timing.hsexit,
352                                       NSEC_PER_USEC);
353         data.t_clk_post = DIV_ROUND_UP(txbyteclkhs * timing.clkpost,
354                                        NSEC_PER_USEC);
355         data.t_clk_pre = DIV_ROUND_UP(txbyteclkhs * timing.clkpre,
356                                       NSEC_PER_USEC);
357         data.t_wakup_h = 0x3;
358         data.t_wakup_l = 0xff;
359         data.t_lpx = txbyteclkhs * timing.lpx / NSEC_PER_USEC;
360
361         /* txclkesc domain */
362         data.t_ta_go = DIV_ROUND_UP(txclkesc * timing.tago, NSEC_PER_USEC);
363         data.t_ta_sure = DIV_ROUND_UP(txclkesc * timing.tasure, NSEC_PER_USEC);
364         data.t_ta_wait = DIV_ROUND_UP(txclkesc * timing.taget, NSEC_PER_USEC);
365
366         inno_mipi_dphy_timing_update(inno, lane_type, &data);
367 }
368
369 static void inno_mipi_dphy_pll_init(struct inno_mipi_dphy *inno)
370 {
371         struct dsi_panel *panel = inno->panel;
372         unsigned int i, pre;
373         unsigned int mpclk, pllref, tmp;
374         unsigned int target_mbps = 1000;
375         unsigned int max_mbps = 1000;
376         u32 fbdiv = 1, prediv = 1;
377         u32 val;
378
379         mpclk = DIV_ROUND_UP(panel->vm.pixelclock, USEC_PER_SEC);
380         if (mpclk) {
381                 /* take 1 / 0.9, since mbps must big than bandwidth of RGB */
382                 tmp = mpclk * (panel->bpp / inno->lanes) * 10 / 9;
383                 if (tmp < max_mbps)
384                         target_mbps = tmp;
385                 else
386                         dev_err(inno->dev, "DPHY clock frequency is out of range\n");
387         }
388
389         pllref = DIV_ROUND_UP(clk_get_rate(inno->ref_clk) / 2, USEC_PER_SEC);
390         tmp = pllref;
391
392         for (i = 1; i < 6; i++) {
393                 pre = pllref / i;
394                 if ((tmp > (target_mbps % pre)) && (target_mbps / pre < 512)) {
395                         tmp = target_mbps % pre;
396                         prediv = i;
397                         fbdiv = target_mbps / pre;
398                 }
399                 if (tmp == 0)
400                         break;
401         }
402
403         inno->lane_mbps = pllref * fbdiv / prediv;
404         phy_set_bus_width(inno->phy, inno->lane_mbps);
405
406         val = FBDIV_8(fbdiv >> 8) | PREDIV(prediv);
407         inno_write(inno, INNO_PHY_PLL_CTRL_0, val);
408
409         val = FBDIV_7_0(fbdiv);
410         inno_write(inno, INNO_PHY_PLL_CTRL_1, val);
411
412         dev_info(inno->dev, "fin=%d, fout=%d, prediv=%d, fbdiv=%d\n",
413                  pllref, inno->lane_mbps, prediv, fbdiv);
414 }
415
416 static void inno_mipi_dphy_reset(struct inno_mipi_dphy *inno)
417 {
418         /* Reset analog */
419         inno_write(inno, INNO_PHY_POWER_CTRL, 0xe0);
420         udelay(10);
421         /* Reset digital */
422         inno_write(inno, INNO_PHY_DIG_CTRL, 0x1e);
423         udelay(10);
424         inno_write(inno, INNO_PHY_DIG_CTRL, 0x1f);
425         udelay(10);
426 }
427
428 static void inno_mipi_dphy_timing_init(struct inno_mipi_dphy *inno)
429 {
430         switch (inno->lanes) {
431         case 4:
432                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_3);
433                 /* Fall through */
434         case 3:
435                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_2);
436                 /* Fall through */
437         case 2:
438                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_1);
439                 /* Fall through */
440         case 1:
441         default:
442                 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_0);
443                 inno_mipi_dphy_lane_timing_init(inno, CLOCK_LANE);
444                 break;
445         }
446 }
447
448 static inline void inno_mipi_dphy_lane_enable(struct inno_mipi_dphy *inno)
449 {
450         u32 val = 0;
451         u32 mask = 0;
452
453         switch (inno->lanes) {
454         case 4:
455                 mask |= DATA_LANE_3_EN_MASK;
456                 val |= DATA_LANE_3_EN;
457                 /* Fall through */
458         case 3:
459                 mask |= DATA_LANE_2_EN_MASK;
460                 val |= DATA_LANE_2_EN;
461                 /* Fall through */
462         case 2:
463                 mask |= DATA_LANE_1_EN_MASK;
464                 val |= DATA_LANE_1_EN;
465                 /* Fall through */
466         default:
467         case 1:
468                 mask |= DATA_LANE_0_EN_MASK | CLK_LANE_EN_MASK;
469                 val |= DATA_LANE_0_EN | CLK_LANE_EN;
470                 break;
471         }
472
473         inno_update_bits(inno, INNO_PHY_LANE_CTRL, mask, val);
474 }
475
476 static inline void inno_mipi_dphy_pll_ldo_enable(struct inno_mipi_dphy *inno)
477 {
478         inno_write(inno, INNO_PHY_POWER_CTRL, 0xe4);
479         udelay(10);
480 }
481
482 static int inno_mipi_dphy_power_on(struct phy *phy)
483 {
484         struct inno_mipi_dphy *inno = phy_get_drvdata(phy);
485
486         clk_prepare_enable(inno->ref_clk);
487         clk_prepare_enable(inno->pclk);
488
489         if (inno->rst) {
490                 /* MIPI DSI PHY APB software reset request. */
491                 reset_control_assert(inno->rst);
492                 usleep_range(20, 40);
493                 reset_control_deassert(inno->rst);
494         }
495
496         inno_mipi_dphy_pll_init(inno);
497         inno_mipi_dphy_pll_ldo_enable(inno);
498         inno_mipi_dphy_lane_enable(inno);
499         inno_mipi_dphy_reset(inno);
500         inno_mipi_dphy_timing_init(inno);
501
502         dev_info(inno->dev, "Inno MIPI-DPHY Power-On\n");
503
504         return 0;
505 }
506
507 static inline void inno_mipi_dphy_lane_disable(struct inno_mipi_dphy *inno)
508 {
509         inno_update_bits(inno, INNO_PHY_LANE_CTRL, 0x7c, 0x00);
510 }
511
512 static inline void inno_mipi_dphy_pll_ldo_disable(struct inno_mipi_dphy *inno)
513 {
514         inno_write(inno, INNO_PHY_POWER_CTRL, 0xe3);
515         udelay(10);
516 }
517
518 static int inno_mipi_dphy_power_off(struct phy *phy)
519 {
520         struct inno_mipi_dphy *inno = phy_get_drvdata(phy);
521
522         inno_mipi_dphy_lane_disable(inno);
523         inno_mipi_dphy_pll_ldo_disable(inno);
524
525         clk_disable_unprepare(inno->pclk);
526         clk_disable_unprepare(inno->ref_clk);
527
528         dev_info(inno->dev, "Inno MIPI-DPHY Power-Off\n");
529
530         return 0;
531 }
532
533 static const struct phy_ops inno_mipi_dphy_ops = {
534         .power_on = inno_mipi_dphy_power_on,
535         .power_off = inno_mipi_dphy_power_off,
536         .owner = THIS_MODULE,
537 };
538
539 static int get_bpp(struct device_node *np)
540 {
541         u32 format = 0;
542
543         if (of_property_read_u32(np, "dsi,format", &format))
544                 return 24;
545
546         switch (format) {
547         case MIPI_DSI_FMT_RGB666_PACKED:
548                 return 18;
549         case MIPI_DSI_FMT_RGB565:
550                 return 16;
551         case MIPI_DSI_FMT_RGB888:
552         case MIPI_DSI_FMT_RGB666:
553         default:
554                 return 24;
555         }
556 }
557
558 static int inno_mipi_dphy_parse_dt(struct device_node *np,
559                                    struct inno_mipi_dphy *inno)
560 {
561         struct device_node *panel_node;
562         struct dsi_panel *panel;
563         int ret;
564
565         panel_node = of_parse_phandle(np, "rockchip,dsi-panel", 0);
566         if (!panel_node) {
567                 dev_err(inno->dev, "Missing 'rockchip,dsi-panel' property");
568                 return -ENODEV;
569         }
570
571         panel = devm_kzalloc(inno->dev, sizeof(*panel), GFP_KERNEL);
572         if (!panel) {
573                 ret = -ENOMEM;
574                 goto put_panel_node;
575         }
576
577         ret = of_get_videomode(panel_node, &panel->vm, 0);
578         if (ret < 0)
579                 goto put_panel_node;
580
581         panel->bpp = get_bpp(panel_node);
582
583         if (of_property_read_u32(panel_node, "dsi,lanes", &inno->lanes))
584                 inno->lanes = 4;
585
586         of_node_put(panel_node);
587
588         inno->panel = panel;
589
590         return 0;
591
592 put_panel_node:
593         of_node_put(panel_node);
594         return ret;
595 }
596
597 static int inno_mipi_dphy_probe(struct platform_device *pdev)
598 {
599         struct device_node *np = pdev->dev.of_node;
600         struct inno_mipi_dphy *inno;
601         struct phy_provider *phy_provider;
602         struct resource *res;
603         int ret;
604
605         inno = devm_kzalloc(&pdev->dev, sizeof(*inno), GFP_KERNEL);
606         if (!inno)
607                 return -ENOMEM;
608
609         inno->dev = &pdev->dev;
610         platform_set_drvdata(pdev, inno);
611
612         ret = inno_mipi_dphy_parse_dt(np, inno);
613         if (ret) {
614                 dev_err(&pdev->dev, "failed to parse DT\n");
615                 return ret;
616         }
617
618         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
619         inno->regs = devm_ioremap_resource(&pdev->dev, res);
620         if (IS_ERR(inno->regs))
621                 return PTR_ERR(inno->regs);
622
623         inno->ref_clk = devm_clk_get(&pdev->dev, "ref");
624         if (IS_ERR(inno->ref_clk)) {
625                 dev_err(&pdev->dev, "failed to get mipi dphy ref clk\n");
626                 return PTR_ERR(inno->ref_clk);
627         }
628
629         clk_set_rate(inno->ref_clk, 24000000);
630
631         inno->pclk = devm_clk_get(&pdev->dev, "pclk");
632         if (IS_ERR(inno->pclk)) {
633                 dev_err(&pdev->dev, "failed to get mipi dphy pclk\n");
634                 return PTR_ERR(inno->pclk);
635         }
636
637         inno->rst = devm_reset_control_get_optional(&pdev->dev, "apb");
638         if (IS_ERR(inno->rst)) {
639                 dev_info(&pdev->dev, "No reset control specified\n");
640                 inno->rst = NULL;
641         }
642
643         inno->phy = devm_phy_create(&pdev->dev, NULL, &inno_mipi_dphy_ops);
644         if (IS_ERR(inno->phy)) {
645                 dev_err(&pdev->dev, "failed to create MIPI D-PHY\n");
646                 return PTR_ERR(inno->phy);
647         }
648
649         phy_set_drvdata(inno->phy, inno);
650
651         phy_provider = devm_of_phy_provider_register(&pdev->dev,
652                                                      of_phy_simple_xlate);
653         if (IS_ERR(phy_provider)) {
654                 dev_err(&pdev->dev, "failed to register phy provider\n");
655                 return PTR_ERR(phy_provider);
656         }
657
658         dev_info(&pdev->dev, "Inno MIPI-DPHY Driver Probe\n");
659
660         return 0;
661 }
662
663 static const struct of_device_id inno_mipi_dphy_of_match[] = {
664         { .compatible = "rockchip,rk3368-mipi-dphy", },
665         { /* Sentinel */ }
666 };
667 MODULE_DEVICE_TABLE(of, inno_mipi_dphy_of_match);
668
669 static struct platform_driver inno_mipi_dphy_driver = {
670         .probe  = inno_mipi_dphy_probe,
671         .driver = {
672                 .name   = DRV_NAME,
673                 .of_match_table = inno_mipi_dphy_of_match,
674         }
675 };
676
677 module_platform_driver(inno_mipi_dphy_driver);
678
679 MODULE_DESCRIPTION("Innosilicon MIPI D-PHY Driver");
680 MODULE_LICENSE("GPL v2");