tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / sprdfb / dsi_1_21a / mipi_dsih_dphy_megacores.c
1 /*
2  * Copyright (C) 2014 Spreadtrum Communications Inc.
3  *
4  * modules/DISPC/dsi_1.21a/mipi_api_dsihost/mipi_dsih_dphy_megacores.c
5  *
6  * Author: Haibing.Yang <haibing.yang@spreadtrum.com>
7  *                                              <yanghb41@gmail.com>
8  *
9  * This software is licensed under the terms of the GNU General Public
10  * License version 2, as published by the Free Software Foundation, and
11  * may be copied, distributed, and modified under those terms.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18
19 #include <div64.h>
20 #include "mipi_dsih_dphy.h"
21
22 #define L                                               0
23 #define H                                               1
24 #define CLK                                             0
25 #define DATA                                    1
26
27 #ifndef INFINITY
28 #define INFINITY                                0xffffffff
29 #endif
30
31 #define MIN_OUTPUT_FREQ                 (100)
32 #define MAX_LANES                               2
33
34 #ifndef ROUND_UP
35 #define ROUND_UP(a, b) (((a) + (b) - 1) / (b))
36 #endif
37
38 #ifndef MAX
39 #define MAX(a, b) ((a) > (b) ? (a) : (b))
40 #define MIN(a, b) ((a) > (b) ? (b) : (a))
41 #endif
42
43 #ifndef abs
44 /*
45  * abs() should not be used for 64-bit types
46  * (s64, u64, long long) - use abs64() for those.
47  */
48 #define abs(x) ({ \
49         long ret; \
50         if (sizeof((x)) == sizeof(long)) { \
51                 long __x = (x); \
52                 ret = (__x < 0) ? - __x : __x; \
53         } else { \
54                 int __x = (x); \
55                 ret = (__x < 0) ? - __x : __x; \
56         } \
57         ret; \
58 })
59 #endif
60
61 #define AVERAGE(a, b) (MIN(a, b) + abs((b) - (a)) / 2)
62
63 typedef unsigned int            u32;
64 typedef unsigned short  u16;
65 typedef unsigned char   u8;
66
67 enum TIMING {
68         NONE,
69         REQUEST_TIME,
70         PREPARE_TIME,
71         SETTLE_TIME,
72         ZERO_TIME,
73         TRAIL_TIME,
74         EXIT_TIME,
75         CLKPOST_TIME,
76         TA_GET,
77         TA_GO,
78         TA_SURE,
79         TA_WAIT,
80 };
81
82 struct pll_regs {
83         union __reg_03__ {
84                 struct __03 {
85                         u8 prbs_bist: 1;
86                         u8 en_lp_treot: 1;
87                         u8 lpf_sel: 4;
88                         u8 txfifo_bypass: 1;
89                         u8 freq_hopping: 1;
90                 } bits;
91                 u8 val;
92         } _03;
93         union __reg_04__ {
94                 struct __04 {
95                         u8 div: 3;
96                         u8 reserved: 2;
97                         u8 cp_s: 2;
98                         u8 fdk_s: 1;
99                 } bits;
100                 u8 val;
101         } _04;
102         union __reg_06__ {
103                 struct __06 {
104                         u8 nint: 7;
105                         u8 mod_en: 1;
106                 } bits;
107                 u8 val;
108         } _06;
109         union __reg_07__ {
110                 struct __07 {
111                         u8 kdelta_h: 8;
112                 } bits;
113                 u8 val;
114         } _07;
115         union __reg_08__ {
116                 struct __08 {
117                         u8 vco_band: 1;
118                         u8 sdm_en: 1;
119                         u8 refin: 2;
120                         u8 kdelta_l: 4;
121                 } bits;
122                 u8 val;
123         } _08;
124         union __reg_09__ {
125                 struct __09 {
126                         u8 kint_h: 8;
127                 } bits;
128                 u8 val;
129         } _09;
130         union __reg_0a__ {
131                 struct __0a {
132                         u8 kint_m: 8;
133                 } bits;
134                 u8 val;
135         } _0a;
136         union __reg_0b__ {
137                 struct __0b {
138                         u8 out_sel: 4;
139                         u8 kint_l: 4;
140                 } bits;
141                 u8 val;
142         } _0b;
143         union __reg_0c__ {
144                 struct __0c {
145                         u8 kstep_h: 8;
146                 } bits;
147                 u8 val;
148         } _0c;
149         union __reg_0d__ {
150                 struct __0d {
151                         u8 kstep_m: 8;
152                 } bits;
153                 u8 val;
154         } _0d;
155         union __reg_0e__ {
156                 struct __0e {
157                         u8 pll_pu_byp: 1;
158                         u8 pll_pu: 1;
159                         u8 reserved1: 3;
160                         u8 kstep_l: 3;
161                 } bits;
162                 u8 val;
163         } _0e;
164 };
165
166 struct dphy_pll {
167         u8 refin; /* Pre-divider control signal */
168         u8 cp_s; /* 00: SDM_EN=1, 10: SDM_EN=0 */
169         u8 fdk_s; /* PLL mode control: integer or fraction */
170         u8 hop_en;
171         u8 mod_en; /* ssc enable */
172         u8 sdm_en;
173         u8 div;
174         u8 int_n; /* integer N PLL */
175         u32 ref_clk; /* dphy reference clock, unit: MHz */
176         u32 freq; /* panel config, unit: KHz */
177         u32 fvco; /* MHz */
178         u32 potential_fvco; /* MHz */
179         u32 nint; /* sigma delta modulator NINT control */
180         u32 kint; /* sigma delta modulator KINT control */
181         u32 sign;
182         u32 kdelta;
183         u32 kstep;
184         u8 lpf_sel; /* low pass filter control */
185         u8 out_sel; /* post divider control */
186         u8 vco_band; /* vco range */
187 };
188
189 /**
190  * Initialise D-PHY module and power up
191  * @param phy: pointer to structure
192  *  which holds information about the d-phy module
193  * @return error code
194  */
195 dsih_error_t mipi_dsih_dphy_open(dphy_t *phy)
196 {
197         if (!phy || !phy->core_read_function || !phy->core_write_function)
198                 return ERR_DSI_PHY_INVALID;
199         else if (phy->status == INITIALIZED)
200                 return ERR_DSI_PHY_INVALID;
201
202         phy->status = INITIALIZED;
203         return OK;
204 }
205
206 u8 mipi_dsih_dphy_test_data_read(dphy_t *phy, u8 address)
207 {
208         mipi_dsih_dphy_test_clock(phy, 1);
209         /* set the desired test code in the input 8-bit bus TESTDIN[7:0] */
210         mipi_dsih_dphy_test_data_in(phy, address);
211         /* set TESTEN input high  */
212         mipi_dsih_dphy_test_en(phy, 1);
213
214         /*
215          * drive the TESTCLK input low;
216          * the falling edge captures the
217          * chosen test code into the transceiver.
218          */
219         mipi_dsih_dphy_test_clock(phy, 0);
220
221         /* set TESTEN input low to disable further test mode code latching */
222         mipi_dsih_dphy_test_en(phy, 0);
223
224         udelay(1);
225
226         return mipi_dsih_dphy_test_data_out(phy);
227 }
228
229 static inline int mipi_dsih_if_dphy_keep_work(dphy_t *phy)
230 {
231         int keep_work;
232
233 #ifdef CONFIG_FB_DYNAMIC_FREQ_SCALING
234         keep_work = phy->phy_keep_work;
235 #else
236         keep_work = FALSE;
237 #endif
238         return keep_work;
239 }
240
241 static int mipi_dsih_dphy_calc_pll_param(dphy_t *phy, struct dphy_pll *pll)
242 {
243         int i;
244         const u32 hopping_period = 200;
245         const u32 khz = 1000;
246         const u32 mhz = 1000000;
247         int delta_freq;
248         static u32 origin_freq = 0;
249         const unsigned long long factor = 100;
250         unsigned long long tmp;
251
252         if (!pll || !pll->freq)
253                 goto FAIL;
254
255         pll->potential_fvco = pll->freq / khz; /* MHz */
256         pll->ref_clk = phy->reference_freq / khz; /* MHz */
257
258         for (i = 0; i < 4; ++i) {
259                 if (pll->potential_fvco >= 750 && pll->potential_fvco <= 1500) {
260                         pll->fvco = pll->potential_fvco;
261                         pll->out_sel = BIT(i);
262                         break;
263                 }
264                 pll->potential_fvco <<= 1;
265         }
266         if (pll->fvco == 0)
267                 goto FAIL;
268
269         if (pll->fvco >= 750 && pll->fvco <= 1100) {
270                 /* vco band control */
271                 pll->vco_band = 0x0;
272                 /* low pass filter control */
273                 pll->lpf_sel = 0x7;
274         } else if (pll->fvco > 1100 && pll->fvco <= 1500) {
275                 pll->vco_band = 0x1;
276                 pll->lpf_sel = 0x6;
277         } else
278                 goto FAIL;
279
280         pll->nint = pll->fvco / pll->ref_clk;
281         tmp = pll->fvco * factor * mhz;
282         do_div(tmp, pll->ref_clk);
283         tmp = tmp - pll->nint * factor * mhz;
284         tmp *= BIT(20);
285         do_div(tmp, 100000000);
286         pll->kint = (u32)tmp;
287         pll->refin = 0x3; /* pre-divider bypass */
288         pll->sdm_en = TRUE; /* use fraction N PLL */
289         pll->fdk_s = 0x1; /* fraction */
290         pll->cp_s = 0x0;
291         pll->mod_en = FALSE;
292
293         if (0)
294                 pll->hop_en = TRUE;
295         else
296                 pll->hop_en = FALSE;
297
298         if (pll->hop_en) {
299                 if (origin_freq == 0)
300                         goto FAIL;
301
302                 delta_freq = (int)pll->freq - (int)origin_freq;
303                 if (delta_freq < 0) {
304                         delta_freq = - delta_freq;
305                         pll->sign = TRUE;
306                 }
307                 pll->kstep = pll->ref_clk * hopping_period;
308                 pll->kdelta = (1 << 20) * delta_freq * pll->out_sel
309                                 / pll->kstep / pll->ref_clk;
310         } else
311                 origin_freq = pll->freq;
312
313         return 0;
314
315 FAIL:
316         if (pll)
317                 pll->fvco = 0;
318
319         phy->log_error("sprdfb: failed to calculate dphy pll parameters\n");
320         return ERR_DSI_PHY_PLL_NOT_LOCKED;
321 }
322
323 static int mipi_dsih_dphy_set_pll_reg(dphy_t *phy, struct dphy_pll *pll)
324 {
325         int i;
326         u8 *val;
327
328         struct pll_regs regs;
329         u8 regs_addr[] = {
330                 0x03, 0x04, 0x06, 0x07, 0x08, 0x09,
331                 0x0a, 0x0b, 0x0c, 0x0d, 0x0e
332         };
333
334         if (!pll || !pll->fvco)
335                 goto FAIL;
336
337         memset((u8 *)&regs, '\0', sizeof(regs));
338         regs._03.bits.prbs_bist = 1;
339         regs._03.bits.en_lp_treot = TRUE;
340         regs._03.bits.lpf_sel = pll->lpf_sel;
341         regs._03.bits.txfifo_bypass = 0;
342         regs._03.bits.freq_hopping = pll->hop_en;
343         regs._04.bits.div = pll->div;
344         regs._04.bits.cp_s = pll->cp_s;
345         regs._04.bits.fdk_s = pll->fdk_s;
346         regs._06.bits.nint = pll->nint;
347         regs._06.bits.mod_en = pll->mod_en;
348         regs._07.bits.kdelta_h = pll->kdelta >> 4;
349         regs._07.bits.kdelta_h |= pll->sign << 7;
350         regs._08.bits.vco_band = pll->vco_band;
351         regs._08.bits.sdm_en = pll->sdm_en;
352         regs._08.bits.refin = pll->refin;
353         regs._08.bits.kdelta_l = pll->kdelta & 0xf;
354         regs._09.bits.kint_h = pll->kint >> 12;
355         regs._0a.bits.kint_m = (pll->kint >> 4) & 0xff;
356         regs._0b.bits.out_sel = pll->out_sel;
357         regs._0b.bits.kint_l = pll->kint & 0xf;
358         regs._0c.bits.kstep_h = pll->kstep >> 11;
359         regs._0d.bits.kstep_m = (pll->kstep >> 3) & 0xff;
360         regs._0e.bits.pll_pu_byp = 0;
361         regs._0e.bits.pll_pu = 0;
362         regs._0e.bits.kstep_l = pll->kstep & 0x7;
363
364         val = (u8 *)&regs;
365
366         for (i = 0; i < sizeof(regs_addr); ++i)
367                 mipi_dsih_dphy_write(phy, regs_addr[i], &val[i], 1);
368
369         return 0;
370
371 FAIL:
372         phy->log_error("sprdfb: failed to set dphy pll registers\n");
373         return ERR_DSI_PHY_PLL_NOT_LOCKED;
374 }
375
376 static int mipi_dsih_dphy_config_pll(dphy_t *phy, u32 freq)
377 {
378         int ret;
379         struct dphy_pll pll = {0};
380
381         pll.freq = freq;
382
383         /* FREQ = 26M * (NINT + KINT / 2^20) / out_sel */
384         ret = mipi_dsih_dphy_calc_pll_param(phy, &pll);
385         if (ret)
386                 goto FAIL;
387         ret = mipi_dsih_dphy_set_pll_reg(phy, &pll);
388         if (ret)
389                 goto FAIL;
390
391         return 0;
392
393 FAIL:
394         phy->log_error("sprdfb: failed to config dphy pll\n");
395         return ERR_DSI_PHY_PLL_NOT_LOCKED;
396 }
397
398 static int mipi_dsih_dphy_set_timing_regs(dphy_t *phy, int type, u8 val[])
399 {
400         switch (type) {
401         case REQUEST_TIME:
402                 if (!mipi_dsih_if_dphy_keep_work(phy)) {
403                         mipi_dsih_dphy_write(phy, 0x31, &val[CLK], 1);
404                         mipi_dsih_dphy_write(phy, 0x41, &val[DATA], 1);
405                         mipi_dsih_dphy_write(phy, 0x51, &val[DATA], 1);
406                 } else {
407                         mipi_dsih_dphy_write(phy, 0x90, &val[CLK], 1);
408                         mipi_dsih_dphy_write(phy, 0xa0, &val[DATA], 1);
409                         mipi_dsih_dphy_write(phy, 0xb0, &val[DATA], 1);
410                 }
411                 break;
412         case PREPARE_TIME:
413                 if (!mipi_dsih_if_dphy_keep_work(phy)) {
414                         mipi_dsih_dphy_write(phy, 0x32, &val[CLK], 1);
415                         mipi_dsih_dphy_write(phy, 0x42, &val[DATA], 1);
416                         mipi_dsih_dphy_write(phy, 0x52, &val[DATA], 1);
417                 } else {
418                         mipi_dsih_dphy_write(phy, 0x91, &val[CLK], 1);
419                         mipi_dsih_dphy_write(phy, 0xa1, &val[DATA], 1);
420                         mipi_dsih_dphy_write(phy, 0xb1, &val[DATA], 1);
421                 }
422                 break;
423         case ZERO_TIME:
424                 if (!mipi_dsih_if_dphy_keep_work(phy)) {
425                         mipi_dsih_dphy_write(phy, 0x33, &val[CLK], 1);
426                         mipi_dsih_dphy_write(phy, 0x43, &val[DATA], 1);
427                         mipi_dsih_dphy_write(phy, 0x53, &val[DATA], 1);
428                 } else {
429                         mipi_dsih_dphy_write(phy, 0x92, &val[CLK], 1);
430                         mipi_dsih_dphy_write(phy, 0xa2, &val[DATA], 1);
431                         mipi_dsih_dphy_write(phy, 0xb2, &val[DATA], 1);
432                 }
433                 break;
434         case TRAIL_TIME:
435                 if (!mipi_dsih_if_dphy_keep_work(phy)) {
436                         mipi_dsih_dphy_write(phy, 0x34, &val[CLK], 1);
437                         mipi_dsih_dphy_write(phy, 0x44, &val[DATA], 1);
438                         mipi_dsih_dphy_write(phy, 0x54, &val[DATA], 1);
439                 } else {
440                         mipi_dsih_dphy_write(phy, 0x93, &val[CLK], 1);
441                         mipi_dsih_dphy_write(phy, 0xa3, &val[DATA], 1);
442                         mipi_dsih_dphy_write(phy, 0xb3, &val[DATA], 1);
443                 }
444                 break;
445         case EXIT_TIME:
446                 if (!mipi_dsih_if_dphy_keep_work(phy)) {
447                         mipi_dsih_dphy_write(phy, 0x36, &val[CLK], 1);
448                         mipi_dsih_dphy_write(phy, 0x46, &val[DATA], 1);
449                         mipi_dsih_dphy_write(phy, 0x56, &val[DATA], 1);
450                 } else {
451                         mipi_dsih_dphy_write(phy, 0x95, &val[CLK], 1);
452                         mipi_dsih_dphy_write(phy, 0xA5, &val[DATA], 1);
453                         mipi_dsih_dphy_write(phy, 0xB5, &val[DATA], 1);
454                 }
455                 break;
456         case CLKPOST_TIME:
457                 if (!mipi_dsih_if_dphy_keep_work(phy))
458                         mipi_dsih_dphy_write(phy, 0x35, &val[CLK], 1);
459                 else
460                         mipi_dsih_dphy_write(phy, 0x94, &val[CLK], 1);
461                 break;
462
463         /* the following just use default value */
464         case SETTLE_TIME:
465         case TA_GET:
466         case TA_GO:
467         case TA_SURE:
468                 break;
469         default:
470                 break;
471         }
472         return 0;
473 }
474
475 static int mipi_dsih_dphy_config_lane_timing(dphy_t *phy,
476                                 u32 bitclk, int type)
477 {
478         u8 val[2];
479         u32 tmp = 0;
480         u32 range[2], constant;
481         u32 t_ui, t_byteck, t_half_byteck;
482         const u32 factor = 2;
483         const u32 scale = 100;
484
485         /* t_ui: 1 ui, byteck: 8 ui, half byteck: 4 ui */
486         t_ui = 1000 * scale / (bitclk / 1000);
487         t_byteck = t_ui << 3;
488         t_half_byteck = t_ui << 2;
489         constant = t_ui << 1;
490
491         switch (type) {
492         case NONE:
493         case REQUEST_TIME: /* HS T-LPX: LP-01 */
494                 /*
495                  *                      NOTE
496                  * For T-LPX, mipi spec defined min value is 50ns,
497                  * but maybe it shouldn't be too small, because BTA,
498                  * LP-10, LP-00, LP-01, all of this is related to T-LPX.
499                  */
500                 range[L] = 50 * scale;
501                 range[H] = INFINITY;
502                 val[CLK] = ROUND_UP(range[L] * (factor << 1), t_byteck) - 2;
503                 val[DATA] = val[CLK];
504                 mipi_dsih_dphy_set_timing_regs(phy, REQUEST_TIME, val);
505
506         case PREPARE_TIME: /* HS sequence: LP-00 */
507                 range[L] = 38 * scale; /* clock */
508                 range[H] = 95 * scale;
509                 tmp = AVERAGE(range[L], range[H]);
510                 val[CLK] = ROUND_UP(AVERAGE(range[L], range[H]),
511                                 t_half_byteck) - 1;
512                 range[L] = 40 * scale + 4 * t_ui; /* data */
513                 range[H] = 85 * scale + 6 * t_ui;
514                 tmp |= AVERAGE(range[L], range[H]) << 16;
515                 val[DATA] = ROUND_UP(AVERAGE(range[L], range[H]),
516                                 t_half_byteck) - 1;
517                 mipi_dsih_dphy_set_timing_regs(phy, PREPARE_TIME, val);
518
519         case ZERO_TIME: /* HS-ZERO */
520                 range[L] = 300 * scale; /* clock */
521                 range[H] = INFINITY;
522                 val[CLK] = ROUND_UP(range[L] * factor + (tmp & 0xffff)
523                                 - 525 * t_byteck / 100, t_byteck) - 2;
524                 range[L] = 145 * scale + 10 * t_ui; /* data */
525                 val[DATA] = ROUND_UP(range[L] * factor
526                                 + ((tmp >> 16) & 0xffff) - 525 * t_byteck / 100,
527                                 t_byteck) - 2;
528                 mipi_dsih_dphy_set_timing_regs(phy, ZERO_TIME, val);
529
530         case TRAIL_TIME: /* HS-TRAIL */
531                 range[L] = 60 * scale;
532                 range[H] = INFINITY;
533                 val[CLK] = ROUND_UP(range[L] * factor - constant, t_half_byteck);
534                 range[L] = MAX(8 * t_ui, 60 * scale + 4 * t_ui);
535                 val[DATA] = ROUND_UP(range[L] * factor / 2 - constant, t_half_byteck);
536                 mipi_dsih_dphy_set_timing_regs(phy, TRAIL_TIME, val);
537
538         case EXIT_TIME:
539                 range[L] = 100 * scale;
540                 range[H] = INFINITY;
541                 val[CLK] = ROUND_UP(range[L] * factor, t_byteck) - 2;
542                 val[DATA] = val[CLK];
543                 mipi_dsih_dphy_set_timing_regs(phy, EXIT_TIME, val);
544
545         case CLKPOST_TIME:
546                 range[L] = 60 * scale + 52 * t_ui;
547                 range[H] = INFINITY;
548                 val[CLK] = ROUND_UP(range[L] * factor, t_byteck) - 2;
549                 val[DATA] = val[CLK];
550                 mipi_dsih_dphy_set_timing_regs(phy, CLKPOST_TIME, val);
551
552         case SETTLE_TIME:
553                 /*
554                  * This time is used for receiver. So for transmitter,
555                  * it can be ignored.
556                  */
557         case TA_GO:
558                 /*
559                  * transmitter drives bridge state(LP-00) before releasing control,
560                  * reg 0x1f default value: 0x04, which is good.
561                  */
562         case TA_SURE:
563                 /*
564                  * After LP-10 state and before bridge state(LP-00),
565                  * reg 0x20 default value: 0x01, which is good.
566                  */
567         case TA_GET:
568                 /*
569                  * receiver drives Bridge state(LP-00) before releasing control
570                  * reg 0x21 default value: 0x03, which is good.
571                  */
572                 break;
573         default:
574                 break;
575         }
576         return 0;
577 }
578
579 static int mipi_dsih_dphy_powerup(dphy_t *phy, int enable)
580 {
581         /*
582          * Make sure that DSI IP is connected to TestChip IO
583          *
584          * get the PHY in power down mode (shutdownz = 0) and
585          * reset it (rstz = 0) to avoid transient periods in
586          * PHY operation during re-configuration procedures.
587          */
588         if (enable) {
589                 mipi_dsih_dphy_clock_en(phy, TRUE);
590                 mipi_dsih_dphy_stop_wait_time(phy, 0x1C);
591                 mipi_dsih_dphy_clock_en(phy, TRUE);
592                 mipi_dsih_dphy_shutdown(phy, FALSE);
593                 mipi_dsih_dphy_reset(phy, FALSE);
594         } else {
595                 mipi_dsih_dphy_reset(phy, TRUE);
596                 mipi_dsih_dphy_shutdown(phy, TRUE);
597                 mipi_dsih_dphy_clock_en(phy, FALSE);
598                 /* provide an initial active-high test clear pulse in TESTCLR */
599                 /* DPHY registers will be reset after test clear is set to high */
600                 mipi_dsih_dphy_test_clear(phy, 0);
601                 mipi_dsih_dphy_test_clear(phy, 1);
602                 mipi_dsih_dphy_test_clear(phy, 0);
603         }
604         return 0;
605 }
606
607 /**
608  * Configure D-PHY and PLL module to desired operation mode
609  * @param phy: pointer to structure
610  *  which holds information about the d-phy module
611  * @param no_of_lanes active
612  * @param output_freq desired high speed frequency
613  * @return error code
614  */
615 dsih_error_t mipi_dsih_dphy_configure(dphy_t *phy,
616                                 u8 lane_num,
617                                 u32 output_freq)
618 {
619         if (!phy)
620                 return ERR_DSI_INVALID_INSTANCE;
621         if (phy->status < INITIALIZED)
622                 return ERR_DSI_INVALID_INSTANCE;
623         if (output_freq < MIN_OUTPUT_FREQ)
624                 return ERR_DSI_PHY_FREQ_OUT_OF_BOUND;
625
626         if (!mipi_dsih_if_dphy_keep_work(phy))
627                 mipi_dsih_dphy_powerup(phy, FALSE);
628
629         /* set up board depending on environment if any */
630         if (phy->bsp_pre_config)
631                 phy->bsp_pre_config(phy, 0);
632
633         mipi_dsih_dphy_config_pll(phy, output_freq);
634         mipi_dsih_dphy_config_lane_timing(phy, output_freq, NONE);
635         mipi_dsih_dphy_no_of_lanes(phy, lane_num);
636
637         if (!mipi_dsih_if_dphy_keep_work(phy))
638                 mipi_dsih_dphy_powerup(phy, TRUE);
639
640         return 0;
641 }
642
643 /**
644  * Close and power down D-PHY module
645  * @param phy pointer to structure which holds information about the d-phy
646  * module
647  * @return error code
648  */
649 dsih_error_t mipi_dsih_dphy_close(dphy_t *phy)
650 {
651         if (!phy)
652                 return ERR_DSI_INVALID_INSTANCE;
653
654         if (!phy->core_read_function || !phy->core_write_function)
655                 return ERR_DSI_INVALID_IO;
656
657         if (phy->status < INITIALIZED)
658                 return ERR_DSI_INVALID_INSTANCE;
659
660         mipi_dsih_dphy_reset(phy, TRUE);
661         mipi_dsih_dphy_shutdown(phy, TRUE);
662         mipi_dsih_dphy_reset(phy, FALSE);
663         phy->status = NOT_INITIALIZED;
664
665         return OK;
666 }
667
668 /**
669  * Enable clock lane module
670  * @param phy pointer to structure
671  *  which holds information about the d-phy module
672  * @param en
673  */
674 void mipi_dsih_dphy_clock_en(dphy_t *phy, int en)
675 {
676         mipi_dsih_dphy_write_part(phy, R_DPHY_RSTZ, en, 2, 1);
677 }
678
679 /**
680  * SPRD ADD
681  * Set non-continuous clock mode
682  * @param phy pointer to structure
683  * which holds information about the d-phy module
684  * @param enable 1: enable non continuous clock
685  */
686 void mipi_dsih_dphy_enable_nc_clk(dphy_t *phy, int enable)
687 {
688         mipi_dsih_dphy_write_part(phy, R_DPHY_LPCLK_CTRL, enable, 1, 1);
689 }
690
691 /**
692  * Reset D-PHY module
693  * @param phy: pointer to structure
694  *  which holds information about the d-phy module
695  * @param reset
696  */
697 void mipi_dsih_dphy_reset(dphy_t *phy, int enable)
698 {
699         mipi_dsih_dphy_write_part(phy, R_DPHY_RSTZ, !!!enable, 1, 1);
700 }
701
702 /**
703  * Power up/down D-PHY module
704  * @param phy: pointer to structure
705  *  which holds information about the d-phy module
706  * @param enable (1: shutdown)
707  */
708 void mipi_dsih_dphy_shutdown(dphy_t *phy, int enable)
709 {
710         mipi_dsih_dphy_write_part(phy, R_DPHY_RSTZ, !!!enable, 0, 1);
711 }
712
713 /**
714  * Force D-PHY PLL to stay on while in ULPS
715  * @param phy: pointer to structure
716  *  which holds information about the d-phy module
717  * @param force (1) disable (0)
718  * @note To follow the programming model, use wakeup_pll function
719  */
720 void mipi_dsih_dphy_force_pll(dphy_t *phy, int force)
721 {
722         u8 data;
723
724         if (force)
725                 data = 0x03;
726         else
727                 data = 0x0;
728
729         /* for megocores, to force pll, dphy register should be set */
730         mipi_dsih_dphy_write(phy, 0x0e, &data, 1);
731
732         mipi_dsih_dphy_write_part(phy, R_DPHY_RSTZ, force, 3, 1);
733 }
734
735 /**
736  * Get force D-PHY PLL module
737  * @param phy pointer to structure
738  *  which holds information about the d-phy module
739  * @return force value
740  */
741 int mipi_dsih_dphy_get_force_pll(dphy_t *phy)
742 {
743         /* FIXME: TODO: for megacores, this status is not true */
744         return mipi_dsih_dphy_read_part(phy, R_DPHY_RSTZ, 3, 1);
745 }
746
747 /**
748  * Wake up or make sure D-PHY PLL module is awake
749  * This function must be called after going into ULPS and before exiting it
750  * to force the DPHY PLLs to wake up. It will wait until the DPHY status is
751  * locked. It follows the procedure described in the user guide.
752  * This function should be used to make sure the PLL is awake, rather than
753  * the force_pll above.
754  * @param phy pointer to structure which holds information about the d-phy
755  * module
756  * @return error code
757  * @note this function has an active wait
758  */
759 int mipi_dsih_dphy_wakeup_pll(dphy_t *phy)
760 {
761         unsigned i = 0;
762
763         if (mipi_dsih_dphy_status(phy, 0x1))
764                 return OK;
765
766         mipi_dsih_dphy_force_pll(phy, 1);
767
768         for (i = 0; i < DSIH_PHY_ACTIVE_WAIT; i++) {
769                 if (mipi_dsih_dphy_status(phy, 0x1))
770                         break;
771         }
772
773         if (mipi_dsih_dphy_status(phy, 0x1) == 0)
774                 return ERR_DSI_PHY_PLL_NOT_LOCKED;
775
776         return OK;
777 }
778
779 /**
780  * Configure minimum wait period for HS transmission request after a stop state
781  * @param phy pointer to structure which holds information about the d-phy
782  * module
783  * @param no_of_byte_cycles [in byte (lane) clock cycles]
784  */
785 void mipi_dsih_dphy_stop_wait_time(dphy_t *phy,
786                                 u8 no_of_byte_cycles)
787 {
788         mipi_dsih_dphy_write_part(phy,
789                         R_DPHY_IF_CFG,
790                         no_of_byte_cycles,
791                         8, 8);
792 }
793
794 /**
795  * Set number of active lanes
796  * @param phy: pointer to structure
797  *  which holds information about the d-phy module
798  * @param no_of_lanes
799  */
800 void mipi_dsih_dphy_no_of_lanes(dphy_t *phy, u8 no_of_lanes)
801 {
802         /* currently, dphy only support 2 lanes */
803         if (no_of_lanes > MAX_LANES)
804                 no_of_lanes = MAX_LANES;
805
806         mipi_dsih_dphy_write_part(phy, R_DPHY_IF_CFG,
807                         no_of_lanes - 1, 0, 2);
808 }
809
810 /**
811  * Get number of currently active lanes
812  * @param phy: pointer to structure
813  *  which holds information about the d-phy module
814  * @return number of active lanes
815  */
816 u8 mipi_dsih_dphy_get_no_of_lanes(dphy_t *phy)
817 {
818         return mipi_dsih_dphy_read_part(phy, R_DPHY_IF_CFG, 0, 2);
819 }
820
821 /**
822  * Request the PHY module to start transmission of high speed clock.
823  * This causes the clock lane to start transmitting DDR clock on the
824  * lane interconnect.
825  * @param phy pointer to structure which holds information about the d-phy
826  * module
827  * @param enable
828  * @note this function should be called explicitly by user always except for
829  * transmitting
830  */
831 void mipi_dsih_dphy_enable_hs_clk(dphy_t *phy, int enable)
832 {
833         mipi_dsih_dphy_write_part(phy, R_DPHY_LPCLK_CTRL, enable, 0, 1);
834 }
835
836 /**
837  * One bit is asserted in the trigger_request (4bits) to cause the lane module
838  * to cause the associated trigger to be sent across the lane interconnect.
839  * The trigger request is synchronous with the rising edge of the clock.
840  * @note: Only one bit of the trigger_request is asserted at any given time, the
841  * remaining must be left set to 0, and only when not in LPDT or ULPS modes
842  * @param phy pointer to structure which holds information about the d-phy
843  * module
844  * @param trigger_request 4 bit request
845  */
846 dsih_error_t mipi_dsih_dphy_escape_mode_trigger(dphy_t *phy,
847                                 u8 trigger_request)
848 {
849         u8 sum = 0;
850         int i = 0;
851         for (i = 0; i < 4; i++) {
852                 sum += ((trigger_request >> i) & 1);
853         }
854
855         if (sum == 1) { /* clear old trigger */
856                 mipi_dsih_dphy_write_part(phy, R_DPHY_TX_TRIGGERS,
857                                 0x00, 0, 4);
858                 mipi_dsih_dphy_write_part(phy, R_DPHY_TX_TRIGGERS,
859                                 trigger_request, 0, 4);
860
861                 for (i = 0; i < DSIH_PHY_ACTIVE_WAIT; i++) {
862                         if (mipi_dsih_dphy_status(phy, 0x0010)) {
863                                 break;
864                         }
865                 }
866                 mipi_dsih_dphy_write_part(phy, R_DPHY_TX_TRIGGERS, 0x00, 0, 4);
867                 if (i >= DSIH_PHY_ACTIVE_WAIT)
868                         return ERR_DSI_TIMEOUT;
869
870                 return OK;
871         }
872         return ERR_DSI_INVALID_COMMAND;
873 }
874
875 /**
876  * ULPS mode request/exit on all active data lanes.
877  * @param phy pointer to structure which holds information about the d-phy
878  * module
879  * @param enable (request 1/ exit 0)
880  * @return error code
881  * @note this is a blocking function. wait upon exiting the ULPS will exceed 1ms
882  */
883 dsih_error_t mipi_dsih_dphy_ulps_data_lanes(dphy_t *phy, int enable)
884 {
885         int timeout;
886         /* mask 1 0101 0010 0000 */
887         u16 data_lanes_mask = 0;
888
889         if (enable) {
890                 mipi_dsih_dphy_write_part(phy, R_DPHY_ULPS_CTRL, 1, 2, 1);
891                 return OK;
892         } else {
893                 if (!mipi_dsih_dphy_status(phy, 0x1))
894                         return ERR_DSI_PHY_PLL_NOT_LOCKED;
895
896                 mipi_dsih_dphy_write_part(phy, R_DPHY_ULPS_CTRL, 1, 3, 1);
897                 switch (mipi_dsih_dphy_get_no_of_lanes(phy)) {
898                 /* Fall through */
899                 case 3:
900                         data_lanes_mask |= (1 << 12);
901                 /* Fall through */
902                 case 2:
903                         data_lanes_mask |= (1 << 10);
904                 /* Fall through */
905                 case 1:
906                         data_lanes_mask |= (1 << 8);
907                 /* Fall through */
908                 case 0:
909                         data_lanes_mask |= (1 << 5);
910                         break;
911                 default:
912                         data_lanes_mask = 0;
913                         break;
914                 }
915                 /* verify that the DPHY has left ULPM */
916                 for (timeout = 0; timeout < DSIH_PHY_ACTIVE_WAIT; timeout++) {
917                         if (mipi_dsih_dphy_status(phy, data_lanes_mask)
918                                         == data_lanes_mask)
919                                 break;
920                         /* wait at least 1ms */
921                         for (timeout = 0; timeout < ONE_MS_ACTIVE_WAIT; timeout++)
922                                 ;
923                 }
924
925                 if (mipi_dsih_dphy_status(phy, data_lanes_mask)
926                                 != data_lanes_mask) {
927                         phy->log_info("stat %x, mask %x",
928                                         mipi_dsih_dphy_status(phy, data_lanes_mask),
929                                         data_lanes_mask);
930                         return ERR_DSI_TIMEOUT;
931                 }
932                 mipi_dsih_dphy_write_part(phy, R_DPHY_ULPS_CTRL, 0, 2, 1);
933                 mipi_dsih_dphy_write_part(phy, R_DPHY_ULPS_CTRL, 0, 3, 1);
934         }
935         return OK;
936 }
937
938 /**
939  * ULPS mode request/exit on Clock Lane.
940  * @param phy pointer to structure which holds information about the
941  * d-phy module
942  * @param enable 1 or disable 0 of the Ultra Low Power State of the clock lane
943  * @return error code
944  * @note this is a blocking function. wait upon exiting the ULPS will exceed 1ms
945  */
946 dsih_error_t mipi_dsih_dphy_ulps_clk_lane(dphy_t *phy, int enable)
947 {
948         int timeout;
949         /* mask 1000 */
950         u16 clk_lane_mask = 0x0008;
951         if (enable)
952                 mipi_dsih_dphy_write_part(phy, R_DPHY_ULPS_CTRL, 1, 0, 1);
953         else {
954                 if (!mipi_dsih_dphy_status(phy, 0x1))
955                         return ERR_DSI_PHY_PLL_NOT_LOCKED;
956
957                 mipi_dsih_dphy_write_part(phy, R_DPHY_ULPS_CTRL, 1, 1, 1);
958                 /* verify that the DPHY has left ULPM */
959                 for (timeout = 0; timeout < DSIH_PHY_ACTIVE_WAIT; timeout++) {
960                         if (mipi_dsih_dphy_status(phy, clk_lane_mask)
961                                         == clk_lane_mask) {
962                                 phy->log_info("stat %x, mask %x",
963                                                 mipi_dsih_dphy_status(phy, clk_lane_mask),
964                                                 clk_lane_mask);
965                                 break;
966                         }
967                         /* wait at least 1ms */
968                         /* dummy operation for the loop not to be optimised */
969                         for (timeout = 0; timeout < ONE_MS_ACTIVE_WAIT; timeout++)
970                                 enable = mipi_dsih_dphy_status(phy, clk_lane_mask);
971                 }
972                 if (mipi_dsih_dphy_status(phy, clk_lane_mask) != clk_lane_mask)
973                         return ERR_DSI_TIMEOUT;
974
975                 mipi_dsih_dphy_write_part(phy, R_DPHY_ULPS_CTRL, 0, 0, 1);
976                 mipi_dsih_dphy_write_part(phy, R_DPHY_ULPS_CTRL, 0, 1, 1);
977         }
978         return OK;
979 }
980
981 /**
982  * Get D-PHY PPI status
983  * @param phy pointer to structure which holds information about the d-phy
984  * module
985  * @param mask
986  * @return status
987  */
988 u32 mipi_dsih_dphy_status(dphy_t *phy, u16 mask)
989 {
990         return mipi_dsih_dphy_read_word(phy, R_DPHY_STATUS) & mask;
991 }
992
993 /**
994  * @param phy pointer to structure which holds information about the d-phy
995  * module
996  * @param value
997  */
998 void mipi_dsih_dphy_test_clock(dphy_t *phy, int value)
999 {
1000         mipi_dsih_dphy_write_part(phy, R_DPHY_TST_CRTL0, value, 1, 1);
1001 }
1002
1003 /**
1004  * @param phy pointer to structure which holds information about the d-phy
1005  * module
1006  * @param value
1007  */
1008 void mipi_dsih_dphy_test_clear(dphy_t *phy, int value)
1009 {
1010         mipi_dsih_dphy_write_part(phy, R_DPHY_TST_CRTL0, value, 0, 1);
1011 }
1012
1013 /**
1014  * @param phy pointer to structure which holds information about the d-phy
1015  * module
1016  * @param on_falling_edge
1017  */
1018 void mipi_dsih_dphy_test_en(dphy_t *phy, u8 on_falling_edge)
1019 {
1020         mipi_dsih_dphy_write_part(phy, R_DPHY_TST_CRTL1,
1021                         on_falling_edge, 16, 1);
1022 }
1023
1024 /**
1025  * @param phy pointer to structure which holds information about the d-phy
1026  * module
1027  */
1028 u8 mipi_dsih_dphy_test_data_out(dphy_t *phy)
1029 {
1030         return mipi_dsih_dphy_read_part(phy, R_DPHY_TST_CRTL1, 8, 8);
1031 }
1032
1033 /**
1034  * @param phy pointer to structure which holds information about the d-phy
1035  * module
1036  * @param test_data
1037  */
1038 void mipi_dsih_dphy_test_data_in(dphy_t *phy, u8 test_data)
1039 {
1040         mipi_dsih_dphy_write_word(phy, R_DPHY_TST_CRTL1, test_data);
1041 }
1042
1043 /**
1044  * Write to D-PHY module (encapsulating the digital interface)
1045  * @param phy pointer to structure which holds information about the d-phy
1046  * module
1047  * @param address offset inside the D-PHY digital interface
1048  * @param data array of bytes to be written to D-PHY
1049  * @param data_length of the data array
1050  */
1051 void mipi_dsih_dphy_write(dphy_t *phy, u8 address,
1052                                 u8 *data, u8 data_length)
1053 {
1054         int i = 0;
1055
1056         if (data) {
1057                 /*
1058                  * set the TESTCLK input high in preparation
1059                  * to latch in the desired test mode
1060                  */
1061                 mipi_dsih_dphy_test_clock(phy, 1);
1062                 /* set the desired test code in the input 8-bit bus TESTDIN[7:0] */
1063                 mipi_dsih_dphy_test_data_in(phy, address);
1064                 /* set TESTEN input high  */
1065                 mipi_dsih_dphy_test_en(phy, 1);
1066                 /*
1067                  * drive the TESTCLK input low;
1068                  * the falling edge captures the chosen test code
1069                  * into the transceiver
1070                  */
1071                 mipi_dsih_dphy_test_clock(phy, 0);
1072                 /*
1073                  * set TESTEN input low
1074                  * to disable further test mode code latching
1075                  */
1076                 mipi_dsih_dphy_test_en(phy, 0);
1077
1078                 /*
1079                  * start writing MSB first
1080                  * set TESTDIN[7:0] to the desired test data appropriate
1081                  * to the chosen test mode
1082                  */
1083                 for (i = data_length; i > 0; i--) {
1084                         mipi_dsih_dphy_test_data_in(phy, data[i - 1]);
1085                         /*
1086                          * pulse TESTCLK high to capture this test data
1087                          * into the macrocell; repeat these two steps as necessary
1088                          */
1089                         mipi_dsih_dphy_test_clock(phy, 1);
1090                         mipi_dsih_dphy_test_clock(phy, 0);
1091                 }
1092         }
1093 }
1094
1095 /**
1096  * Write to whole register to D-PHY module (encapsulating the bus interface)
1097  * @param phy pointer to structure which holds information about the d-phy
1098  * module
1099  * @param reg_address offset
1100  * @param data 32-bit word
1101  */
1102 void mipi_dsih_dphy_write_word(dphy_t *phy,
1103                                 u32 reg_address, u32 data)
1104 {
1105         if (phy->core_write_function)
1106                 phy->core_write_function(phy->address,
1107                                 reg_address, data);
1108 }
1109
1110 /**
1111  * Write bit field to D-PHY module (encapsulating the bus interface)
1112  * @param phy pointer to structure which holds information about the d-phy
1113  * module
1114  * @param reg_address offset
1115  * @param data bits to be written to D-PHY
1116  * @param shift from the right hand side of the register (big endian)
1117  * @param width of the bit field
1118  */
1119 void mipi_dsih_dphy_write_part(dphy_t *phy,
1120                                 u32 reg_address, u32 data,
1121                                 u8 shift, u8 width)
1122 {
1123         u32 mask = 0;
1124         u32 temp = 0;
1125
1126         if (phy->core_read_function) {
1127                 mask = (1 << width) - 1;
1128                 temp = mipi_dsih_dphy_read_word(phy, reg_address);
1129                 temp &= ~(mask << shift);
1130                 temp |= (data & mask) << shift;
1131                 mipi_dsih_dphy_write_word(phy, reg_address, temp);
1132         }
1133 }
1134
1135 /**
1136  * Read whole register from D-PHY module (encapsulating the bus interface)
1137  * @param phy pointer to structure which holds information about the d-phy
1138  * module
1139  * @param reg_address offset
1140  * @return data 32-bit word
1141  */
1142 u32 mipi_dsih_dphy_read_word(dphy_t *phy, u32 reg_address)
1143 {
1144         if (!phy->core_read_function)
1145                 return ERR_DSI_INVALID_IO;
1146
1147         return phy->core_read_function(phy->address, reg_address);
1148 }
1149
1150 /**
1151  * Read bit field from D-PHY module (encapsulating the bus interface)
1152  * @param phy pointer to structure which holds information about the d-phy
1153  * module
1154  * @param reg_address offset
1155  * @param shift from the right hand side of the register (big endian)
1156  * @param width of the bit field
1157  * @return data bits to be written to D-PHY
1158  */
1159 u32 mipi_dsih_dphy_read_part(dphy_t *phy,
1160                                 u32 reg_address,
1161                                 u8 shift,
1162                                 u8 width)
1163 {
1164         return (mipi_dsih_dphy_read_word(phy, reg_address) >> shift)
1165                         & ((1 << width) - 1);
1166 }