• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (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  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include "mipi_tx_hal.h"
20 #include "hi_osal.h"
21 #include "type.h"
22 #include "mipi_tx.h"
23 #include "mipi_tx_reg.h"
24 
25 #ifdef __cplusplus
26 #if __cplusplus
27 extern "C" {
28 #endif
29 #endif /* End of #ifdef __cplusplus */
30 
31 #define MIPI_TX_REGS_ADDR   0x11270000
32 #define MIPI_TX_REGS_SIZE   0x10000
33 
34 #define MIPI_TX_IRQ         120
35 
36 #define MIPI_TX_CRG         0x1201010C
37 
38 #define MIPI_TX_REF_CLK     27
39 
40 #define TLPX                60
41 #define TCLK_PREPARE        60
42 #define TCLK_ZERO           250
43 #define TCLK_TRAIL          80
44 #define TPRE_DELAY          100
45 #define THS_PREPARE         80
46 #define THS_ZERO            180
47 #define THS_TRAIL           110
48 
49 /* phy addr */
50 #define PLL_SET0            0x60
51 #define PLL_SET1            0x64
52 #define PLL_SET2            0x65
53 #ifdef HI_FPGA
54 #define PLL_SET3            0x17
55 #endif
56 #define PLL_SET4            0x66
57 #define PLL_SET5            0x67
58 
59 #define DATA0_TPRE_DELAY    0x28
60 #define DATA1_TPRE_DELAY    0x38
61 #define DATA2_TPRE_DELAY    0x48
62 #define DATA3_TPRE_DELAY    0x58
63 
64 #define CLK_TLPX            0x10
65 #define CLK_TCLK_PREPARE    0x11
66 #define CLK_TCLK_ZERO       0x12
67 #define CLK_TCLK_TRAIL      0x13
68 
69 #define DATA0_TLPX          0x20
70 #define DATA0_THS_PREPARE   0x21
71 #define DATA0_THS_ZERO      0x22
72 #define DATA0_THS_TRAIL     0x23
73 #define DATA1_TLPX          0x30
74 #define DATA1_THS_PREPARE   0x31
75 #define DATA1_THS_ZERO      0x32
76 #define DATA1_THS_TRAIL     0x33
77 #define DATA2_TLPX          0x40
78 #define DATA2_THS_PREPARE   0x41
79 #define DATA2_THS_ZERO      0x42
80 #define DATA2_THS_TRAIL     0x43
81 #define DATA3_TLPX          0x50
82 #define DATA3_THS_PREPARE   0x51
83 #define DATA3_THS_ZERO      0x52
84 #define DATA3_THS_TRAIL     0x53
85 
86 #define MIPI_TX_READ_TIMEOUT_CNT 1000
87 
88 #define PREPARE_COMPENSATE    10
89 #define ROUNDUP_VALUE     7999
90 #define INNER_PEROID      8000   /* 8 * 1000 ,1000 is 1us = 1000ns, 8 is division ratio */
91 
92 typedef struct {
93     unsigned char data_tpre_delay;
94     unsigned char clk_tlpx;
95     unsigned char clk_tclk_prepare;
96     unsigned char clk_tclk_zero;
97     unsigned char clk_tclk_trail;
98     unsigned char data_tlpx;
99     unsigned char data_ths_prepare;
100     unsigned char data_ths_zero;
101     unsigned char data_ths_trail;
102 } mipi_tx_phy_timing_parameters;
103 
104 volatile mipi_tx_regs_type_t *g_mipi_tx_regs_va = NULL;
105 
106 unsigned int g_mipi_tx_irq_num = MIPI_TX_IRQ;
107 
108 unsigned int g_actual_phy_data_rate;
109 
110 static unsigned int g_reg_map_flag = 0;
111 
write_reg32(unsigned long addr,unsigned int value,unsigned int mask)112 static void write_reg32(unsigned long addr, unsigned int value, unsigned int mask)
113 {
114     unsigned int t;
115 
116     t = osal_readl(addr);
117     t &= ~mask;
118     t |= value & mask;
119     osal_writel(t, addr);
120 }
121 
set_phy_reg(unsigned int addr,unsigned char value)122 static void set_phy_reg(unsigned int addr, unsigned char value)
123 {
124     osal_isb();
125     osal_dsb();
126     osal_dmb();
127     g_mipi_tx_regs_va->PHY_TST_CTRL1.u32 = (0x10000 + addr);
128     osal_isb();
129     osal_dsb();
130     osal_dmb();
131     g_mipi_tx_regs_va->PHY_TST_CTRL0.u32 = 0x2;
132     osal_isb();
133     osal_dsb();
134     osal_dmb();
135     g_mipi_tx_regs_va->PHY_TST_CTRL0.u32 = 0x0;
136     osal_isb();
137     osal_dsb();
138     osal_dmb();
139     g_mipi_tx_regs_va->PHY_TST_CTRL1.u32 = value;
140     osal_isb();
141     osal_dsb();
142     osal_dmb();
143     g_mipi_tx_regs_va->PHY_TST_CTRL0.u32 = 0x2;
144     osal_isb();
145     osal_dsb();
146     osal_dmb();
147     g_mipi_tx_regs_va->PHY_TST_CTRL0.u32 = 0x0;
148     osal_isb();
149     osal_dsb();
150     osal_dmb();
151 }
152 
mipi_tx_drv_get_phy_pll_set0(unsigned int phy_data_rate)153 static unsigned char mipi_tx_drv_get_phy_pll_set0(unsigned int phy_data_rate)
154 {
155     unsigned char pll_set0;
156 
157     /* to get pll_set0, the parameters come from algorithm */
158     if (phy_data_rate > 750) { // 750 is data rate value, Different values correspond to different pll_set.
159         pll_set0 = 0x0;
160     } else if (phy_data_rate > 375) { // 375 is data rate value, Different values correspond to different pll_set.
161         pll_set0 = 0x8;
162     } else if (phy_data_rate > 188) { // 188 is data rate value, Different values correspond to different pll_set.
163         pll_set0 = 0xa;
164     } else if (phy_data_rate > 94) { // 94 is data rate value, Different values correspond to different pll_set.
165         pll_set0 = 0xc;
166     } else {
167         pll_set0 = 0xe;
168     }
169     return pll_set0;
170 }
171 
mipi_tx_drv_get_phy_pll_set1_set5(unsigned int phy_data_rate,unsigned char pll_set0,unsigned char * pll_set1,unsigned char * pll_set5)172 static void mipi_tx_drv_get_phy_pll_set1_set5(unsigned int phy_data_rate,
173     unsigned char pll_set0,
174     unsigned char *pll_set1,
175     unsigned char *pll_set5)
176 {
177     int datarate_clk;
178     int pll_ref;
179 
180     datarate_clk = (phy_data_rate + MIPI_TX_REF_CLK - 1) / MIPI_TX_REF_CLK;
181 
182     /* to get pll_set1 and pll_set5, the parameters come from algorithm */
183     if (pll_set0 / 2 == 4) {
184         pll_ref = 2;
185     } else if (pll_set0 / 2 == 5) {
186         pll_ref = 4;
187     } else if (pll_set0 / 2 == 6) {
188         pll_ref = 8;
189     } else if (pll_set0 / 2 == 7) {
190         pll_ref = 16;
191     } else {
192         pll_ref = 1;
193     }
194     if ((datarate_clk * pll_ref) % 2) {
195         *pll_set1 = 0x10;
196         *pll_set5 = (datarate_clk * pll_ref - 1) / 2;
197     } else {
198         *pll_set1 = 0x20;
199         *pll_set5 = datarate_clk * pll_ref / 2 - 1;
200     }
201 
202     return;
203 }
204 
mipi_tx_drv_set_phy_pll_setx(unsigned int phy_data_rate)205 static void mipi_tx_drv_set_phy_pll_setx(unsigned int phy_data_rate)
206 {
207     unsigned char pll_set0;
208     unsigned char pll_set1;
209     unsigned char pll_set2;
210 #ifdef HI_FPGA
211     unsigned char pll_set3;
212 #endif
213     unsigned char pll_set4;
214     unsigned char pll_set5;
215 
216     /* pll_set0 */
217     pll_set0 = mipi_tx_drv_get_phy_pll_set0(phy_data_rate);
218     set_phy_reg(PLL_SET0, pll_set0);
219 
220     /* pll_set1 */
221     mipi_tx_drv_get_phy_pll_set1_set5(phy_data_rate, pll_set0, &pll_set1, &pll_set5);
222     set_phy_reg(PLL_SET1, pll_set1);
223 
224     /* pll_set2 */
225     pll_set2 = 0x2;
226     set_phy_reg(PLL_SET2, pll_set2);
227 
228     /* pll_set4 */
229     pll_set4 = 0x0;
230     set_phy_reg(PLL_SET4, pll_set4);
231 
232 #ifdef HI_FPGA
233     pll_set3 = 0x1;
234     set_phy_reg(PLL_SET3, pll_set3);
235 #endif
236 
237     /* pll_set5 */
238     set_phy_reg(PLL_SET5, pll_set5);
239 
240 #ifdef MIPI_TX_DEBUG
241     osal_printk("\n==========phy pll info=======\n");
242     osal_printk("pll_set0(0x14): 0x%x\n", pll_set0);
243     osal_printk("pll_set1(0x15): 0x%x\n", pll_set1);
244     osal_printk("pll_set2(0x16): 0x%x\n", pll_set2);
245 #ifdef HI_FPGA
246     osal_printk("pll_set3(0x17): 0x%x\n", pll_set3);
247 #endif
248     osal_printk("pll_set4(0x1e): 0x%x\n", pll_set4);
249     osal_printk("=========================\n");
250 #endif
251 }
252 
mipi_tx_drv_get_phy_clk_prepare(unsigned char * clk_prepare)253 static void mipi_tx_drv_get_phy_clk_prepare(unsigned char *clk_prepare)
254 {
255     unsigned char temp0;
256     unsigned char temp1;
257 
258     temp0 = ((g_actual_phy_data_rate * TCLK_PREPARE + ROUNDUP_VALUE) / INNER_PEROID - 1 +
259             ((g_actual_phy_data_rate * PREPARE_COMPENSATE + ROUNDUP_VALUE) / INNER_PEROID) -
260             ((((g_actual_phy_data_rate * TCLK_PREPARE + ROUNDUP_VALUE) / INNER_PEROID +
261             ((g_actual_phy_data_rate * PREPARE_COMPENSATE + ROUNDUP_VALUE) / INNER_PEROID)) * INNER_PEROID -
262             PREPARE_COMPENSATE * g_actual_phy_data_rate - TCLK_PREPARE * g_actual_phy_data_rate) / INNER_PEROID));
263     if (temp0 > 0) { /* 0 is the minimum  */
264         temp1 = temp0;
265     } else {
266         temp1 = 0; /* 0 is the minimum  */
267     }
268 
269     if (((temp1 + 1) * INNER_PEROID - PREPARE_COMPENSATE * g_actual_phy_data_rate) /* temp + 1 is next level period */
270         > 94 * g_actual_phy_data_rate) { /* 94 is the  maximum in mipi protocol */
271         if (temp0 > 0) {
272             *clk_prepare = temp0 - 1;
273         } else {
274             *clk_prepare = 255; /* set 255 will easy to found mistake */
275             hi_mipi_tx_err("err when calc phy timing \n");
276         }
277     } else {
278         if (temp0 > 0) { /* 0 is the minimum  */
279             *clk_prepare = temp0;
280         } else {
281             *clk_prepare = 0; /* 0 is the minimum  */
282         }
283     }
284 }
285 
mipi_tx_drv_get_phy_data_prepare(unsigned char * data_prepare)286 static void mipi_tx_drv_get_phy_data_prepare(unsigned char *data_prepare)
287 {
288     unsigned char temp0;
289     unsigned char temp1;
290 
291     /* DATA_THS_PREPARE */
292     temp0 = ((g_actual_phy_data_rate * THS_PREPARE + ROUNDUP_VALUE) / INNER_PEROID - 1 +
293             ((g_actual_phy_data_rate * PREPARE_COMPENSATE + ROUNDUP_VALUE) / INNER_PEROID) -
294             ((((g_actual_phy_data_rate * THS_PREPARE + ROUNDUP_VALUE) / INNER_PEROID +
295             ((g_actual_phy_data_rate * PREPARE_COMPENSATE + ROUNDUP_VALUE) / INNER_PEROID)) * INNER_PEROID -
296             PREPARE_COMPENSATE * g_actual_phy_data_rate - THS_PREPARE * g_actual_phy_data_rate) / INNER_PEROID));
297     if (temp0 > 0) {
298         temp1 = temp0;
299     } else {
300         temp1 = 0;
301     }
302 
303     if ((g_actual_phy_data_rate > 105) && /* bigger than 105 */
304         (((temp1 + 1) * INNER_PEROID - PREPARE_COMPENSATE * g_actual_phy_data_rate) >
305         (85 * g_actual_phy_data_rate + 6 * 1000))) { /* 85 + 6 * 1000 is the  maximum in mipi protocol */
306         if (temp0 > 0) {
307             *data_prepare = temp0 - 1;
308         } else {
309             *data_prepare = 255; /* set 255 will easy to found mistake */
310             hi_mipi_tx_err("err when calc phy timing \n");
311         }
312     } else {
313         if (temp0 > 0) {
314             *data_prepare = temp0;
315         } else {
316             *data_prepare = 0;
317         }
318     }
319 }
320 
321 /* get global operation timing parameters. */
mipi_tx_drv_get_phy_timing_parameters(mipi_tx_phy_timing_parameters * tp)322 static void mipi_tx_drv_get_phy_timing_parameters(mipi_tx_phy_timing_parameters *tp)
323 {
324     /* DATA0~3 TPRE-DELAY */
325     tp->data_tpre_delay = (g_actual_phy_data_rate * TPRE_DELAY + ROUNDUP_VALUE) /
326                           INNER_PEROID - 1; /* 1 is compensate */
327     /* CLK_TLPX */
328     tp->clk_tlpx = (g_actual_phy_data_rate * TLPX + ROUNDUP_VALUE) / INNER_PEROID - 1; /* 1 is compensate */
329     /* CLK_TCLK_PREPARE */
330     mipi_tx_drv_get_phy_clk_prepare(&tp->clk_tclk_prepare);
331 
332     /* CLK_TCLK_ZERO */
333     if ((g_actual_phy_data_rate * TCLK_ZERO + ROUNDUP_VALUE) / INNER_PEROID > 4) {         /* 4 is compensate */
334         tp->clk_tclk_zero = (g_actual_phy_data_rate * TCLK_ZERO + ROUNDUP_VALUE) / INNER_PEROID - 4;
335     } else {
336         tp->clk_tclk_zero = 0;       /* 0 is minimum */
337     }
338 
339     /* CLK_TCLK_TRAIL */
340     tp->clk_tclk_trail = (g_actual_phy_data_rate * TCLK_TRAIL + ROUNDUP_VALUE) / INNER_PEROID;
341 
342     /* DATA_TLPX */
343     tp->data_tlpx = (g_actual_phy_data_rate * TLPX + ROUNDUP_VALUE) / INNER_PEROID - 1;    /* 1 is compensate */
344 
345     /* DATA_THS_PREPARE */
346     mipi_tx_drv_get_phy_data_prepare(&tp->data_ths_prepare);
347 
348     /* DATA_THS_ZERO */
349     if ((g_actual_phy_data_rate * THS_ZERO + ROUNDUP_VALUE) / INNER_PEROID > 4) {             /* 4 is compensate */
350         tp->data_ths_zero = (g_actual_phy_data_rate * THS_ZERO + ROUNDUP_VALUE) / INNER_PEROID - 4;
351     } else {
352         tp->data_ths_zero = 0;       /* 0 is minimum */
353     }
354 
355     /* DATA_THS_TRAIL */
356     tp->data_ths_trail = (g_actual_phy_data_rate * THS_TRAIL + ROUNDUP_VALUE) /
357                          INNER_PEROID + 1;   /* 1 is compensate */
358 }
359 
360 /* set global operation timing parameters. */
mipi_tx_drv_set_phy_timing_parameters(const mipi_tx_phy_timing_parameters * tp)361 static void mipi_tx_drv_set_phy_timing_parameters(const mipi_tx_phy_timing_parameters *tp)
362 {
363     unsigned char data_tpre_delay = tp->data_tpre_delay;
364     unsigned char clk_tlpx = tp->clk_tlpx;
365     unsigned char clk_tclk_prepare = tp->clk_tclk_prepare;
366     unsigned char clk_tclk_zero = tp->clk_tclk_zero;
367     unsigned char clk_tclk_trail = tp->clk_tclk_trail;
368     unsigned char data_tlpx = tp->data_tlpx;
369     unsigned char data_ths_prepare = tp->data_ths_prepare;
370     unsigned char data_ths_zero = tp->data_ths_zero;
371     unsigned char data_ths_trail = tp->data_ths_trail;
372 
373     /* DATA0~3 TPRE-DELAY */
374     set_phy_reg(DATA0_TPRE_DELAY, data_tpre_delay);
375     set_phy_reg(DATA1_TPRE_DELAY, data_tpre_delay);
376     set_phy_reg(DATA2_TPRE_DELAY, data_tpre_delay);
377     set_phy_reg(DATA3_TPRE_DELAY, data_tpre_delay);
378 
379     /* CLK_TLPX */
380     set_phy_reg(CLK_TLPX, clk_tlpx);
381 
382     /* CLK_TCLK_PREPARE */
383     set_phy_reg(CLK_TCLK_PREPARE, clk_tclk_prepare);
384 
385     /* CLK_TCLK_ZERO */
386     set_phy_reg(CLK_TCLK_ZERO, clk_tclk_zero);
387 
388     /* CLK_TCLK_TRAIL */
389     set_phy_reg(CLK_TCLK_TRAIL, clk_tclk_trail);
390 
391     /*
392      * DATA_TLPX
393      * DATA_THS_PREPARE
394      * DATA_THS_ZERO
395      * DATA_THS_TRAIL
396      */
397     set_phy_reg(DATA0_TLPX, data_tlpx);
398     set_phy_reg(DATA0_THS_PREPARE, data_ths_prepare);
399     set_phy_reg(DATA0_THS_ZERO, data_ths_zero);
400     set_phy_reg(DATA0_THS_TRAIL, data_ths_trail);
401     set_phy_reg(DATA1_TLPX, data_tlpx);
402     set_phy_reg(DATA1_THS_PREPARE, data_ths_prepare);
403     set_phy_reg(DATA1_THS_ZERO, data_ths_zero);
404     set_phy_reg(DATA1_THS_TRAIL, data_ths_trail);
405     set_phy_reg(DATA2_TLPX, data_tlpx);
406     set_phy_reg(DATA2_THS_PREPARE, data_ths_prepare);
407     set_phy_reg(DATA2_THS_ZERO, data_ths_zero);
408     set_phy_reg(DATA2_THS_TRAIL, data_ths_trail);
409     set_phy_reg(DATA3_TLPX, data_tlpx);
410     set_phy_reg(DATA3_THS_PREPARE, data_ths_prepare);
411     set_phy_reg(DATA3_THS_ZERO, data_ths_zero);
412     set_phy_reg(DATA3_THS_TRAIL, data_ths_trail);
413 
414 #ifdef MIPI_TX_DEBUG
415     osal_printk("\n==========phy timing parameters=======\n");
416     osal_printk("data_tpre_delay(0x30/40/50/60): 0x%x\n", data_tpre_delay);
417     osal_printk("clk_tlpx(0x22): 0x%x\n", clk_tlpx);
418     osal_printk("clk_tclk_prepare(0x23): 0x%x\n", clk_tclk_prepare);
419     osal_printk("clk_tclk_zero(0x24): 0x%x\n", clk_tclk_zero);
420     osal_printk("clk_tclk_trail(0x25): 0x%x\n", clk_tclk_trail);
421     osal_printk("data_tlpx(0x32/42/52/62): 0x%x\n", data_tlpx);
422     osal_printk("data_ths_prepare(0x33/43/53/63): 0x%x\n", data_ths_prepare);
423     osal_printk("data_ths_zero(0x34/44/54/64): 0x%x\n", data_ths_zero);
424     osal_printk("data_ths_trail(0x35/45/55/65): 0x%x\n", data_ths_trail);
425     osal_printk("=========================\n");
426 #endif
427 }
428 
429 /*
430  * set data lp2hs,hs2lp time
431  * set clk lp2hs,hs2lp time
432  * unit: hsclk
433  */
mipi_tx_drv_set_phy_hs_lp_switch_time(const mipi_tx_phy_timing_parameters * tp)434 static void mipi_tx_drv_set_phy_hs_lp_switch_time(const mipi_tx_phy_timing_parameters *tp)
435 {
436     unsigned char data_tpre_delay = tp->data_tpre_delay;
437     unsigned char clk_tlpx = tp->clk_tlpx;
438     unsigned char clk_tclk_prepare = tp->clk_tclk_prepare;
439     unsigned char clk_tclk_zero = tp->clk_tclk_zero;
440     unsigned char data_tlpx = tp->data_tlpx;
441     unsigned char data_ths_prepare = tp->data_ths_prepare;
442     unsigned char data_ths_zero = tp->data_ths_zero;
443     unsigned char data_ths_trail = tp->data_ths_trail;
444 
445     /* data lp2hs,hs2lp time */
446     g_mipi_tx_regs_va->PHY_TMR_CFG.u32 = ((data_ths_trail - 1) << 16) +  /* 16 set register */
447         data_tpre_delay + data_tlpx + data_ths_prepare + data_ths_zero + 7; /* 7 from algorithm */
448     /* clk lp2hs,hs2lp time */
449     g_mipi_tx_regs_va->PHY_TMR_LPCLK_CFG.u32 = ((31 + data_ths_trail) << 16) + /* 31 from algorithm, 16 set register */
450         clk_tlpx + clk_tclk_prepare + clk_tclk_zero + 6; /* 6 from algorithm */
451 
452 #ifdef MIPI_TX_DEBUG
453         osal_printk("PHY_TMR_CFG(0x9C): 0x%x\n", g_mipi_tx_regs_va->PHY_TMR_CFG.u32);
454         osal_printk("PHY_TMR_LPCLK_CFG(0x98): 0x%x\n", g_mipi_tx_regs_va->PHY_TMR_LPCLK_CFG.u32);
455 #endif
456 }
457 
mipi_tx_drv_set_phy_cfg(const combo_dev_cfg_t * dev_cfg)458 void mipi_tx_drv_set_phy_cfg(const combo_dev_cfg_t *dev_cfg)
459 {
460     mipi_tx_phy_timing_parameters tp = {0};
461 
462     /* set phy pll parameters setx */
463     mipi_tx_drv_set_phy_pll_setx(dev_cfg->phy_data_rate);
464 
465     /* get global operation timing parameters */
466     mipi_tx_drv_get_phy_timing_parameters(&tp);
467 
468     /* set global operation timing parameters */
469     mipi_tx_drv_set_phy_timing_parameters(&tp);
470 
471     /* set hs switch to lp and lp switch to hs time  */
472     mipi_tx_drv_set_phy_hs_lp_switch_time(&tp);
473 
474     /* edpi_cmd_size */
475     g_mipi_tx_regs_va->EDPI_CMD_SIZE.u32 = 0xF0;
476 
477     /* phy enable */
478     g_mipi_tx_regs_va->PHY_RSTZ.u32 = 0xf;
479 
480     if (dev_cfg->output_mode == OUTPUT_MODE_CSI) {
481         if (dev_cfg->output_format == OUT_FORMAT_YUV420_8_BIT_NORMAL) {
482             g_mipi_tx_regs_va->DATATYPE0.u32 = 0x10218;
483             g_mipi_tx_regs_va->CSI_CTRL.u32 = 0x1111;
484         } else if (dev_cfg->output_format == OUT_FORMAT_YUV422_8_BIT) {
485             g_mipi_tx_regs_va->DATATYPE0.u32 = 0x1021E;
486             g_mipi_tx_regs_va->CSI_CTRL.u32 = 0x1111;
487         }
488     } else {
489         if (dev_cfg->output_format == OUT_FORMAT_RGB_16_BIT) {
490             g_mipi_tx_regs_va->DATATYPE0.u32 = 0x111213D;
491             g_mipi_tx_regs_va->CSI_CTRL.u32 = 0x10100;
492         } else if (dev_cfg->output_format == OUT_FORMAT_RGB_18_BIT) {
493             g_mipi_tx_regs_va->DATATYPE0.u32 = 0x111213D;
494             g_mipi_tx_regs_va->CSI_CTRL.u32 = 0x10100;
495         } else if (dev_cfg->output_format == OUT_FORMAT_RGB_24_BIT) {
496             g_mipi_tx_regs_va->DATATYPE0.u32 = 0x111213D;
497             g_mipi_tx_regs_va->CSI_CTRL.u32 = 0x10100;
498         }
499     }
500 
501     g_mipi_tx_regs_va->PHY_RSTZ.u32 = 0XF;
502 
503     osal_msleep(1);
504 
505     g_mipi_tx_regs_va->LPCLK_CTRL.u32 = 0x0;
506 }
507 
mipi_tx_drv_get_dev_status(mipi_tx_dev_phy_t * mipi_tx_phy_ctx)508 void mipi_tx_drv_get_dev_status(mipi_tx_dev_phy_t *mipi_tx_phy_ctx)
509 {
510     mipi_tx_phy_ctx->hact_det = g_mipi_tx_regs_va->HORI0_DET.bits.hact_det;
511     mipi_tx_phy_ctx->hall_det = g_mipi_tx_regs_va->HORI0_DET.bits.hline_det;
512     mipi_tx_phy_ctx->hbp_det  = g_mipi_tx_regs_va->HORI1_DET.bits.hbp_det;
513     mipi_tx_phy_ctx->hsa_det  = g_mipi_tx_regs_va->HORI1_DET.bits.hsa_det;
514 
515     mipi_tx_phy_ctx->vact_det = g_mipi_tx_regs_va->VERT_DET.bits.vact_det;
516     mipi_tx_phy_ctx->vall_det = g_mipi_tx_regs_va->VERT_DET.bits.vall_det;
517     mipi_tx_phy_ctx->vsa_det  = g_mipi_tx_regs_va->VSA_DET.bits.vsa_det;
518 }
519 
set_output_format(const combo_dev_cfg_t * dev_cfg)520 static void set_output_format(const combo_dev_cfg_t *dev_cfg)
521 {
522     int color_coding = 0;
523 
524     if (dev_cfg->output_mode == OUTPUT_MODE_CSI) {
525         if (dev_cfg->output_format == OUT_FORMAT_YUV420_8_BIT_NORMAL) {
526             color_coding = 0xd;
527         } else if (dev_cfg->output_format == OUT_FORMAT_YUV422_8_BIT) {
528             color_coding = 0x1;
529         }
530     } else {
531         if (dev_cfg->output_format == OUT_FORMAT_RGB_16_BIT) {
532             color_coding = 0x0;
533         } else if (dev_cfg->output_format == OUT_FORMAT_RGB_18_BIT) {
534             color_coding = 0x3;
535         } else if (dev_cfg->output_format == OUT_FORMAT_RGB_24_BIT) {
536             color_coding = 0x5;
537         }
538     }
539 
540     g_mipi_tx_regs_va->COLOR_CODING.u32 = color_coding;
541 #ifdef MIPI_TX_DEBUG
542     osal_printk("set_output_format: 0x%x\n", color_coding);
543 #endif
544 }
545 
set_video_mode_cfg(const combo_dev_cfg_t * dev_cfg)546 static void set_video_mode_cfg(const combo_dev_cfg_t *dev_cfg)
547 {
548     int video_mode;
549 
550     if (dev_cfg->video_mode == NON_BURST_MODE_SYNC_PULSES) {
551         video_mode = 0;
552     } else if (dev_cfg->video_mode == NON_BURST_MODE_SYNC_EVENTS) {
553         video_mode = 1;
554     } else {
555         video_mode = 2; /* 2 register value */
556     }
557 
558     if ((dev_cfg->output_mode == OUTPUT_MODE_CSI) || (dev_cfg->output_mode == OUTPUT_MODE_DSI_CMD)) {
559         video_mode = 2; /* 2 register value */
560     }
561 
562     g_mipi_tx_regs_va->VID_MODE_CFG.u32 = 0x3f00 + video_mode;
563 }
564 
set_timing_config(const combo_dev_cfg_t * dev_cfg)565 static void set_timing_config(const combo_dev_cfg_t *dev_cfg)
566 {
567     unsigned int hsa_time;
568     unsigned int hbp_time;
569     unsigned int hline_time;
570 
571     if (dev_cfg->pixel_clk == 0) {
572         osal_printk("dev_cfg->pixel_clk is 0, illegal.\n");
573         return;
574     }
575 
576     hsa_time = g_actual_phy_data_rate * dev_cfg->sync_info.vid_hsa_pixels * 125 / /* 125 from algorithm */
577                dev_cfg->pixel_clk;
578     hbp_time = g_actual_phy_data_rate * dev_cfg->sync_info.vid_hbp_pixels * 125 / /* 125 from algorithm */
579                dev_cfg->pixel_clk;
580     hline_time = g_actual_phy_data_rate * dev_cfg->sync_info.vid_hline_pixels * 125 / /* 125 from algorithm */
581                  dev_cfg->pixel_clk;
582 
583     g_mipi_tx_regs_va->VID_HSA_TIME.u32 = hsa_time;
584     g_mipi_tx_regs_va->VID_HBP_TIME.u32 = hbp_time;
585     g_mipi_tx_regs_va->VID_HLINE_TIME.u32 = hline_time;
586 
587     g_mipi_tx_regs_va->VID_VSA_LINES.u32 = dev_cfg->sync_info.vid_vsa_lines;
588     g_mipi_tx_regs_va->VID_VBP_LINES.u32 = dev_cfg->sync_info.vid_vbp_lines;
589     g_mipi_tx_regs_va->VID_VFP_LINES.u32 = dev_cfg->sync_info.vid_vfp_lines;
590     g_mipi_tx_regs_va->VID_VACTIVE_LINES.u32 = dev_cfg->sync_info.vid_active_lines;
591 
592 #ifdef MIPI_TX_DEBUG
593     osal_printk("VID_HSA_TIME(0x48): 0x%x\n", hsa_time);
594     osal_printk("VID_HBP_TIME(0x4c): 0x%x\n", hbp_time);
595     osal_printk("VID_HLINE_TIME(0x50): 0x%x\n", hline_time);
596     osal_printk("VID_VSA_LINES(0x54): 0x%x\n", dev_cfg->sync_info.vid_vsa_lines);
597     osal_printk("VID_VBP_LINES(0x58): 0x%x\n", dev_cfg->sync_info.vid_vbp_lines);
598     osal_printk("VID_VFP_LINES(0x5c): 0x%x\n", dev_cfg->sync_info.vid_vfp_lines);
599     osal_printk("VID_VACTIVE_LINES(0x60): 0x%x\n", dev_cfg->sync_info.vid_active_lines);
600 #endif
601 }
602 
set_lane_config(const short lane_id[])603 void set_lane_config(const short lane_id[])
604 {
605     int lane_num = 0;
606     int i;
607 
608     for (i = 0; i < LANE_MAX_NUM; i++) {
609         if (-1 != lane_id[i]) {
610             lane_num++;
611         }
612     }
613 
614     g_mipi_tx_regs_va->PHY_IF_CFG.u32 = lane_num - 1;
615 }
616 
mipi_tx_drv_set_clkmgr_cfg(void)617 void mipi_tx_drv_set_clkmgr_cfg(void)
618 {
619     if (g_actual_phy_data_rate / 160 < 2) { /* 160 cal div, should not smaller than 2 */
620         g_mipi_tx_regs_va->CLKMGR_CFG.u32 = 0x102;
621     } else {
622         g_mipi_tx_regs_va->CLKMGR_CFG.u32 = 0x100 + (g_actual_phy_data_rate + 159) / 160; /* 159 160 cal div */
623     }
624 }
625 
mipi_tx_drv_set_controller_cfg(const combo_dev_cfg_t * dev_cfg)626 void mipi_tx_drv_set_controller_cfg(const combo_dev_cfg_t *dev_cfg)
627 {
628     if (dev_cfg == NULL) {
629         hi_mipi_tx_err("para check failed \n");
630         return;
631     }
632     /* disable input */
633     g_mipi_tx_regs_va->OPERATION_MODE.u32 = 0x0;
634 
635     /* vc_id */
636     g_mipi_tx_regs_va->VCID.u32 = 0x0;
637 
638     /* output format,color coding */
639     set_output_format(dev_cfg);
640 
641     /* txescclk,timeout */
642     g_actual_phy_data_rate = ((dev_cfg->phy_data_rate + MIPI_TX_REF_CLK - 1) / MIPI_TX_REF_CLK) * MIPI_TX_REF_CLK;
643     mipi_tx_drv_set_clkmgr_cfg();
644 
645     /* cmd transmission mode */
646     g_mipi_tx_regs_va->CMD_MODE_CFG.u32 = 0xffffff00;
647 
648     /* crc,ecc,eotp tran */
649     g_mipi_tx_regs_va->PCKHDL_CFG.u32 = 0x1c;
650     /* gen_vcid_rx */
651     g_mipi_tx_regs_va->GEN_VCID.u32 = 0x0;
652 
653     /* mode config */
654     g_mipi_tx_regs_va->MODE_CFG.u32 = 0x1;
655 
656     /* video mode cfg */
657     set_video_mode_cfg(dev_cfg);
658     if ((dev_cfg->output_mode == OUTPUT_MODE_DSI_VIDEO) || (dev_cfg->output_mode == OUTPUT_MODE_CSI)) {
659         g_mipi_tx_regs_va->VID_PKT_SIZE.u32 = dev_cfg->sync_info.vid_pkt_size;
660     } else {
661         g_mipi_tx_regs_va->EDPI_CMD_SIZE.u32 = dev_cfg->sync_info.edpi_cmd_size;
662     }
663 
664     /* num_chunks/null_size */
665     g_mipi_tx_regs_va->VID_NUM_CHUNKS.u32 = 0x0;
666     g_mipi_tx_regs_va->VID_NULL_SIZE.u32 = 0x0;
667 
668     /* timing config */
669     set_timing_config(dev_cfg);
670 
671     /* invact,outvact time */
672     g_mipi_tx_regs_va->LP_CMD_TIM.u32 = 0x0;
673 
674     g_mipi_tx_regs_va->PHY_TMR_CFG.u32 = 0x9002D;
675 
676     g_mipi_tx_regs_va->PHY_TMR_LPCLK_CFG.u32 = 0x29002E;
677 
678     g_mipi_tx_regs_va->EDPI_CMD_SIZE.u32 = 0xF0;
679 
680     /* lp_wr_to_cnt */
681     g_mipi_tx_regs_va->LP_WR_TO_CNT.u32 = 0x0;
682     /* bta_to_cnt */
683     g_mipi_tx_regs_va->BTA_TO_CNT.u32 = 0x0;
684 
685     /* lanes */
686     set_lane_config(dev_cfg->lane_id);
687 
688     /* phy_tx requlpsclk */
689     g_mipi_tx_regs_va->PHY_ULPS_CTRL.u32 = 0x0;
690 
691     /* int msk0 */
692     g_mipi_tx_regs_va->INT_MSK0.u32 = 0x0;
693 
694     /* pwr_up unreset */
695     g_mipi_tx_regs_va->PWR_UP.u32 = 0x0;
696     g_mipi_tx_regs_va->PWR_UP.u32 = 0xf;
697 }
698 
mipi_tx_wait_cmd_fifo_empty(void)699 static int mipi_tx_wait_cmd_fifo_empty(void)
700 {
701     U_CMD_PKT_STATUS cmd_pkt_status;
702     unsigned int wait_count;
703 
704     wait_count = 0;
705     do {
706         cmd_pkt_status.u32 = g_mipi_tx_regs_va->CMD_PKT_STATUS.u32;
707 
708         wait_count++;
709 
710         osal_udelay(1);
711 
712         if (wait_count >  MIPI_TX_READ_TIMEOUT_CNT) {
713             hi_mipi_tx_err("timeout when send cmd buffer \n");
714             return -1;
715         }
716     } while (cmd_pkt_status.bits.gen_cmd_empty == 0);
717 
718     return 0;
719 }
720 
mipi_tx_wait_write_fifo_empty(void)721 static int mipi_tx_wait_write_fifo_empty(void)
722 {
723     U_CMD_PKT_STATUS cmd_pkt_status;
724     unsigned int wait_count;
725 
726     wait_count = 0;
727     do {
728         cmd_pkt_status.u32 = g_mipi_tx_regs_va->CMD_PKT_STATUS.u32;
729 
730         wait_count++;
731 
732         osal_udelay(1);
733 
734         if (wait_count >  MIPI_TX_READ_TIMEOUT_CNT) {
735             hi_mipi_tx_err("timeout when send data buffer \n");
736             return -1;
737         }
738     } while (cmd_pkt_status.bits.gen_pld_w_empty == 0);
739 
740     return 0;
741 }
742 
mipi_tx_wait_write_fifo_not_full(void)743 static int mipi_tx_wait_write_fifo_not_full(void)
744 {
745     U_CMD_PKT_STATUS cmd_pkt_status;
746     unsigned int wait_count;
747 
748     wait_count = 0;
749     do {
750         cmd_pkt_status.u32 = g_mipi_tx_regs_va->CMD_PKT_STATUS.u32;
751         if (wait_count > 0) {
752             osal_udelay(1);
753             hi_mipi_tx_err("write fifo full happened wait count = %d\n", wait_count);
754         }
755         if (wait_count >  MIPI_TX_READ_TIMEOUT_CNT) {
756             hi_mipi_tx_err("timeout when wait write fifo not full buffer \n");
757             return -1;
758         }
759         wait_count++;
760     } while (cmd_pkt_status.bits.gen_pld_w_full == 1);
761 
762     return 0;
763 }
764 
765 /*
766  * set payloads data by writing register
767  * each 4 bytes in cmd corresponds to one register
768  */
mipi_tx_drv_set_payload_data(const unsigned char * cmd,unsigned short cmd_size)769 static void mipi_tx_drv_set_payload_data(const unsigned char *cmd, unsigned short cmd_size)
770 {
771     U_GEN_PLD_DATA gen_pld_data;
772     int i, j;
773 
774     gen_pld_data.u32 = g_mipi_tx_regs_va->GEN_PLD_DATA.u32;
775 
776     for (i = 0; i < (cmd_size / 4); i++) { /* 4 cmd once */
777         gen_pld_data.bits.gen_pld_b1 = cmd[i * 4]; /* 0 in 4 */
778         gen_pld_data.bits.gen_pld_b2 = cmd[i * 4 + 1]; /* 1 in 4 */
779         gen_pld_data.bits.gen_pld_b3 = cmd[i * 4 + 2]; /* 2 in 4 */
780         gen_pld_data.bits.gen_pld_b4 = cmd[i * 4 + 3]; /* 3 in 4 */
781 
782         mipi_tx_wait_write_fifo_not_full();
783         g_mipi_tx_regs_va->GEN_PLD_DATA.u32 = gen_pld_data.u32;
784     }
785 
786     j = cmd_size % 4; /* remainder of 4 */
787     if (j != 0) {
788         if (j > 0) {
789             gen_pld_data.bits.gen_pld_b1 = cmd[i * 4]; /* 0 in 4 */
790         }
791         if (j > 1) {
792             gen_pld_data.bits.gen_pld_b2 = cmd[i * 4 + 1]; /* 1 in 4 */
793         }
794         if (j > 2) { /* bigger than 2 */
795             gen_pld_data.bits.gen_pld_b3 = cmd[i * 4 + 2]; /* 2 in 4 */
796         }
797 
798         mipi_tx_wait_write_fifo_not_full();
799         g_mipi_tx_regs_va->GEN_PLD_DATA.u32 = gen_pld_data.u32;
800     }
801 
802 #ifdef MIPI_TX_DEBUG
803         osal_printk("\n=====set cmd=======\n");
804         osal_printk("GEN_PLD_DATA(0x70): 0x%x\n", gen_pld_data);
805 #endif
806 
807     return;
808 }
809 
mipi_tx_drv_set_cmd_info(const cmd_info_t * cmd_info)810 int mipi_tx_drv_set_cmd_info(const cmd_info_t *cmd_info)
811 {
812     U_GEN_HDR gen_hdr;
813     unsigned char *cmd = NULL;
814 
815     gen_hdr.u32 = g_mipi_tx_regs_va->GEN_HDR.u32;
816 
817     if (cmd_info->cmd != NULL) {
818         if (cmd_info->cmd_size > 200 || cmd_info->cmd_size == 0) { /* 200 is max cmd size */
819             hi_mipi_tx_err("set cmd size illegal, size =%d\n", cmd_info->cmd_size);
820             return  -1;
821         }
822 
823         cmd = (unsigned char *)osal_kmalloc(cmd_info->cmd_size, osal_gfp_kernel);
824         if (cmd == NULL) {
825             hi_mipi_tx_err("kmalloc fail,please check,need %d bytes\n", cmd_info->cmd_size);
826             return  -1;
827         }
828 
829         if (osal_copy_from_user(cmd, cmd_info->cmd, cmd_info->cmd_size)) {
830             osal_kfree(cmd);
831             cmd = NULL;
832             return  -1;
833         }
834 
835         mipi_tx_drv_set_payload_data(cmd, cmd_info->cmd_size);
836 
837         osal_kfree(cmd);
838         cmd = NULL;
839     }
840 
841     gen_hdr.bits.gen_dt = cmd_info->data_type;
842     gen_hdr.bits.gen_wc_lsbyte = cmd_info->cmd_size & 0xff;
843     gen_hdr.bits.gen_wc_msbyte = (cmd_info->cmd_size & 0xff00) >> 8; /* height 8 bits */
844     g_mipi_tx_regs_va->GEN_HDR.u32 = gen_hdr.u32;
845 
846     osal_udelay(350);  /* wait 350 us transfer end */
847 
848     mipi_tx_wait_cmd_fifo_empty();
849     mipi_tx_wait_write_fifo_empty();
850 
851 #ifdef MIPI_TX_DEBUG
852     osal_printk("\n=====set cmd=======\n");
853     osal_printk("cmd_info->cmd_size: 0x%x\n", cmd_info->cmd_size);
854     osal_printk("cmd_info->data_type: 0x%x\n", cmd_info->data_type);
855     osal_printk("GEN_HDR(0x6C): 0x%x\n", gen_hdr);
856 #endif
857 
858     return 0;
859 }
860 
mipi_tx_wait_read_fifo_not_empty(void)861 static int mipi_tx_wait_read_fifo_not_empty(void)
862 {
863     U_INT_ST0 int_st0;
864     U_INT_ST1 int_st1;
865     unsigned int wait_count;
866     U_CMD_PKT_STATUS cmd_pkt_status;
867 
868     wait_count = 0;
869     do {
870         int_st1.u32 =  g_mipi_tx_regs_va->INT_ST1.u32;
871         int_st0.u32 =  g_mipi_tx_regs_va->INT_ST0.u32;
872 
873         if ((int_st1.u32 & 0x3e) != 0) {
874             hi_mipi_tx_err("err happened when read data, int_st1 = 0x%x,int_st0 = %x\n", int_st1.u32, int_st0.u32);
875             return -1;
876         }
877 
878         if (wait_count >  MIPI_TX_READ_TIMEOUT_CNT) {
879             hi_mipi_tx_err("timeout when read data\n");
880             return -1;
881         }
882 
883         wait_count++;
884 
885         osal_udelay(1);
886 
887         cmd_pkt_status.u32 = g_mipi_tx_regs_va->CMD_PKT_STATUS.u32;
888     } while (cmd_pkt_status.bits.gen_pld_r_empty == 0x1);
889 
890     return 0;
891 }
892 
mipi_tx_wait_read_fifo_empty(void)893 static int mipi_tx_wait_read_fifo_empty(void)
894 {
895     U_GEN_PLD_DATA pld_data;
896     U_INT_ST1 int_st1;
897     unsigned int wait_count;
898 
899     wait_count = 0;
900     do {
901         int_st1.u32 = g_mipi_tx_regs_va->INT_ST1.u32;
902         if ((int_st1.bits.gen_pld_rd_err) == 0x0) {
903             pld_data.u32 = g_mipi_tx_regs_va->GEN_PLD_DATA.u32;
904         }
905         wait_count++;
906         osal_udelay(1);
907         if (wait_count >  MIPI_TX_READ_TIMEOUT_CNT) {
908             hi_mipi_tx_err("timeout when clear data buffer, the last read data is 0x%x \n", pld_data.u32);
909             return -1;
910         }
911     } while ((int_st1.bits.gen_pld_rd_err) == 0x0);
912 
913     return 0;
914 }
915 
mipi_tx_send_short_packet(unsigned char virtual_channel,short unsigned data_type,unsigned short data_param)916 static int mipi_tx_send_short_packet(unsigned char virtual_channel,
917     short unsigned data_type, unsigned short  data_param)
918 {
919     U_GEN_HDR gen_hdr;
920 
921     gen_hdr.bits.gen_vc = virtual_channel;
922     gen_hdr.bits.gen_dt = data_type;
923     gen_hdr.bits.gen_wc_lsbyte = (data_param & 0xff);
924     gen_hdr.bits.gen_wc_msbyte = (data_param & 0xff00) >> 8; /* height 8 bits */
925     g_mipi_tx_regs_va->GEN_HDR.u32 = gen_hdr.u32;
926 
927     if (mipi_tx_wait_cmd_fifo_empty() != 0) {
928         return -1;
929     }
930 
931     return 0;
932 }
933 
mipi_tx_get_read_fifo_data(unsigned int get_data_size,unsigned char * data_buf)934 static int mipi_tx_get_read_fifo_data(unsigned int get_data_size, unsigned char *data_buf)
935 {
936     U_GEN_PLD_DATA pld_data;
937     unsigned int i, j;
938 
939     for (i = 0; i < get_data_size / 4; i++) {   /* 4byte once */
940         if (mipi_tx_wait_read_fifo_not_empty() != 0) {
941             return -1;
942         }
943         pld_data.u32 = g_mipi_tx_regs_va->GEN_PLD_DATA.u32;
944         data_buf[i * 4] = pld_data.bits.gen_pld_b1;     /* 0 in 4 */
945         data_buf[i * 4 + 1] = pld_data.bits.gen_pld_b2; /* 1 in 4 */
946         data_buf[i * 4 + 2] = pld_data.bits.gen_pld_b3; /* 2 in 4 */
947         data_buf[i * 4 + 3] = pld_data.bits.gen_pld_b4; /* 3 in 4 */
948     }
949 
950     j = get_data_size % 4; /* remainder of 4 */
951 
952     if (j != 0) {
953         if (mipi_tx_wait_read_fifo_not_empty() != 0) {
954             return -1;
955         }
956         pld_data.u32 = g_mipi_tx_regs_va->GEN_PLD_DATA.u32;
957         if (j > 0) {
958             data_buf[i * 4] = pld_data.bits.gen_pld_b1; /* 0 in 4 */
959         }
960         if (j > 1) {
961             data_buf[i * 4 + 1] = pld_data.bits.gen_pld_b2; /* 1 in 4 */
962         }
963         if (j > 2) { /* bigger than 2 */
964             data_buf[i * 4 + 2] = pld_data.bits.gen_pld_b3; /* 2 in 4 */
965         }
966     }
967 
968     return 0;
969 }
970 
mipi_tx_reset(void)971 void mipi_tx_reset(void)
972 {
973     g_mipi_tx_regs_va->PWR_UP.u32 = 0x0;
974     g_mipi_tx_regs_va->PHY_RSTZ.u32 = 0xd;
975     osal_udelay(1);
976     g_mipi_tx_regs_va->PWR_UP.u32 = 0x1;
977     g_mipi_tx_regs_va->PHY_RSTZ.u32 = 0xf;
978     osal_udelay(1);
979     return;
980 }
981 
mipi_tx_drv_get_cmd_info(get_cmd_info_t * get_cmd_info)982 int mipi_tx_drv_get_cmd_info(get_cmd_info_t *get_cmd_info)
983 {
984     unsigned char* data_buf = NULL;
985 
986     data_buf = (unsigned char*)osal_kmalloc(get_cmd_info->get_data_size, osal_gfp_kernel);
987     if (data_buf == NULL) {
988         return -1;
989     }
990 
991     if (mipi_tx_wait_read_fifo_empty() != 0) {
992         goto fail0;
993     }
994 
995     if (mipi_tx_send_short_packet(0, get_cmd_info->data_type, get_cmd_info->data_param) != 0) {
996         goto fail0;
997     }
998 
999     if (mipi_tx_get_read_fifo_data(get_cmd_info->get_data_size, data_buf) != 0) {
1000         /* fail will block mipi data lane ,so need reset  */
1001         mipi_tx_reset();
1002         goto fail0;
1003     }
1004 
1005     osal_copy_to_user(get_cmd_info->get_data, data_buf, get_cmd_info->get_data_size);
1006 
1007     osal_kfree(data_buf);
1008     data_buf = NULL;
1009 
1010     return 0;
1011 
1012 fail0:
1013     osal_kfree(data_buf);
1014     data_buf = NULL;
1015     return -1;
1016 }
1017 
mipi_tx_drv_enable_input(const output_mode_t output_mode)1018 void mipi_tx_drv_enable_input(const output_mode_t output_mode)
1019 {
1020     if ((output_mode == OUTPUT_MODE_DSI_VIDEO) || (output_mode == OUTPUT_MODE_CSI)) {
1021         g_mipi_tx_regs_va->MODE_CFG.u32 = 0x0;
1022     }
1023 
1024     if (output_mode == OUTPUT_MODE_DSI_CMD) {
1025         g_mipi_tx_regs_va->CMD_MODE_CFG.u32 = 0x0;
1026     }
1027 
1028     /* enable input */
1029     g_mipi_tx_regs_va->OPERATION_MODE.u32 = 0x80150000;
1030 
1031     g_mipi_tx_regs_va->LPCLK_CTRL.u32 = 0x1;
1032 
1033     mipi_tx_reset();
1034 }
1035 
mipi_tx_drv_disable_input(void)1036 void mipi_tx_drv_disable_input(void)
1037 {
1038     /* disable input */
1039     g_mipi_tx_regs_va->OPERATION_MODE.u32 = 0x0;
1040 
1041     g_mipi_tx_regs_va->CMD_MODE_CFG.u32 = 0xffffff00;
1042 
1043     /* command mode */
1044     g_mipi_tx_regs_va->MODE_CFG.u32 = 0x1;
1045 
1046     g_mipi_tx_regs_va->LPCLK_CTRL.u32 = 0x0;
1047 
1048     mipi_tx_reset();
1049 }
1050 
mipi_tx_drv_reg_init(void)1051 static int mipi_tx_drv_reg_init(void)
1052 {
1053     if (g_mipi_tx_regs_va == NULL) {
1054         g_mipi_tx_regs_va = (mipi_tx_regs_type_t *)osal_ioremap(MIPI_TX_REGS_ADDR, (unsigned int)MIPI_TX_REGS_SIZE);
1055         if (g_mipi_tx_regs_va == NULL) {
1056             hi_mipi_tx_err("remap mipi_tx reg addr fail\n");
1057             return -1;
1058         }
1059         g_reg_map_flag = 1;
1060     }
1061 
1062     return 0;
1063 }
1064 
mipi_tx_drv_reg_exit(void)1065 static void mipi_tx_drv_reg_exit(void)
1066 {
1067     if (g_reg_map_flag == 1) {
1068         if (g_mipi_tx_regs_va != NULL) {
1069             osal_iounmap((void *)g_mipi_tx_regs_va, (unsigned int)MIPI_TX_REGS_SIZE);
1070             g_mipi_tx_regs_va = NULL;
1071         }
1072         g_reg_map_flag = 0;
1073     }
1074 }
1075 
mipi_tx_drv_hw_init(int smooth)1076 static void mipi_tx_drv_hw_init(int smooth)
1077 {
1078     unsigned long mipi_tx_crg_addr;
1079 
1080     mipi_tx_crg_addr = (unsigned long)osal_ioremap(MIPI_TX_CRG, (unsigned long)0x4);
1081 
1082     /* mipi_tx gate clk enable */
1083     write_reg32(mipi_tx_crg_addr, 1, 0x1);
1084 
1085     /* reset */
1086     if (smooth == FALSE) {
1087         write_reg32(mipi_tx_crg_addr, 1 << 1, 0x1 << 1);
1088     }
1089 
1090     /* unreset */
1091     write_reg32(mipi_tx_crg_addr, 0 << 1, 0x1 << 1);
1092 
1093     /* ref clk */
1094     write_reg32(mipi_tx_crg_addr, 1 << 2, 0x1 << 2); /* 2 clk bit */
1095 
1096     osal_iounmap((void *)mipi_tx_crg_addr, (unsigned long)0x4);
1097 }
1098 
mipi_tx_drv_init(int smooth)1099 int mipi_tx_drv_init(int smooth)
1100 {
1101     int ret;
1102 
1103     ret = mipi_tx_drv_reg_init();
1104     if (ret < 0) {
1105         hi_mipi_tx_err("mipi_tx_drv_reg_init fail!\n");
1106         goto fail0;
1107     }
1108 
1109     mipi_tx_drv_hw_init(smooth);
1110 
1111     return 0;
1112 
1113 fail0:
1114     return -1;
1115 }
1116 
mipi_tx_drv_exit(void)1117 void mipi_tx_drv_exit(void)
1118 {
1119     mipi_tx_drv_reg_exit();
1120 }
1121 
1122 #ifdef __cplusplus
1123 #if __cplusplus
1124 }
1125 
1126 #endif
1127 #endif /* End of #ifdef __cplusplus */
1128