tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / autotst / mipi_dsih_api.c
1 #include "mipi_dsih_api.h"\r
2 #include "mipi_dsih_hal.h"\r
3 #include "mipi_dsih_dphy.h"\r
4 #include <linux/delay.h>\r
5 \r
6 /* whether to get debug messages (1) or not (0) */\r
7 #define DEBUG                                   0\r
8 \r
9 #define PRECISION_FACTOR                1000\r
10 #define VIDEO_PACKET_OVERHEAD   6\r
11 #define NULL_PACKET_OVERHEAD    6\r
12 #define SHORT_PACKET                    4\r
13 #define BLANKING_PACKET         6\r
14 /** Version supported by this driver */\r
15 static const uint32_t mipi_dsih_supported_versions[] = {0x3132302A, 0x3132312A};\r
16 static const uint32_t mipi_dsih_no_of_versions = sizeof(mipi_dsih_supported_versions) / sizeof(uint32_t);\r
17 \r
18 /**\r
19  * Open controller instance\r
20  * - Check if driver is compatible with core version\r
21  * - Check if instance context data structure is not NULL\r
22  * - Bring up PHY for any transmissions in low power\r
23  *      + Includes programming PLL to DEFAULT_BYTE_CLOCK\r
24  * - Bring up controller and perform initial configuration\r
25  *      + Includes start all commands transmision in LP\r
26  *      + Controller will not turn the bus around after commands\r
27  *      + program counters\r
28  * @param instance pointer to structure holding the DSI Host core information\r
29  * @return dsih_error_t\r
30  * @note this function must be called before any other function in this API\r
31  */\r
32 dsih_error_t mipi_dsih_open(dsih_ctrl_t * instance)\r
33 {\r
34         dsih_error_t err = OK;\r
35         uint32_t version = 0;\r
36         int i = 0;\r
37 \r
38         if (instance == 0)\r
39         {\r
40                 return ERR_DSI_INVALID_INSTANCE;\r
41         }\r
42         else if ((instance->core_read_function == 0) || (instance->core_write_function == 0))\r
43         {\r
44                 return ERR_DSI_INVALID_IO;\r
45         }\r
46         else if (instance->status == INITIALIZED)\r
47         {\r
48                 return ERR_DSI_INVALID_INSTANCE;\r
49         }\r
50         else if (mipi_dsih_dphy_open(&(instance->phy_instance)))\r
51         {\r
52                 return ERR_DSI_PHY_INVALID;\r
53         }\r
54         else\r
55         {\r
56                 instance->status = NOT_INITIALIZED;\r
57                 version = mipi_dsih_hal_get_version(instance);\r
58                 for (i = 0; i < mipi_dsih_no_of_versions; i++)\r
59                 {\r
60                         if (version == mipi_dsih_supported_versions[i])\r
61                         {\r
62                                 break;\r
63                         }\r
64                 }\r
65                 /* no matching supported version has been found*/\r
66                 if (i >= mipi_dsih_no_of_versions)\r
67                 {\r
68                         if (instance->log_info != 0)\r
69                         {\r
70                                 instance->log_info("sprdfb: driver does not support this core version 0x%lX", version);\r
71                         }\r
72                         return ERR_DSI_CORE_INCOMPATIBLE;\r
73                 }\r
74         }\r
75         mipi_dsih_hal_power(instance, 0);\r
76     //mipi_dsih_hal_power(instance, 0);//Jessica\r
77     //mipi_dsih_hal_power(instance, 1);//Jessica\r
78         mipi_dsih_hal_dpi_color_mode_pol(instance, !instance->color_mode_polarity);\r
79         mipi_dsih_hal_dpi_shut_down_pol(instance, !instance->shut_down_polarity);\r
80     //err = mipi_dsih_phy_hs2lp_config(instance, instance->max_hs_to_lp_cycles);\r
81     //err |=  mipi_dsih_phy_lp2hs_config(instance, instance->max_lp_to_hs_cycles);\r
82         mipi_dsih_hal_int_mask_0(instance, 0xffffff);\r
83         mipi_dsih_hal_int_mask_1(instance, 0xffffff);\r
84         err = mipi_dsih_phy_bta_time(instance, instance->max_bta_cycles);\r
85         if (err)\r
86         {\r
87                 return ERR_DSI_OVERFLOW;\r
88         }\r
89         /* by default, return to LP during ALL, unless otherwise specified*/\r
90         mipi_dsih_hal_dpi_lp_during_hfp(instance, 1);\r
91         mipi_dsih_hal_dpi_lp_during_hbp(instance, 1);\r
92         mipi_dsih_hal_dpi_lp_during_vactive(instance, 1);\r
93         mipi_dsih_hal_dpi_lp_during_vfp(instance, 1);\r
94         mipi_dsih_hal_dpi_lp_during_vbp(instance, 1);\r
95         mipi_dsih_hal_dpi_lp_during_vsync(instance, 1);\r
96         /* by default, all commands are sent in LP */\r
97         mipi_dsih_hal_dcs_wr_tx_type(instance, 0, 1);\r
98         mipi_dsih_hal_dcs_wr_tx_type(instance, 1, 1);\r
99         mipi_dsih_hal_dcs_wr_tx_type(instance, 3, 1); /* long packet*/\r
100         mipi_dsih_hal_dcs_rd_tx_type(instance, 0, 1);\r
101     /*Jessica add to support max rd packet size command*/\r
102     mipi_dsih_hal_max_rd_packet_size_type(instance, 1);\r
103         mipi_dsih_hal_gen_wr_tx_type(instance, 0, 1);\r
104         mipi_dsih_hal_gen_wr_tx_type(instance, 1, 1);\r
105         mipi_dsih_hal_gen_wr_tx_type(instance, 2, 1);\r
106         mipi_dsih_hal_gen_wr_tx_type(instance, 3, 1); /* long packet*/\r
107         mipi_dsih_hal_gen_rd_tx_type(instance, 0, 1);\r
108         mipi_dsih_hal_gen_rd_tx_type(instance, 1, 1);\r
109         mipi_dsih_hal_gen_rd_tx_type(instance, 2, 1);\r
110         /* by default, RX_VC = 0, NO EOTp, EOTn, BTA, ECC rx and CRC rx */\r
111         mipi_dsih_hal_gen_rd_vc(instance, 0);\r
112         mipi_dsih_hal_gen_eotp_rx_en(instance, 0);\r
113         mipi_dsih_hal_gen_eotp_tx_en(instance, 0);\r
114         mipi_dsih_hal_bta_en(instance, 0);\r
115         mipi_dsih_hal_gen_ecc_rx_en(instance, 0);\r
116         mipi_dsih_hal_gen_crc_rx_en(instance, 0);\r
117     //mipi_dsih_hal_power(instance, 0);//Jessica\r
118     mipi_dsih_hal_power(instance, 1);//Jessica\r
119 \r
120     /* dividing by 6 is aimed for max PHY frequency, 1GHz */\r
121     mipi_dsih_hal_tx_escape_division(instance, 4); //6    //Jessica\r
122     instance->status = INITIALIZED;\r
123     /* initialize pll so escape clocks could be generated at 864MHz, 1 lane */\r
124     /* however the high speed clock will not be requested */\r
125     //err = mipi_dsih_dphy_configure(&(instance->phy_instance), 1, DEFAULT_BYTE_CLOCK);\r
126     return err;\r
127 }\r
128 /**\r
129  * Close DSI Host driver\r
130  * - Free up resources and shutdown host controller and PHY\r
131  * @param instance pointer to structure holding the DSI Host core information\r
132  * @return dsih_error_t\r
133  */\r
134 dsih_error_t mipi_dsih_close(dsih_ctrl_t * instance)\r
135 {\r
136         if (instance == 0)\r
137         {\r
138                 return ERR_DSI_INVALID_INSTANCE;\r
139         }\r
140         if (instance->status != INITIALIZED)\r
141         {\r
142                 return ERR_DSI_INVALID_INSTANCE;\r
143         }\r
144         mipi_dsih_hal_int_mask_0(instance, 0xffffff);\r
145         mipi_dsih_hal_int_mask_1(instance, 0xffffff);\r
146         mipi_dsih_dphy_close(&(instance->phy_instance));\r
147         mipi_dsih_hal_power(instance, 0);\r
148         instance->status = NOT_INITIALIZED;\r
149         return OK;\r
150 }\r
151 /**\r
152  * Enable return to low power mode inside video periods when timing allows\r
153  * @param instance pointer to structure holding the DSI Host core information\r
154  * @param hfp allow to return to lp inside horizontal front porch pixels\r
155  * @param hbp allow to return to lp inside horizontal back porch pixels\r
156  * @param vactive allow to return to lp inside vertical active lines\r
157  * @param vfp allow to return to lp inside vertical front porch lines\r
158  * @param vbp allow to return to lp inside vertical back porch lines\r
159  * @param vsync allow to return to lp inside vertical sync lines\r
160  */\r
161 void mipi_dsih_allow_return_to_lp(dsih_ctrl_t * instance, int hfp, int hbp, int vactive, int vfp, int vbp, int vsync)\r
162 {\r
163     if(0 == instance)\r
164     {\r
165         return;\r
166     }\r
167 \r
168     if (instance->status == INITIALIZED)\r
169     {\r
170         mipi_dsih_hal_dpi_lp_during_hfp(instance, hfp);\r
171         mipi_dsih_hal_dpi_lp_during_hbp(instance, hbp);\r
172         mipi_dsih_hal_dpi_lp_during_vactive(instance, vactive);\r
173         mipi_dsih_hal_dpi_lp_during_vfp(instance, vfp);\r
174         mipi_dsih_hal_dpi_lp_during_vbp(instance, vbp);\r
175         mipi_dsih_hal_dpi_lp_during_vsync(instance, vsync);\r
176         return;\r
177     }\r
178     if (instance->log_error != 0)\r
179     {\r
180         instance->log_error("sprdfb: [mipi_dsih_allow_return_to_lp] invalid instance");\r
181     }\r
182 \r
183 }\r
184 /**\r
185  * Set DCS command packet transmission to low power\r
186  * @param instance pointer to structure holding the DSI Host core information\r
187  * @param long_write command packets\r
188  * @param short_write command packets with none and one parameters\r
189  * @param short_read command packets with none parameters\r
190  */\r
191 void mipi_dsih_dcs_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read)\r
192 {\r
193     if(0 == instance)\r
194     {\r
195         return;\r
196     }\r
197 \r
198     if (instance->status == INITIALIZED)\r
199     {\r
200         mipi_dsih_hal_dcs_wr_tx_type(instance, 0, short_write);\r
201         mipi_dsih_hal_dcs_wr_tx_type(instance, 1, short_write);\r
202         mipi_dsih_hal_dcs_wr_tx_type(instance, 3, long_write); /* long packet*/\r
203         mipi_dsih_hal_dcs_rd_tx_type(instance, 0, short_read);\r
204         return;\r
205     }\r
206     if (instance->log_error != 0)\r
207     {\r
208         instance->log_error("sprdfb: [mipi_dsih_dcs_cmd_lp_transmission] invalid instance");\r
209     }\r
210 \r
211 }\r
212 /**\r
213  * Set Generic interface packet transmission to low power\r
214  * @param instance pointer to structure holding the DSI Host core information\r
215  * @param long_write command packets\r
216  * @param short_write command packets with none, one and two parameters\r
217  * @param short_read command packets with none, one and two parameters\r
218  */\r
219 void mipi_dsih_gen_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read)\r
220 {\r
221     if(0 == instance)\r
222     {\r
223         return;\r
224     }\r
225 \r
226     if (instance->status == INITIALIZED)\r
227     {\r
228         mipi_dsih_hal_gen_wr_tx_type(instance, 0, short_write);\r
229         mipi_dsih_hal_gen_wr_tx_type(instance, 1, short_write);\r
230         mipi_dsih_hal_gen_wr_tx_type(instance, 2, short_write);\r
231         mipi_dsih_hal_gen_wr_tx_type(instance, 3, long_write); /* long packet*/\r
232         mipi_dsih_hal_gen_rd_tx_type(instance, 0, short_read);\r
233         mipi_dsih_hal_gen_rd_tx_type(instance, 1, short_read);\r
234         mipi_dsih_hal_gen_rd_tx_type(instance, 2, short_read);\r
235         return;\r
236     }\r
237     if (instance->log_error != 0)\r
238     {\r
239         instance->log_error("sprdfb: [mipi_dsih_gen_cmd_lp_transmission] invalid instance");\r
240     }\r
241 \r
242 }\r
243 /* packet handling */\r
244 /**\r
245  *  Enable all receiving activities (applying a Bus Turn Around).\r
246  *  - Disabling using this function will stop all acknowledges by the\r
247  *  peripherals and no interrupts from low-level protocol error reporting\r
248  *  will be able to rise.\r
249  *  - Enabling any receiving function (command or frame ACKs, ECC,\r
250  *  tear effect ACK or EoTp receiving) will enable this automatically,\r
251  *  but it must be EXPLICITLY be disabled to disabled all kinds of\r
252  *  receiving functionality.\r
253  * @param instance pointer to structure holding the DSI Host core information\r
254  * @param enable or disable\r
255  * @return error code\r
256  */\r
257 dsih_error_t mipi_dsih_enable_rx(dsih_ctrl_t * instance, int enable)\r
258 {\r
259         mipi_dsih_hal_bta_en(instance, enable);\r
260         return OK;\r
261 }\r
262 /**\r
263  *  Enable command packet acknowledges by the peripherals\r
264  *  - For interrupts to rise the monitored event must be registered\r
265  *  using the event_register function\r
266  * @param instance pointer to structure holding the DSI Host core information\r
267  * @param enable or disable\r
268  * @return error code\r
269  */\r
270 dsih_error_t mipi_dsih_peripheral_ack(dsih_ctrl_t * instance, int enable)\r
271 {\r
272         if (instance != 0)\r
273         {\r
274                 if (instance->status == INITIALIZED)\r
275                 {\r
276                         mipi_dsih_hal_cmd_ack_en(instance, enable);\r
277                         if (enable)\r
278                         {\r
279                                 mipi_dsih_hal_bta_en(instance, 1);\r
280                         }\r
281                         return OK;\r
282                 }\r
283         }\r
284         return ERR_DSI_INVALID_INSTANCE;\r
285 }\r
286 /**\r
287  * Enable tearing effect acknowledges by the peripherals (wait for TE)\r
288  * - It enables the following from the DSI specification\r
289  * "Since the timing of a TE event is, by definition, unknown to the host\r
290  * processor, the host processor shall give bus possession to the display\r
291  * module and then wait for up to one video frame period for the TE response.\r
292  * During this time, the host processor cannot send new commands, or requests\r
293  * to the display module, because it does not have bus possession."\r
294  * @param instance pointer to structure holding the DSI Host core information\r
295  * @param enable or disable\r
296  * @return error code\r
297  */\r
298 dsih_error_t mipi_dsih_tear_effect_ack(dsih_ctrl_t * instance, int enable)\r
299 {\r
300         if (instance != 0)\r
301         {\r
302                 if (instance->status == INITIALIZED)\r
303                 {\r
304                         mipi_dsih_hal_tear_effect_ack_en(instance, enable);\r
305                         if (enable)\r
306                         {\r
307                                 mipi_dsih_hal_bta_en(instance, 1);\r
308                         }\r
309                         return OK;\r
310                 }\r
311         }\r
312         return ERR_DSI_INVALID_INSTANCE;\r
313 }\r
314 /**\r
315  * Enable the receiving of EoT packets at the end of LS transmission.\r
316  * @param instance pointer to structure holding the DSI Host core information\r
317  * @param enable or disable\r
318  * @return error code\r
319  */\r
320 dsih_error_t mipi_dsih_eotp_rx(dsih_ctrl_t * instance, int enable)\r
321 {\r
322         if (instance != 0)\r
323         {\r
324                 if (instance->status == INITIALIZED)\r
325                 {\r
326                         mipi_dsih_hal_gen_eotp_rx_en(instance, enable);\r
327                         if (enable)\r
328                         {\r
329                                 mipi_dsih_hal_bta_en(instance, 1);\r
330                         }\r
331                         return OK;\r
332                 }\r
333         }\r
334         return ERR_DSI_INVALID_INSTANCE;\r
335 }\r
336 /**\r
337  * Enable the listening to ECC bytes. This allows for recovering from\r
338  * 1 bit errors. To report ECC events, the ECC events should be registered\r
339  * @param instance pointer to structure holding the DSI Host core information\r
340  * @param enable or disable\r
341  * @return error code\r
342  */\r
343 dsih_error_t mipi_dsih_ecc_rx(dsih_ctrl_t * instance, int enable)\r
344 {\r
345         if (instance != 0)\r
346         {\r
347                 if (instance->status == INITIALIZED)\r
348                 {\r
349                         mipi_dsih_hal_gen_ecc_rx_en(instance, enable);\r
350                         if (enable)\r
351                         {\r
352                                 mipi_dsih_hal_bta_en(instance, 1);\r
353                         }\r
354                         return OK;\r
355                 }\r
356         }\r
357         return ERR_DSI_INVALID_INSTANCE;\r
358 }\r
359 /**\r
360  * Enable the sending of EoT (End of Transmission) packets at the end of HS\r
361  * transmission. It was made optional in the DSI spec. for retro-compatibility.\r
362  * @param instance pointer to structure holding the DSI Host core information\r
363  * @param enable or disable\r
364  * @return error code\r
365  */\r
366 dsih_error_t mipi_dsih_eotp_tx(dsih_ctrl_t * instance, int enable)\r
367 {\r
368         if (instance != 0)\r
369         {\r
370                 if (instance->status == INITIALIZED)\r
371                 {\r
372                         mipi_dsih_hal_gen_eotp_tx_en(instance, enable);\r
373                         return OK;\r
374                 }\r
375         }\r
376         return ERR_DSI_INVALID_INSTANCE;\r
377 }\r
378 /**\r
379  * Configure DPI video interface\r
380  * - If not in burst mode, it will compute the video and null packet sizes\r
381  * according to necessity\r
382  * - Configure timers for data lanes and/or clock lane to return to LP when\r
383  * bandwidth is not filled by data\r
384  * @param instance pointer to structure holding the DSI Host core information\r
385  * @param video_params pointer to video stream-to-send information\r
386  * @return error code\r
387  */\r
388 dsih_error_t mipi_dsih_dpi_video(dsih_ctrl_t * instance, dsih_dpi_video_t * video_params)\r
389 {\r
390         dsih_error_t err_code = OK;\r
391         uint16_t bytes_per_pixel_x100 = 0; /* bpp x 100 because it can be 2.25 */\r
392         uint16_t video_size = 0;\r
393         uint32_t ratio_clock_xPF = 0; /* holds dpi clock/byte clock times precision factor */\r
394         uint16_t null_packet_size = 0;\r
395         uint8_t video_size_step = 1;\r
396         uint32_t hs_timeout = 0;\r
397         uint32_t total_bytes = 0;\r
398         uint32_t bytes_per_chunk = 0;\r
399         uint32_t no_of_chunks = 0;\r
400         uint32_t bytes_left = 0;\r
401         uint32_t chunk_overhead = 0;\r
402         int counter = 0;\r
403         /* check DSI controller instance */\r
404         if ((instance == 0) || (video_params == 0))\r
405         {\r
406                 return ERR_DSI_INVALID_INSTANCE;\r
407         }\r
408         if (instance->status != INITIALIZED)\r
409         {\r
410                 return ERR_DSI_INVALID_INSTANCE;\r
411         }\r
412         if (video_params->no_of_lanes > instance->max_lanes)\r
413         {\r
414                 return ERR_DSI_OUT_OF_BOUND;\r
415         }\r
416     /* set up phy pll to required lane clock */\r
417         err_code = mipi_dsih_phy_hs2lp_config(instance, video_params->max_hs_to_lp_cycles);\r
418         err_code |=     mipi_dsih_phy_lp2hs_config(instance, video_params->max_lp_to_hs_cycles);\r
419         err_code = mipi_dsih_phy_clk_hs2lp_config(instance, video_params->max_clk_hs_to_lp_cycles);\r
420         err_code |=     mipi_dsih_phy_clk_lp2hs_config(instance, video_params->max_clk_lp_to_hs_cycles);\r
421         video_params->non_continuous_clock = 0; // 1.21a new feature, set 1 result in half-bottom snow screen , disbale it\r
422         mipi_dsih_non_continuous_clock(instance,video_params->non_continuous_clock);\r
423     //begin--frank\r
424     //err_code = mipi_dsih_dphy_configure(&(instance->phy_instance), video_params->no_of_lanes, video_params->byte_clock * 8);\r
425     //if (err_code)\r
426     //{\r
427     //    return err_code;\r
428     //}\r
429     //end--frank\r
430         ratio_clock_xPF = (video_params->byte_clock * PRECISION_FACTOR) / (video_params->pixel_clock);\r
431         video_size = video_params->h_active_pixels;\r
432         /* set up ACKs and error reporting */\r
433         mipi_dsih_hal_dpi_frame_ack_en(instance, video_params->receive_ack_packets);\r
434         if (video_params->receive_ack_packets)\r
435         { /* if ACK is requested, enable BTA, otherwise leave as is */\r
436                 mipi_dsih_hal_bta_en(instance, 1);\r
437         }\r
438         /* mipi_dsih_hal_gen_cmd_mode_en(instance, 0); */\r
439         mipi_dsih_hal_dpi_video_mode_en(instance, 1);\r
440         /* get bytes per pixel and video size step (depending if loosely or not */\r
441         switch (video_params->color_coding)\r
442         {\r
443         case COLOR_CODE_16BIT_CONFIG1:\r
444         case COLOR_CODE_16BIT_CONFIG2:\r
445         case COLOR_CODE_16BIT_CONFIG3:\r
446                 bytes_per_pixel_x100 = 200;\r
447                 video_size_step = 1;\r
448                 break;\r
449         case COLOR_CODE_18BIT_CONFIG1:\r
450         case COLOR_CODE_18BIT_CONFIG2:\r
451                 mipi_dsih_hal_dpi_18_loosely_packet_en(instance, video_params->is_18_loosely);\r
452                 bytes_per_pixel_x100 = 225;\r
453                 if (!video_params->is_18_loosely)\r
454                 { /* 18bits per pixel and NOT loosely, packets should be multiples of 4 */\r
455                         video_size_step = 4;\r
456                         /* round up active H pixels to a multiple of 4 */\r
457                         for (; (video_size % 4) != 0; video_size++)\r
458                         {\r
459                                 ;\r
460                         }\r
461                 }\r
462                 else\r
463                 {\r
464                         video_size_step = 1;\r
465                 }\r
466                 break;\r
467         case COLOR_CODE_24BIT:\r
468                 bytes_per_pixel_x100 = 300;\r
469                 video_size_step = 1;\r
470                 break;\r
471         case COLOR_CODE_20BIT_YCC422_LOOSELY:\r
472                 bytes_per_pixel_x100 = 250;\r
473                 video_size_step = 2;\r
474                 /* round up active H pixels to a multiple of 2 */\r
475                 if ((video_size % 2) != 0)\r
476                 {\r
477                         video_size += 1;\r
478                 }\r
479                 break;\r
480         case COLOR_CODE_24BIT_YCC422:\r
481                 bytes_per_pixel_x100 = 300;\r
482                 video_size_step = 2;\r
483                 /* round up active H pixels to a multiple of 2 */\r
484                 if ((video_size % 2) != 0)\r
485                 {\r
486                         video_size += 1;\r
487                 }\r
488                 break;\r
489         case COLOR_CODE_16BIT_YCC422:\r
490                 bytes_per_pixel_x100 = 200;\r
491                 video_size_step = 2;\r
492                 /* round up active H pixels to a multiple of 2 */\r
493                 if ((video_size % 2) != 0)\r
494                 {\r
495                         video_size += 1;\r
496                 }\r
497                 break;\r
498         case COLOR_CODE_30BIT:\r
499                 bytes_per_pixel_x100 = 375;\r
500                 video_size_step = 2;\r
501                 break;\r
502         case COLOR_CODE_36BIT:\r
503                 bytes_per_pixel_x100 = 450;\r
504                 video_size_step = 2;\r
505                 break;\r
506         case COLOR_CODE_12BIT_YCC420:\r
507                 bytes_per_pixel_x100 = 150;\r
508                 video_size_step = 2;\r
509                 /* round up active H pixels to a multiple of 2 */\r
510                 if ((video_size % 2) != 0)\r
511                 {\r
512                         video_size += 1;\r
513                 }\r
514                 break;\r
515         default:\r
516                 if (instance->log_error != 0)\r
517                 {\r
518                         instance->log_error("sprdfb: invalid color coding");\r
519                 }\r
520                 err_code = ERR_DSI_COLOR_CODING;\r
521                 break;\r
522         }\r
523         if (err_code == OK)\r
524         {\r
525                 err_code = mipi_dsih_hal_dpi_color_coding(instance, video_params->color_coding);\r
526         }\r
527         if (err_code != OK)\r
528         {\r
529                 return err_code;\r
530         }\r
531         mipi_dsih_hal_dpi_video_mode_type(instance, video_params->video_mode);\r
532         mipi_dsih_hal_dpi_hline(instance, (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
533         mipi_dsih_hal_dpi_hbp(instance, ((video_params->h_back_porch_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
534         mipi_dsih_hal_dpi_hsa(instance, ((video_params->h_sync_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
535         mipi_dsih_hal_dpi_vactive(instance, video_params->v_active_lines);\r
536         mipi_dsih_hal_dpi_vfp(instance, video_params->v_total_lines - (video_params->v_back_porch_lines + video_params->v_sync_lines + video_params->v_active_lines));\r
537         mipi_dsih_hal_dpi_vbp(instance, video_params->v_back_porch_lines);\r
538         mipi_dsih_hal_dpi_vsync(instance, video_params->v_sync_lines);\r
539         mipi_dsih_hal_dpi_hsync_pol(instance, !video_params->h_polarity);\r
540         mipi_dsih_hal_dpi_vsync_pol(instance, !video_params->v_polarity);\r
541         mipi_dsih_hal_dpi_dataen_pol(instance, !video_params->data_en_polarity);\r
542         /* HS timeout */\r
543         hs_timeout = ((video_params->h_total_pixels * video_params->v_active_lines) + (DSIH_PIXEL_TOLERANCE * bytes_per_pixel_x100) / 100);\r
544         for (counter = 0x80; (counter < hs_timeout) && (counter > 2); counter--)\r
545         {\r
546                 if ((hs_timeout % counter) == 0)\r
547                 {\r
548                         mipi_dsih_hal_timeout_clock_division(instance, counter);\r
549                         mipi_dsih_hal_lp_rx_timeout(instance, (uint16_t)(hs_timeout / counter));\r
550                         mipi_dsih_hal_hs_tx_timeout(instance, (uint16_t)(hs_timeout / counter));\r
551                         break;\r
552                 }\r
553         }\r
554     /* TX_ESC_CLOCK_DIV must be less than 20000KHz */\r
555     mipi_dsih_hal_tx_escape_division(instance, 4); //6 //Jessia\r
556         /* video packetisation */\r
557         if (video_params->video_mode == VIDEO_BURST_WITH_SYNC_PULSES)\r
558         { /* BURST */\r
559                 mipi_dsih_hal_dpi_null_packet_en(instance, 0);\r
560                 mipi_dsih_hal_dpi_multi_packet_en(instance, 0);\r
561                 err_code = mipi_dsih_hal_dpi_null_packet_size(instance, 0);\r
562                 err_code = err_code? err_code: mipi_dsih_hal_dpi_chunks_no(instance, 1);\r
563                 err_code = err_code? err_code: mipi_dsih_hal_dpi_video_packet_size(instance, video_size);\r
564                 if (err_code != OK)\r
565                 {\r
566                         return err_code;\r
567                 }\r
568                 /* BURST by default, returns to LP during ALL empty periods - energy saving */\r
569                 mipi_dsih_hal_dpi_lp_during_hfp(instance, 1);\r
570 #if defined(CONFIG_FB_SCX35) && defined(CONFIG_FB_LCD_SSD2075_MIPI)\r
571                 mipi_dsih_hal_dpi_lp_during_hbp(instance, 0);//forbit return to lp during hbp\r
572 #else\r
573         mipi_dsih_hal_dpi_lp_during_hbp(instance, 1);\r
574 #endif\r
575                 mipi_dsih_hal_dpi_lp_during_vactive(instance, 1);\r
576                 mipi_dsih_hal_dpi_lp_during_vfp(instance, 1);\r
577                 mipi_dsih_hal_dpi_lp_during_vbp(instance, 1);\r
578                 mipi_dsih_hal_dpi_lp_during_vsync(instance, 1);\r
579 #if DEBUG\r
580                 /*      D E B U G               */\r
581                 if (instance->log_info != 0)\r
582                 {\r
583                         instance->log_info("sprdfb: burst video");\r
584                         instance->log_info("sprdfb: h line time %ld", (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
585                         instance->log_info("sprdfb: video_size %ld", video_size);\r
586                 }\r
587 #endif\r
588         }\r
589         else\r
590         {       /* non burst transmission */\r
591                 null_packet_size = 0;\r
592                 /* bytes to be sent - first as one chunk */\r
593                 bytes_per_chunk = (bytes_per_pixel_x100 * video_params->h_active_pixels) / 100 + VIDEO_PACKET_OVERHEAD;\r
594                 /* bytes being received through the DPI interface per byte clock cycle */\r
595                 total_bytes = (ratio_clock_xPF * video_params->no_of_lanes * (video_params->h_total_pixels - video_params->h_back_porch_pixels - video_params->h_sync_pixels)) / PRECISION_FACTOR;\r
596                 /* check if the in pixels actually fit on the DSI link */\r
597                 if (total_bytes >= bytes_per_chunk)\r
598                 {\r
599                         chunk_overhead = total_bytes - bytes_per_chunk;\r
600                         /* overhead higher than 1 -> enable multi packets */\r
601                         if (chunk_overhead > 1)\r
602                         {       /* MULTI packets */\r
603                                 for (video_size = video_size_step; video_size < video_params->h_active_pixels; video_size += video_size_step)\r
604                                 {       /* determine no of chunks */\r
605                                         if ((((video_params->h_active_pixels * PRECISION_FACTOR) / video_size) % PRECISION_FACTOR) == 0)\r
606                                         {\r
607                                                 no_of_chunks = video_params->h_active_pixels / video_size;\r
608                                                 bytes_per_chunk = (bytes_per_pixel_x100 * video_size) / 100 + VIDEO_PACKET_OVERHEAD;\r
609                                                 if (total_bytes >= (bytes_per_chunk * no_of_chunks))\r
610                                                 {\r
611                                                         bytes_left = total_bytes - (bytes_per_chunk * no_of_chunks);\r
612                                                         break;\r
613                                                 }\r
614                                         }\r
615                                 }\r
616                                 /* prevent overflow (unsigned - unsigned) */\r
617                                 if (bytes_left > (NULL_PACKET_OVERHEAD * no_of_chunks))\r
618                                 {\r
619                                         null_packet_size = (bytes_left - (NULL_PACKET_OVERHEAD * no_of_chunks)) / no_of_chunks;\r
620                                         if (null_packet_size > MAX_NULL_SIZE)\r
621                                         {       /* avoid register overflow */\r
622                                                 null_packet_size = MAX_NULL_SIZE;\r
623                                         }\r
624                                 }\r
625                         }\r
626                         else\r
627                         {       /* no multi packets */\r
628                                 no_of_chunks = 1;\r
629 #if DEBUG\r
630                                 /*      D E B U G               */\r
631                                 if (instance->log_info != 0)\r
632                                 {\r
633                                         instance->log_info("sprdfb: no multi no null video");\r
634                                         instance->log_info("sprdfb: h line time %ld", (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
635                                         instance->log_info("sprdfb: video_size %ld", video_size);\r
636                                 }\r
637                                 /************************/\r
638 #endif\r
639                                 /* video size must be a multiple of 4 when not 18 loosely */\r
640                                 for (video_size = video_params->h_active_pixels; (video_size % video_size_step) != 0; video_size++)\r
641                                 {\r
642                                         ;\r
643                                 }\r
644                         }\r
645                 }\r
646                 else\r
647                 {\r
648                         instance->log_error("sprdfb: resolution cannot be sent to display through current settings");\r
649                         err_code = ERR_DSI_OVERFLOW;\r
650                 }\r
651         }\r
652         err_code = err_code? err_code: mipi_dsih_hal_dpi_chunks_no(instance, no_of_chunks);\r
653         err_code = err_code? err_code: mipi_dsih_hal_dpi_video_packet_size(instance, video_size);\r
654         err_code = err_code? err_code: mipi_dsih_hal_dpi_null_packet_size(instance, null_packet_size);\r
655         mipi_dsih_hal_dpi_null_packet_en(instance, null_packet_size > 0? 1: 0);\r
656         mipi_dsih_hal_dpi_multi_packet_en(instance, (no_of_chunks > 1)? 1: 0);\r
657 #if DEBUG\r
658         /*      D E B U G               */\r
659         if (instance->log_info != 0)\r
660         {\r
661                 instance->log_info("sprdfb: total_bytes %d", total_bytes);\r
662                 instance->log_info("sprdfb: bytes_per_chunk %d", bytes_per_chunk);\r
663                 instance->log_info("sprdfb: bytes left %d", bytes_left);\r
664                 instance->log_info("sprdfb: null packets %d", null_packet_size);\r
665                 instance->log_info("sprdfb: chunks %ld", no_of_chunks);\r
666                 instance->log_info("sprdfb: video_size %ld", video_size);\r
667         }\r
668         /************************/\r
669 #endif\r
670         mipi_dsih_hal_dpi_video_vc(instance, video_params->virtual_channel);\r
671         mipi_dsih_dphy_no_of_lanes(&(instance->phy_instance), video_params->no_of_lanes);\r
672         /* enable high speed clock */\r
673         //mipi_dsih_dphy_enable_hs_clk(&(instance->phy_instance), 1);//jessica, panel not init yet, could not set to hs, or result in err to some panel\r
674     return err_code;\r
675 }\r
676 /**\r
677  * Send a DCS write command\r
678  * It sends the User Command Set commands listed in the DCS specification and\r
679  * not the Manufacturer Command Set. To send the Manufacturer Commands use the\r
680  * packet on the generic packets sending function\r
681  * function sets the packet data type automatically\r
682  * @param instance pointer to structure holding the DSI Host core information\r
683  * @param vc destination virtual channel\r
684  * @param params byte-addressed array of command parameters, including the\r
685  * command itself\r
686  * @param param_length length of the above array\r
687  * @return error code\r
688  * @note this function has an active delay to wait for the buffer to clear.\r
689  * The delay is limited to DSIH_FIFO_ACTIVE_WAIT x register access time\r
690  */\r
691 dsih_error_t mipi_dsih_dcs_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length)\r
692 {\r
693         uint8_t packet_type = 0;\r
694 //    int i = 0;\r
695         if (params == 0)\r
696         {\r
697                 return ERR_DSI_OUT_OF_BOUND;\r
698         }\r
699 #if 0\r
700         if (param_length > 2)\r
701         {\r
702                 i = 2;\r
703         }\r
704         switch (params[i])\r
705         {\r
706         case 0x39:\r
707         case 0x38:\r
708         case 0x34:\r
709         case 0x29:\r
710         case 0x28:\r
711         case 0x21:\r
712         case 0x20:\r
713         case 0x13:\r
714         case 0x12:\r
715         case 0x11:\r
716         case 0x10:\r
717         case 0x01:\r
718         case 0x00:\r
719                 packet_type = 0x05; /* DCS short write no param */\r
720                 break;\r
721         case 0x3A:\r
722         case 0x36:\r
723         case 0x35:\r
724         case 0x26:\r
725                 packet_type = 0x15; /* DCS short write 1 param */\r
726                 break;\r
727         case 0x44:\r
728         case 0x3C:\r
729         case 0x37:\r
730         case 0x33:\r
731         case 0x30:\r
732         case 0x2D:\r
733         case 0x2C:\r
734         case 0x2B:\r
735         case 0x2A:\r
736                 packet_type = 0x39; /* DCS long write/write_LUT command packet */\r
737                 break;\r
738         default:\r
739                 if (instance->log_error != 0)\r
740                 {\r
741                         instance->log_error("invalid DCS command");\r
742                 }\r
743                 return ERR_DSI_INVALID_COMMAND;\r
744         }\r
745 #else\r
746         switch(param_length)\r
747         {\r
748                 case 1:\r
749                         packet_type = 0x05; /* DCS short write no param */\r
750                         break;\r
751                 case 2:\r
752                         packet_type = 0x15; /* DCS short write 1 param */\r
753                         break;\r
754                 default:\r
755                         packet_type = 0x39; /* DCS long write/write_LUT command packet */\r
756                         break;\r
757         }\r
758 #endif\r
759     return mipi_dsih_gen_wr_packet(instance, vc, packet_type, params, param_length);\r
760 }\r
761 /**\r
762  * Enable command mode\r
763  * - This function shall be explicitly called before commands are send if they\r
764  * are to be sent in command mode and not interlaced with video\r
765  * - If video mode is ON, it will be turned off automatically\r
766  * @param instance pointer to structure holding the DSI Host core information\r
767  * @param en enable/disable\r
768  */\r
769 void mipi_dsih_cmd_mode(dsih_ctrl_t * instance, int en)\r
770 {\r
771     if(0 == instance)\r
772     {\r
773         return;\r
774     }\r
775 \r
776     if (instance->status == INITIALIZED)\r
777     {\r
778                 mipi_dsih_hal_gen_cmd_mode_en(instance, en);\r
779                   return;\r
780     }\r
781     if (instance->log_error != 0)\r
782     {\r
783         instance->log_error("sprdfb: [mipi_dsih_cmd_mode] invalid instance");\r
784     }\r
785 \r
786 }\r
787 /**\r
788  * Enable video mode\r
789  * - If command mode is ON, it will be turned off automatically\r
790  * @param instance pointer to structure holding the DSI Host core information\r
791  * @param en enable/disable\r
792  */\r
793 void mipi_dsih_video_mode(dsih_ctrl_t * instance, int en)\r
794 {\r
795     if(0 == instance)\r
796     {\r
797         return;\r
798     }\r
799 \r
800     if (instance->status == INITIALIZED)\r
801     {\r
802                 mipi_dsih_hal_dpi_video_mode_en(instance, en);\r
803                   return;\r
804     }\r
805     if (instance->log_error != 0)\r
806     {\r
807         instance->log_error("sprdfb: [mipi_dsih_video_mode] invalid instance");\r
808     }\r
809 \r
810 }\r
811 \r
812 /**\r
813  * Get the current active mode\r
814  * - 1 command mode\r
815  * - 2 DPI video mode\r
816  */\r
817 int mipi_dsih_active_mode(dsih_ctrl_t * instance)\r
818 {\r
819         if (mipi_dsih_hal_gen_is_cmd_mode(instance))\r
820         {\r
821                 return 1;\r
822         }\r
823         else if (mipi_dsih_hal_dpi_is_video_mode(instance))\r
824         {\r
825                 return 2;\r
826         }\r
827         return 0;\r
828 }\r
829 /**\r
830  * Send a generic write command\r
831  * @param instance pointer to structure holding the DSI Host core information\r
832  * @param vc destination virtual channel\r
833  * @param params byte-addressed array of command parameters\r
834  * @param param_length length of the above array\r
835  * @return error code\r
836  * @note this function has an active delay to wait for the buffer to clear.\r
837  * The delay is limited to DSIH_FIFO_ACTIVE_WAIT x register access time\r
838  */\r
839 dsih_error_t mipi_dsih_gen_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length)\r
840 {\r
841         uint8_t data_type = 0;\r
842         switch(param_length)\r
843         {\r
844         case 0:\r
845                 data_type = 0x03;\r
846                 break;\r
847         case 1:\r
848                 data_type = 0x13;\r
849                 break;\r
850         case 2:\r
851                 data_type = 0x23;\r
852                 break;\r
853         default:\r
854                 data_type = 0x29;\r
855                 break;\r
856         }\r
857         return mipi_dsih_gen_wr_packet(instance, vc, data_type, params, param_length);\r
858 }\r
859 /**\r
860  * Send a packet on the generic interface\r
861  * @param instance pointer to structure holding the DSI Host core information\r
862  * @param vc destination virtual channel\r
863  * @param data_type type of command, inserted in first byte of header\r
864  * @param params byte array of command parameters\r
865  * @param param_length length of the above array\r
866  * @return error code\r
867  * @note this function has an active delay to wait for the buffer to clear.\r
868  * The delay is limited to:\r
869  * (param_length / 4) x DSIH_FIFO_ACTIVE_WAIT x register access time\r
870  * @note the controller restricts the sending of .\r
871  * This function will not be able to send Null and Blanking packets due to\r
872  *  controller restriction\r
873  */\r
874 dsih_error_t mipi_dsih_gen_wr_packet(dsih_ctrl_t * instance, uint8_t vc, uint8_t data_type, uint8_t* params, uint16_t param_length)\r
875 {\r
876         dsih_error_t err_code = OK;\r
877         /* active delay iterator */\r
878         int timeout = 0;\r
879         /* iterators */\r
880         int i = 0;\r
881         int j = 0;\r
882         /* holds padding bytes needed */\r
883         int compliment_counter = 0;\r
884         uint8_t* payload = 0;\r
885         /* temporary variable to arrange bytes into words */\r
886         uint32_t temp = 0;\r
887         uint16_t word_count = 0;\r
888         if (instance == 0)\r
889         {\r
890                 return ERR_DSI_INVALID_INSTANCE;\r
891         }\r
892         if (instance->status != INITIALIZED)\r
893         {\r
894                 return ERR_DSI_INVALID_INSTANCE;\r
895         }\r
896         if ((params == 0) && (param_length != 0)) /* pointer NULL */\r
897         {\r
898                 return ERR_DSI_OUT_OF_BOUND;\r
899         }\r
900         if (param_length > 2)\r
901         {       /* long packet - write word count to header, and the rest to payload */\r
902                 payload = params + (2 * sizeof(params[0]));\r
903                 word_count = (params[1] << 8) | params[0];\r
904                 if ((param_length - 2) < word_count)\r
905                 {\r
906                         if (instance->log_error != 0)\r
907                         {\r
908                                 instance->log_error("sprdfb: sent > input payload. complemented with zeroes");\r
909                         }\r
910                         compliment_counter = (param_length - 2) - word_count;\r
911                 }\r
912                 else if ((param_length - 2) > word_count)\r
913                 {\r
914                         if (instance->log_error != 0)\r
915                         {\r
916                                 instance->log_error("sprdfb: Overflow - input > sent. payload truncated");\r
917                         }\r
918                 }\r
919                 for (i = 0; i < (param_length - 2); i += j)\r
920                 {\r
921                         temp = 0;\r
922                         for (j = 0; (j < 4) && ((j + i) < (param_length - 2)); j++)\r
923                         {       /* temp = (payload[i + 3] << 24) | (payload[i + 2] << 16) | (payload[i + 1] << 8) | payload[i]; */\r
924                                 temp |= payload[i + j] << (j * 8);\r
925                         }\r
926                         /* check if payload Tx fifo is not full */\r
927                         for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
928                         {\r
929                                 if (!mipi_dsih_hal_gen_packet_payload(instance, temp))\r
930                                 {\r
931                                         break;\r
932                                 }\r
933                         }\r
934                         if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))\r
935                         {\r
936                                 return ERR_DSI_TIMEOUT;\r
937                         }\r
938                 }\r
939                 /* if word count entered by the user more than actual parameters received\r
940                  * fill with zeroes - a fail safe mechanism, otherwise controller will\r
941                  * want to send data from an empty buffer */\r
942                 for (i = 0; i < compliment_counter; i++)\r
943                 {\r
944                         /* check if payload Tx fifo is not full */\r
945                         for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
946                         {\r
947                                 if (!mipi_dsih_hal_gen_packet_payload(instance, 0x00))\r
948                                 {\r
949                                         break;\r
950                                 }\r
951                         }\r
952                         if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))\r
953                         {\r
954                                 return ERR_DSI_TIMEOUT;\r
955                         }\r
956                 }\r
957         }\r
958         for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
959         {\r
960                 /* check if payload Tx fifo is not full */\r
961                 if (!mipi_dsih_hal_gen_cmd_fifo_full(instance))\r
962                 {\r
963                         if (param_length == 0)\r
964                         {\r
965                                 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, 0x0, 0x0);\r
966                         }\r
967                         else if (param_length == 1)\r
968                         {\r
969                                 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, 0x0, params[0]);\r
970                         }\r
971                         else\r
972                         {\r
973                                 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, params[1], params[0]);\r
974                         }\r
975                         break;\r
976                 }\r
977         }\r
978         if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))\r
979         {\r
980                 err_code = ERR_DSI_TIMEOUT;\r
981         }\r
982         return err_code;\r
983 }\r
984 /**\r
985  * Send a DCS READ command to peripheral\r
986  * function sets the packet data type automatically\r
987  * @param instance pointer to structure holding the DSI Host core information\r
988  * @param vc destination virtual channel\r
989  * @param command DCS code\r
990  * @param bytes_to_read no of bytes to read (expected to arrive at buffer)\r
991  * @param read_buffer pointer to 8-bit array to hold the read buffer words\r
992  * return read_buffer_length\r
993  * @note this function has an active delay to wait for the buffer to clear.\r
994  * The delay is limited to 2 x DSIH_FIFO_ACTIVE_WAIT\r
995  * (waiting for command buffer, and waiting for receiving)\r
996  * @note this function will enable BTA\r
997  */\r
998 uint16_t mipi_dsih_dcs_rd_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t command, uint8_t bytes_to_read, uint8_t* read_buffer)\r
999 {\r
1000         if (instance == 0)\r
1001         {\r
1002                 return 0;\r
1003         }\r
1004         if (instance->status != INITIALIZED)\r
1005         {\r
1006                 return 0;\r
1007         }\r
1008         switch (command)\r
1009         {\r
1010         case 0xA8:\r
1011         case 0xA1:\r
1012         case 0x45:\r
1013         case 0x3E:\r
1014         case 0x2E:\r
1015         case 0x0F:\r
1016         case 0x0E:\r
1017         case 0x0D:\r
1018         case 0x0C:\r
1019         case 0x0B:\r
1020         case 0x0A:\r
1021         case 0x08:\r
1022         case 0x07:\r
1023         case 0x06:\r
1024                 /* COMMAND_TYPE 0x06 - DCS Read no params refer to DSI spec p.47 */\r
1025                 return mipi_dsih_gen_rd_packet(instance, vc, 0x06, 0x0, command, bytes_to_read, read_buffer);\r
1026         default:\r
1027                 if (instance->log_error != 0)\r
1028                 {\r
1029                         instance->log_error("sprdfb: invalid DCS command");\r
1030                 }\r
1031                 return 0;\r
1032         }\r
1033         return 0;\r
1034 }\r
1035 /**\r
1036  * Send Generic READ command to peripheral\r
1037  * - function sets the packet data type automatically\r
1038  * @param instance pointer to structure holding the DSI Host core information\r
1039  * @param vc destination virtual channel\r
1040  * @param params byte array of command parameters\r
1041  * @param param_length length of the above array\r
1042  * @param bytes_to_read no of bytes to read (expected to arrive at buffer)\r
1043  * @param read_buffer pointer to 8-bit array to hold the read buffer words\r
1044  * return read_buffer_length\r
1045  * @note this function has an active delay to wait for the buffer to clear.\r
1046  * The delay is limited to 2 x DSIH_FIFO_ACTIVE_WAIT\r
1047  * (waiting for command buffer, and waiting for receiving)\r
1048  * @note this function will enable BTA\r
1049  */\r
1050 uint16_t mipi_dsih_gen_rd_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length, uint8_t bytes_to_read, uint8_t* read_buffer)\r
1051 {\r
1052         uint8_t data_type = 0;\r
1053         if (instance == 0)\r
1054         {\r
1055                 return 0;\r
1056         }\r
1057         if (instance->status != INITIALIZED)\r
1058         {\r
1059                 return 0;\r
1060         }\r
1061         switch(param_length)\r
1062         {\r
1063         case 0:\r
1064                 data_type = 0x04;\r
1065                 return mipi_dsih_gen_rd_packet(instance, vc, data_type, 0x00, 0x00, bytes_to_read, read_buffer);\r
1066         case 1:\r
1067                 data_type = 0x14;\r
1068                 return mipi_dsih_gen_rd_packet(instance, vc, data_type, 0x00, params[0], bytes_to_read, read_buffer);\r
1069         case 2:\r
1070                 data_type = 0x24;\r
1071                 return mipi_dsih_gen_rd_packet(instance, vc, data_type, params[1], params[0], bytes_to_read, read_buffer);\r
1072         default:\r
1073                 return 0;\r
1074         }\r
1075 }\r
1076 /**\r
1077  * Send READ packet to peripheral using the generic interface\r
1078  * This will force command mode and stop video mode (because of BTA)\r
1079  * @param instance pointer to structure holding the DSI Host core information\r
1080  * @param vc destination virtual channel\r
1081  * @param data_type generic command type\r
1082  * @param lsb_byte first command parameter\r
1083  * @param msb_byte second command parameter\r
1084  * @param bytes_to_read no of bytes to read (expected to arrive at buffer)\r
1085  * @param read_buffer pointer to 8-bit array to hold the read buffer words\r
1086  * return read_buffer_length\r
1087  * @note this function has an active delay to wait for the buffer to clear.\r
1088  * The delay is limited to 2 x DSIH_FIFO_ACTIVE_WAIT\r
1089  * (waiting for command buffer, and waiting for receiving)\r
1090  * @note this function will enable BTA\r
1091  */\r
1092 uint16_t mipi_dsih_gen_rd_packet(dsih_ctrl_t * instance, uint8_t vc, uint8_t data_type, uint8_t msb_byte, uint8_t lsb_byte, uint8_t bytes_to_read, uint8_t* read_buffer)\r
1093 {\r
1094         dsih_error_t err_code = OK;\r
1095         int timeout = 0;\r
1096         int counter = 0;\r
1097         int i = 0;\r
1098         int last_count = 0;\r
1099         uint32_t temp[1] = {0};\r
1100         if (instance == 0)\r
1101         {\r
1102                 return 0;\r
1103         }\r
1104         if (instance->status != INITIALIZED)\r
1105         {\r
1106                 return 0;\r
1107         }\r
1108         if (bytes_to_read < 1)\r
1109         {\r
1110                 return 0;\r
1111         }\r
1112         if (read_buffer == 0)\r
1113         {\r
1114                 return 0;\r
1115         }\r
1116 #ifndef FB_CHECK_ESD_IN_VFP\r
1117         /* make sure command mode is on */\r
1118         mipi_dsih_cmd_mode(instance, 1);\r
1119 #endif\r
1120         /* make sure receiving is enabled */\r
1121         mipi_dsih_hal_bta_en(instance, 1);\r
1122         /* listen to the same virtual channel as the one sent to */\r
1123         mipi_dsih_hal_gen_rd_vc(instance, vc);\r
1124         for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
1125         {       /* check if payload Tx fifo is not full */\r
1126                 if (!mipi_dsih_hal_gen_cmd_fifo_full(instance))\r
1127                 {\r
1128                         mipi_dsih_hal_gen_packet_header(instance, vc, data_type, msb_byte, lsb_byte);\r
1129                         break;\r
1130                 }\r
1131         }\r
1132         if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))\r
1133         {\r
1134                 if (instance->log_error != 0)\r
1135                 {\r
1136                         instance->log_error("sprdfb: tx rd command timed out");\r
1137                 }\r
1138                 return 0;\r
1139         }\r
1140         /* loop for the number of words to be read */\r
1141         for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
1142         {       /* check if command transaction is done */\r
1143                 if (!mipi_dsih_hal_gen_rd_cmd_busy(instance))\r
1144                 {\r
1145                         if (!mipi_dsih_hal_gen_read_fifo_empty(instance))\r
1146                         {\r
1147                                 for (counter = 0; (!mipi_dsih_hal_gen_read_fifo_empty(instance)); counter += 4)\r
1148                                 {\r
1149                                         err_code = mipi_dsih_hal_gen_read_payload(instance, temp);\r
1150                                         if (err_code)\r
1151                                         {\r
1152                                                 return 0;\r
1153                                         }\r
1154                                         if (counter < bytes_to_read)\r
1155                                         {\r
1156                                                 for (i = 0; i < 4; i++)\r
1157                                                 {\r
1158                                                         if ((counter + i) < bytes_to_read)\r
1159                                                         {\r
1160                                                                 /* put 32 bit temp in 4 bytes of buffer passed by user*/\r
1161                                                                 read_buffer[counter + i] = (uint8_t)(temp[0] >> (i * 8));\r
1162                                                                 last_count = i + counter;\r
1163                                                         }\r
1164                                                         else\r
1165                                                         {\r
1166                                                                 if ((uint8_t)(temp[0] >> (i * 8)) != 0x00)\r
1167                                                                 {\r
1168                                                                         last_count = i + counter;\r
1169                                                                 }\r
1170                                                         }\r
1171                                                 }\r
1172                                         }\r
1173                                         else\r
1174                                         {\r
1175                                                 last_count = counter;\r
1176                                                 for (i = 0; i < 4; i++)\r
1177                                                 {\r
1178                                                         if ((uint8_t)(temp[0] >> (i * 8)) != 0x00)\r
1179                                                         {\r
1180                                                                 last_count = i + counter;\r
1181                                                         }\r
1182                                                 }\r
1183                                         }\r
1184                                 }\r
1185                                 return last_count + 1;\r
1186                         }\r
1187 #ifdef FB_CHECK_ESD_IN_VFP\r
1188                        else if(timeout == (DSIH_FIFO_ACTIVE_WAIT - 1))//else\r
1189 #else\r
1190                        else\r
1191 #endif\r
1192                         {\r
1193                                 if (instance->log_error != 0)\r
1194                                 {\r
1195                                         instance->log_error("sprdfb: rx buffer empty");\r
1196                                 }\r
1197                                 return 0;\r
1198                         }\r
1199                 }\r
1200 #ifdef FB_CHECK_ESD_IN_VFP\r
1201                 udelay(5);\r
1202 #endif\r
1203         }\r
1204         if (instance->log_error != 0)\r
1205         {\r
1206                 instance->log_error("sprdfb: rx command timed out");\r
1207         }\r
1208         return 0;\r
1209 }\r
1210 /**\r
1211  * Dump values stored in the DSI host core registers\r
1212  * @param instance pointer to structure holding the DSI Host core information\r
1213  * @param all whether to dump all the registers, no register_config array need\r
1214  * be provided if dump is to standard IO\r
1215  * @param config array of register_config_t type where addresses and values are\r
1216  * stored\r
1217  * @param config_length the length of the config array\r
1218  * @return the number of the registers that were read\r
1219  */\r
1220 uint32_t mipi_dsih_dump_register_configuration(dsih_ctrl_t * instance, int all, register_config_t *config, uint16_t config_length)\r
1221 {\r
1222         uint32_t current0 = 0;\r
1223         uint16_t count = 0;\r
1224         if (instance == 0)\r
1225         {\r
1226                 return ERR_DSI_INVALID_INSTANCE;\r
1227         }\r
1228         if (instance->status != INITIALIZED)\r
1229         {\r
1230                 return ERR_DSI_INVALID_INSTANCE;\r
1231         }\r
1232         if (all)\r
1233         {       /* dump all registers */\r
1234                 for (current0 = R_DSI_HOST_VERSION; current0 <= R_DSI_HOST_PHY_TMR_LPCLK_CFG; count++, current0 += (R_DSI_HOST_PWR_UP - R_DSI_HOST_VERSION))\r
1235                 {\r
1236                         if ((config_length == 0) || (config == 0) || count >= config_length)\r
1237                         {       /* no place to write - write to STD IO */\r
1238                                 if (instance->log_info != 0)\r
1239                                 {\r
1240                                         instance->log_info("sprdfb: DSI 0x%lX:0x%lX", current0, mipi_dsih_read_word(instance, current0));\r
1241                                 }\r
1242                         }\r
1243                         else\r
1244                         {\r
1245                                 config[count].addr = current0;\r
1246                                 config[count].data = mipi_dsih_read_word(instance, current0);\r
1247                         }\r
1248                 }\r
1249         }\r
1250         else\r
1251         {\r
1252                 if(config == 0)\r
1253                 {\r
1254                         if (instance->log_error != 0)\r
1255                         {\r
1256                                 instance->log_error("sprdfb: invalid buffer");\r
1257                         }\r
1258                 }\r
1259                 else\r
1260                 {\r
1261                         for (count = 0; count < config_length; count++)\r
1262                         {\r
1263                                 config[count].data = mipi_dsih_read_word(instance, config[count].addr);\r
1264                         }\r
1265                 }\r
1266         }\r
1267         return count;\r
1268 }\r
1269 /**\r
1270  * Write values to DSI host core registers\r
1271  * @param instance pointer to structure holding the DSI Host core information\r
1272  * @param config array of register_config_t type where register addresses and\r
1273  * their new values are stored\r
1274  * @param config_length the length of the config array\r
1275  * @return the number of the registers that were written to\r
1276  */\r
1277 uint32_t mipi_dsih_write_register_configuration(dsih_ctrl_t * instance, register_config_t *config, uint16_t config_length)\r
1278 {\r
1279         uint16_t count = 0;\r
1280         if (instance == 0)\r
1281         {\r
1282                 return ERR_DSI_INVALID_INSTANCE;\r
1283         }\r
1284         if (instance->status != INITIALIZED)\r
1285         {\r
1286                 return ERR_DSI_INVALID_INSTANCE;\r
1287         }\r
1288         for (count = 0; count < config_length; count++)\r
1289         {\r
1290                 mipi_dsih_write_word(instance, config[count].addr, config[count].data);\r
1291         }\r
1292         return count;\r
1293 }\r
1294 /**\r
1295  * Register a handler for a specific event\r
1296  * - The handler will be called when this specific event occurs\r
1297  * @param instance pointer to structure holding the DSI Host core information\r
1298  * @param event enum\r
1299  * @param handler call back to handler function to handle the event\r
1300  * @return error code\r
1301  */\r
1302 dsih_error_t mipi_dsih_register_event(dsih_ctrl_t * instance, dsih_event_t event, void (*handler)(dsih_ctrl_t *, void *))\r
1303 {\r
1304         uint32_t mask = 1;\r
1305         uint32_t temp = 0;\r
1306         if (event >= DSI_MAX_EVENT)\r
1307         {\r
1308                 return ERR_DSI_INVALID_EVENT;\r
1309         }\r
1310         if (handler == 0)\r
1311         {\r
1312                 return ERR_DSI_INVALID_HANDLE;\r
1313         }\r
1314         if (instance == 0)\r
1315         {\r
1316                 return ERR_DSI_INVALID_INSTANCE;\r
1317         }\r
1318         if (instance->status != INITIALIZED)\r
1319         {\r
1320                 return ERR_DSI_INVALID_INSTANCE;\r
1321         }\r
1322         instance->event_registry[event] = handler;\r
1323         if (event < HS_CONTENTION)\r
1324         {\r
1325                 temp = mipi_dsih_hal_int_get_mask_0(instance, 0xffffffff);\r
1326                 temp &= ~(mask << event);\r
1327                 temp |= (0 & mask) << event;\r
1328                 mipi_dsih_hal_int_mask_0(instance, temp);\r
1329         }\r
1330         else\r
1331         {\r
1332                 temp = mipi_dsih_hal_int_get_mask_1(instance, 0xffffffff);\r
1333                 temp &= ~(mask << (event - HS_CONTENTION));\r
1334                 temp |= (0 & mask) << (event - HS_CONTENTION);\r
1335                 mipi_dsih_hal_int_mask_1(instance, temp);\r
1336                 if (event == RX_CRC_ERR)\r
1337                 {       /* automatically enable CRC reporting */\r
1338                         mipi_dsih_hal_gen_crc_rx_en(instance, 1);\r
1339                 }\r
1340         }\r
1341         return OK;\r
1342 }\r
1343 /**\r
1344  * Clear an already registered event\r
1345  * - Callback of the handler will be removed\r
1346  * @param instance pointer to structure holding the DSI Host core information\r
1347  * @param event enum\r
1348  * @return error code\r
1349  */\r
1350 dsih_error_t mipi_dsih_unregister_event(dsih_ctrl_t * instance, dsih_event_t event)\r
1351 {\r
1352         uint32_t mask = 1;\r
1353         uint32_t temp = 0;\r
1354     if (event >= DSI_MAX_EVENT)\r
1355         {\r
1356                 return ERR_DSI_INVALID_EVENT;\r
1357         }\r
1358         if (instance == 0)\r
1359         {\r
1360                 return ERR_DSI_INVALID_INSTANCE;\r
1361         }\r
1362         if (instance->status != INITIALIZED)\r
1363         {\r
1364                 return ERR_DSI_INVALID_INSTANCE;\r
1365         }\r
1366         instance->event_registry[event] = 0;\r
1367         if (event < HS_CONTENTION)\r
1368         {\r
1369                 temp = mipi_dsih_hal_int_get_mask_0(instance, 0xffffffff);\r
1370                 temp &= ~(mask << event);\r
1371                 temp |= (1 & mask) << event;\r
1372                 mipi_dsih_hal_int_mask_0(instance, temp);\r
1373         }\r
1374         else\r
1375         {\r
1376                 temp = mipi_dsih_hal_int_get_mask_1(instance, 0xffffffff);\r
1377                 temp &= ~(mask << (event - HS_CONTENTION));\r
1378                 temp |= (1 & mask) << (event - HS_CONTENTION);\r
1379                 mipi_dsih_hal_int_mask_1(instance, temp);\r
1380                 if (event == RX_CRC_ERR)\r
1381                 {       /* automatically disable CRC reporting */\r
1382                         mipi_dsih_hal_gen_crc_rx_en(instance, 0);\r
1383                 }\r
1384         }\r
1385         return OK;\r
1386 }\r
1387 /**\r
1388  * Clear all registered events at once\r
1389  * @param instance pointer to structure holding the DSI Host core information\r
1390  * @return error code\r
1391  */\r
1392 dsih_error_t mipi_dsih_unregister_all_events(dsih_ctrl_t * instance)\r
1393 {\r
1394         int i = 0;\r
1395         if (instance == 0)\r
1396         {\r
1397                 return ERR_DSI_INVALID_INSTANCE;\r
1398         }\r
1399         if (instance->status != INITIALIZED)\r
1400         {\r
1401                 return ERR_DSI_INVALID_INSTANCE;\r
1402         }\r
1403         for (i = 0; i < DSI_MAX_EVENT; i++)\r
1404         {\r
1405                 instance->event_registry[i] = 0;\r
1406         }\r
1407         mipi_dsih_hal_int_mask_0(instance, 0xffffff);\r
1408         mipi_dsih_hal_int_mask_1(instance, 0xffffff);\r
1409         /* automatically disable CRC reporting */\r
1410         mipi_dsih_hal_gen_crc_rx_en(instance, 0);\r
1411         return OK;\r
1412 }\r
1413 /**\r
1414  * This event handler shall be called upon receiving any event\r
1415  * it will call the specific callback (handler) registered for the invoking\r
1416  * event. Registration is done beforehand using mipi_dsih_register_event\r
1417  * its signature is void * so it could be OS agnostic (for it to be\r
1418  * registered in any OS/Interrupt controller)\r
1419  * @param param pointer to structure holding the DSI Host core information\r
1420  * @note This function must be registered with the DSI IRQs\r
1421  */\r
1422 void mipi_dsih_event_handler(void * param)\r
1423 {\r
1424         dsih_ctrl_t * instance = (dsih_ctrl_t *)(param);\r
1425         uint8_t i = 0;\r
1426     uint32_t status_0;\r
1427     uint32_t status_1;\r
1428 \r
1429         if (instance == 0)\r
1430         {\r
1431                 return;\r
1432         }\r
1433 \r
1434     status_0 = mipi_dsih_hal_int_status_0(instance, 0xffffffff);\r
1435     status_1 = mipi_dsih_hal_int_status_1(instance, 0xffffffff);\r
1436 \r
1437         for (i = 0; i < DSI_MAX_EVENT; i++)\r
1438         {\r
1439                 if (instance->event_registry[i] != 0)\r
1440                 {\r
1441                         if (i < HS_CONTENTION)\r
1442                         {\r
1443                                 if ((status_0 & (1 << i)) != 0)\r
1444                                 {\r
1445                                         instance->event_registry[i](instance, &i);\r
1446                                 }\r
1447                         }\r
1448                         else\r
1449                         {\r
1450                                 if ((status_1 & (1 << (i - HS_CONTENTION))) != 0)\r
1451                                 {\r
1452                                         instance->event_registry[i](instance, &i);\r
1453                                 }\r
1454                         }\r
1455                 }\r
1456         }\r
1457 }\r
1458 /**\r
1459  * Reset the DSI Host controller\r
1460  * - Sends a pulse to the shut down register\r
1461  * @param instance pointer to structure holding the DSI Host core information\r
1462  */\r
1463 void mipi_dsih_reset_controller(dsih_ctrl_t * instance)\r
1464 {\r
1465         mipi_dsih_hal_power(instance, 0);\r
1466         mipi_dsih_hal_power(instance, 1);\r
1467 }\r
1468 /**\r
1469  * Shut down the DSI Host controller\r
1470  * @param instance pointer to structure holding the DSI Host core information\r
1471  * @param shutdown (1) power up (0)\r
1472  */\r
1473 void mipi_dsih_shutdown_controller(dsih_ctrl_t * instance, int shutdown)\r
1474 {\r
1475         mipi_dsih_hal_power(instance, !shutdown);\r
1476 }\r
1477 /**\r
1478  * Reset the PHY module being controlled by the DSI Host controller\r
1479  * - Sends a pulse to the PPI reset signal\r
1480  * @param instance pointer to structure holding the DSI Host core information\r
1481  */\r
1482 void mipi_dsih_reset_phy(dsih_ctrl_t * instance)\r
1483 {\r
1484         mipi_dsih_dphy_reset(&(instance->phy_instance), 0);\r
1485         mipi_dsih_dphy_reset(&(instance->phy_instance), 1);\r
1486 }\r
1487 /**\r
1488  * Shut down the PHY module being controlled by the DSI Host controller\r
1489  * @param instance pointer to structure holding the DSI Host core information\r
1490  * @param shutdown (1) power up (0)\r
1491  */\r
1492 void mipi_dsih_shutdown_phy(dsih_ctrl_t * instance, int shutdown)\r
1493 {\r
1494         mipi_dsih_dphy_shutdown(&(instance->phy_instance), !shutdown);\r
1495 }\r
1496 \r
1497 /*\r
1498 sprd Aoke added for power saving while suspend\r
1499 */\r
1500 void mipi_dsih_ulps_mode(dsih_ctrl_t * instance, int en)\r
1501 {\r
1502         mipi_dsih_dphy_ulps_data_lanes(&(instance->phy_instance),en);\r
1503         mipi_dsih_dphy_ulps_clk_lane(&(instance->phy_instance),en);\r
1504 }\r
1505 /**\r
1506  * Configure the eDPI interface\r
1507  * - Programs the controller to receive pixels on the DPI interface and send them\r
1508  * as commands (write memory start and write memory continue) instead of a\r
1509  * video stream.\r
1510  * @param instance pointer to structure holding the DSI Host core information\r
1511  * @param video_params pointer to the command mode video parameters context\r
1512  * @param send_setup_packets whether to send the setup packets from given info. These are: 1 - set pixel format; 2 - set column address; 3 - set page address\r
1513  * @return error code\r
1514  */\r
1515 dsih_error_t mipi_dsih_edpi_video(dsih_ctrl_t * instance, dsih_cmd_mode_video_t *video_params, int send_setup_packets)\r
1516 {\r
1517         dsih_error_t err_code = OK;\r
1518         uint8_t buf[7] = {0};\r
1519         uint32_t bytes_per_pixel_x100 = 0;\r
1520         mipi_dsih_hal_dpi_video_vc(instance, video_params->virtual_channel);\r
1521         mipi_dsih_cmd_mode(instance, 1);\r
1522         err_code = mipi_dsih_hal_dpi_color_coding(instance, video_params->color_coding);\r
1523         /* define whether write memory commands will be sent in LP or HS */\r
1524         err_code = err_code? err_code: mipi_dsih_hal_dcs_wr_tx_type(instance, 3, video_params->lp); /* long packet*/\r
1525         if (send_setup_packets)\r
1526         {\r
1527                 /* define pixel packing format - 1 param */\r
1528                 buf[0] = 0x3A;\r
1529                 /* colour depth: table 6 DCS spec. 3:1| 8:2| 12:3| 16:5| 18:6| 24:7*/\r
1530                 switch (video_params->color_coding)\r
1531                 {\r
1532                 case 0:\r
1533                 case 1:\r
1534                 case 2:\r
1535                         buf[1] = 5;\r
1536                         break;\r
1537                 case 3:\r
1538                 case 4:\r
1539                         buf[1] = 6;\r
1540                         break;\r
1541                 default:\r
1542                         buf[1] = 7;\r
1543                         break;\r
1544                 }\r
1545                 err_code = err_code? err_code: mipi_dsih_dcs_wr_cmd(instance, video_params->virtual_channel, buf, 2);\r
1546                 if (err_code)\r
1547                 {\r
1548                         instance->log_error("sprdfb: error setting up command video - colour depth");\r
1549                 }\r
1550                 /* set column address (left to right) - 4 param */\r
1551                 buf[0] = 0x05; /* cmd length */\r
1552                 buf[1] = 0x00;\r
1553                 buf[2] = 0x2A; /* cmd opcode */\r
1554                 buf[3] = (uint8_t)(video_params->h_start >> 8); /* payload start */\r
1555                 buf[4] = (uint8_t)(video_params->h_start);\r
1556                 buf[5] = (uint8_t)(video_params->h_active_pixels >> 8);\r
1557                 buf[6] = (uint8_t)(video_params->h_active_pixels);\r
1558                 err_code = err_code? err_code: mipi_dsih_dcs_wr_cmd(instance, video_params->virtual_channel, buf, 7);\r
1559                 if (err_code)\r
1560                 {\r
1561                         instance->log_error("sprdfb: error setting up command video - set column address");\r
1562                 }\r
1563                 /* set page address (top to bottom) 4 - param*/\r
1564                 buf[0] = 0x05; /* cmd length */\r
1565                 buf[1] = 0x00;\r
1566                 buf[2] = 0x2B; /* cmd opcode */\r
1567                 buf[3] = (uint8_t)(video_params->v_start >> 8); /* payload start */\r
1568                 buf[4] = (uint8_t)(video_params->v_start);\r
1569                 buf[5] = (uint8_t)(video_params->v_active_lines >> 8);\r
1570                 buf[6] = (uint8_t)(video_params->v_active_lines);\r
1571                 err_code = err_code? err_code: mipi_dsih_dcs_wr_cmd(instance, video_params->virtual_channel, buf, 7);\r
1572                 if (err_code)\r
1573                 {\r
1574                         instance->log_error("sprdfb: error setting up command video - set page address");\r
1575                 }\r
1576         }\r
1577         switch (video_params->color_coding)\r
1578         {\r
1579         case COLOR_CODE_16BIT_CONFIG1:\r
1580         case COLOR_CODE_16BIT_CONFIG2:\r
1581         case COLOR_CODE_16BIT_CONFIG3:\r
1582                 bytes_per_pixel_x100 = 200;\r
1583                 break;\r
1584         case COLOR_CODE_18BIT_CONFIG1:\r
1585         case COLOR_CODE_18BIT_CONFIG2:\r
1586                 bytes_per_pixel_x100 = 225;\r
1587                 break;\r
1588         case COLOR_CODE_24BIT:\r
1589                 bytes_per_pixel_x100 = 300;\r
1590                 break;\r
1591         case COLOR_CODE_20BIT_YCC422_LOOSELY:\r
1592                 bytes_per_pixel_x100 = 250;\r
1593                 break;\r
1594         case COLOR_CODE_24BIT_YCC422:\r
1595                 bytes_per_pixel_x100 = 300;\r
1596                 break;\r
1597         case COLOR_CODE_16BIT_YCC422:\r
1598                 bytes_per_pixel_x100 = 200;\r
1599                 break;\r
1600         case COLOR_CODE_30BIT:\r
1601                 bytes_per_pixel_x100 = 375;\r
1602                 break;\r
1603         case COLOR_CODE_36BIT:\r
1604                 bytes_per_pixel_x100 = 450;\r
1605                 break;\r
1606         case COLOR_CODE_12BIT_YCC420:\r
1607                 bytes_per_pixel_x100 = 150;\r
1608                   break;\r
1609         default:\r
1610                 if (instance->log_error != 0)\r
1611                 {\r
1612                         instance->log_error("sprdfb: invalid color coding");\r
1613                 }\r
1614                 err_code = ERR_DSI_COLOR_CODING;\r
1615                 break;\r
1616         }\r
1617         if (video_params->te)\r
1618         {\r
1619                 mipi_dsih_hal_bta_en(instance, video_params->te);\r
1620                 /* enable tearing effect */\r
1621                 mipi_dsih_tear_effect_ack(instance, video_params->te);\r
1622                 buf[0] = 0x35;\r
1623                 err_code = mipi_dsih_dcs_wr_cmd(instance, video_params->virtual_channel, buf, 1);\r
1624         }\r
1625         mipi_dsih_dphy_enable_hs_clk(&(instance->phy_instance), 1);\r
1626         if ((((WORD_LENGTH * FIFO_DEPTH) * 100) / bytes_per_pixel_x100) > video_params->h_active_pixels)\r
1627         {\r
1628                 mipi_dsih_hal_edpi_max_allowed_size(instance, video_params->h_active_pixels);\r
1629         }\r
1630         else\r
1631         {\r
1632                 mipi_dsih_hal_edpi_max_allowed_size(instance, (((WORD_LENGTH * FIFO_DEPTH) * 100) / bytes_per_pixel_x100));\r
1633         }\r
1634         return err_code;\r
1635 }\r
1636 \r
1637 /* PRESP Time outs */\r
1638 /**\r
1639  * Timeout for peripheral (for controller to stay still) after LP data\r
1640  * transmission write requests\r
1641  * @param instance pointer to structure holding the DSI Host core information\r
1642  * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the\r
1643  * link still, after sending a low power write operation. This period is\r
1644  * measured in cycles of lanebyteclk\r
1645  */\r
1646 void mipi_dsih_presp_timeout_low_power_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)\r
1647 {\r
1648         mipi_dsih_hal_presp_timeout_low_power_write(instance, no_of_byte_cycles);\r
1649 }\r
1650 /**\r
1651  * Timeout for peripheral (for controller to stay still) after LP data\r
1652  * transmission read requests\r
1653  * @param instance pointer to structure holding the DSI Host core information\r
1654  * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the\r
1655  * link still, after sending a low power read operation. This period is\r
1656  * measured in cycles of lanebyteclk\r
1657  */\r
1658 void mipi_dsih_presp_timeout_low_power_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)\r
1659 {\r
1660         mipi_dsih_hal_presp_timeout_low_power_read(instance, no_of_byte_cycles);\r
1661 }\r
1662 /**\r
1663  * Timeout for peripheral (for controller to stay still) after HS data\r
1664  * transmission write requests\r
1665  * @param instance pointer to structure holding the DSI Host core information\r
1666  * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the\r
1667  * link still, after sending a high-speed write operation. This period is\r
1668  * measured in cycles of lanebyteclk\r
1669  */\r
1670 void mipi_dsih_presp_timeout_high_speed_write(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)\r
1671 {\r
1672         mipi_dsih_hal_presp_timeout_high_speed_write(instance, no_of_byte_cycles);\r
1673 }\r
1674 /**\r
1675  * Timeout for peripheral between HS data transmission read requests\r
1676  * @param instance pointer to structure holding the DSI Host core information\r
1677  * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the\r
1678  * link still, after sending a high-speed read operation. This period is\r
1679  * measured in cycles of lanebyteclk\r
1680  */\r
1681 void mipi_dsih_presp_timeout_high_speed_read(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)\r
1682 {\r
1683         mipi_dsih_hal_presp_timeout_high_speed_read(instance, no_of_byte_cycles);\r
1684 }\r
1685 /**\r
1686  * Timeout for peripheral (for controller to stay still) after bus turn around\r
1687  * @param instance pointer to structure holding the DSI Host core information\r
1688  * @param no_of_byte_cycles period for which the DWC_mipi_dsi_host keeps the\r
1689  * link still, after sending a BTA operation. This period is\r
1690  * measured in cycles of lanebyteclk\r
1691  */\r
1692 void mipi_dsih_presp_timeout_bta(dsih_ctrl_t * instance, uint16_t no_of_byte_cycles)\r
1693 {\r
1694         mipi_dsih_hal_presp_timeout_bta(instance, no_of_byte_cycles);\r
1695 }\r
1696 uint16_t mipi_dsih_check_dbi_fifos_state(dsih_ctrl_t * instance)\r
1697 {\r
1698         uint16_t cnt = 0;\r
1699         while( cnt < 5000 && mipi_dsih_read_word(instance, R_DSI_HOST_CMD_PKT_STATUS) != 0x15)\r
1700         {\r
1701                 cnt ++;\r
1702         }\r
1703         return (mipi_dsih_read_word(instance, R_DSI_HOST_CMD_PKT_STATUS) != 0x15) ? -1 : 1;\r
1704 }\r
1705 uint16_t mipi_dsih_check_ulpm_mode(dsih_ctrl_t * instance)\r
1706 {\r
1707         return (mipi_dsih_read_word(instance, R_DSI_HOST_PHY_STATUS) != 0x1528) ? -1 : 1;\r
1708 }\r