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