tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / video / sprdfb / dsi_1_10a / mipi_dsih_api.c
1 \r
2 #include "mipi_dsih_api.h"\r
3 #include "mipi_dsih_hal.h"\r
4 #include "mipi_dsih_dphy.h"\r
5 /* whether to get debug messages (1) or not (0) */\r
6 #define DEBUG                   0\r
7 \r
8 #define PRECISION_FACTOR        1000\r
9 #define VIDEO_PACKET_OVERHEAD   6\r
10 #define NULL_PACKET_OVERHEAD    6\r
11 #define SHORT_PACKET            4\r
12 #define BLANKING_PACKET         6\r
13 #define MAX_NULL_SIZE           1023\r
14 \r
15 static const uint32_t mipi_dsih_supported_versions[] = {0x3130302A, 0x3130312A, 0x3131302A};\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 /*\r
20 func:mipi_dsih_set_lp_clock\r
21 desc:in low-power mode, max PHY frequency should smaller than 20MHz,\r
22      in synopsys IP, low-power clock divide from high-speed clock,\r
23      this function is designed to adapt low-power clock to various high-speed clock.\r
24 arithmetic:\r
25      Fhs : high-speed frequence\r
26      Flp : low-power frequence\r
27      div : mipi_dsih_hal_tx_escape_division() param, byte clock unit.\r
28      because of the 20MHz demand, Flp == Fhs/(div*8) <= 20 MHz, here 500000 present 500MHz, so MHz equal 1000\r
29      so div >= { Fhs/(20Mhz*8) == Fhs/(20000*8) == (Fhs>>4)/10000 }\r
30 */\r
31 static void mipi_dsih_set_lp_clock(dsih_ctrl_t * instance)\r
32 {\r
33         uint32_t tx_escape_division = 1;\r
34         tx_escape_division = (instance->phy_feq>>4);\r
35         tx_escape_division = (tx_escape_division+9999)/10000;//ceiling calc\r
36         if (instance->log_info != 0)\r
37         {\r
38                 instance->log_info("sprdfb:[%s]: lp frequence div:%d\n", __FUNCTION__, tx_escape_division);\r
39         }\r
40         mipi_dsih_hal_tx_escape_division(instance, (uint8_t)tx_escape_division);\r
41 }\r
42 \r
43 dsih_error_t mipi_dsih_open(dsih_ctrl_t * instance)\r
44 {\r
45     dsih_error_t err = OK;\r
46     uint32_t version = 0;\r
47     int i = 0;\r
48 \r
49      if (instance == 0)\r
50     {\r
51         return ERR_DSI_INVALID_INSTANCE;\r
52     }\r
53     else if ((instance->core_read_function == 0) || (instance->core_write_function == 0))\r
54     {\r
55         return ERR_DSI_INVALID_IO;\r
56     }\r
57     else if (instance->status == INITIALIZED)\r
58     {\r
59         return ERR_DSI_INVALID_INSTANCE;\r
60     }\r
61     else if (mipi_dsih_dphy_open(&(instance->phy_instance)))\r
62     {\r
63         return ERR_DSI_PHY_INVALID;\r
64     }\r
65     else\r
66     {\r
67         instance->status = NOT_INITIALIZED;\r
68         version = mipi_dsih_hal_get_version(instance);\r
69         for (i = 0; i < mipi_dsih_no_of_versions; i++)\r
70         {\r
71             if (version == mipi_dsih_supported_versions[i])\r
72             {\r
73                 break;\r
74             }\r
75         }\r
76         /* no matching supported version has been found*/\r
77         if (i >= mipi_dsih_no_of_versions)\r
78         {\r
79             if (instance->log_info != 0)\r
80             {\r
81                 instance->log_info("driver does not support this core version 0x%lX", version);\r
82             }\r
83             return ERR_DSI_CORE_INCOMPATIBLE;\r
84         }\r
85     }\r
86     //mipi_dsih_hal_power(instance, 0);//Jessica\r
87     //mipi_dsih_hal_power(instance, 1);//Jessica\r
88     mipi_dsih_hal_dpi_color_mode_pol(instance, !instance->color_mode_polarity);\r
89     mipi_dsih_hal_dpi_shut_down_pol(instance, !instance->shut_down_polarity);\r
90     err = mipi_dsih_phy_hs2lp_config(instance, instance->max_hs_to_lp_cycles);\r
91     err |=  mipi_dsih_phy_lp2hs_config(instance, instance->max_lp_to_hs_cycles);\r
92     err |= mipi_dsih_phy_bta_time(instance, instance->max_bta_cycles);\r
93     if (err)\r
94     {\r
95         return ERR_DSI_OVERFLOW;\r
96     }\r
97     /* by default, return to LP during ALL, unless otherwise specified*/\r
98     mipi_dsih_hal_dpi_lp_during_hfp(instance, 1);\r
99     mipi_dsih_hal_dpi_lp_during_hbp(instance, 1);\r
100     mipi_dsih_hal_dpi_lp_during_vactive(instance, 1);\r
101     mipi_dsih_hal_dpi_lp_during_vfp(instance, 1);\r
102     mipi_dsih_hal_dpi_lp_during_vbp(instance, 1);\r
103     mipi_dsih_hal_dpi_lp_during_vsync(instance, 1);\r
104     /* by default, all commands are sent in LP */\r
105     mipi_dsih_hal_dcs_wr_tx_type(instance, 0, 1);\r
106     mipi_dsih_hal_dcs_wr_tx_type(instance, 1, 1);\r
107     mipi_dsih_hal_dcs_wr_tx_type(instance, 3, 1); /* long packet*/\r
108     mipi_dsih_hal_dcs_rd_tx_type(instance, 0, 1);\r
109     /*Jessica add to support max rd packet size command*/\r
110     mipi_dsih_hal_max_rd_packet_size_type(instance, 1);\r
111     mipi_dsih_hal_gen_wr_tx_type(instance, 0, 1);\r
112     mipi_dsih_hal_gen_wr_tx_type(instance, 1, 1);\r
113     mipi_dsih_hal_gen_wr_tx_type(instance, 2, 1);\r
114     mipi_dsih_hal_gen_wr_tx_type(instance, 3, 1); /* long packet*/\r
115     mipi_dsih_hal_gen_rd_tx_type(instance, 0, 1);\r
116     mipi_dsih_hal_gen_rd_tx_type(instance, 1, 1);\r
117     mipi_dsih_hal_gen_rd_tx_type(instance, 2, 1);\r
118     /* by default, RX_VC = 0, NO EOTp, EOTn, BTA, ECC rx and CRC rx */\r
119     mipi_dsih_hal_gen_rd_vc(instance, 0);\r
120     mipi_dsih_hal_gen_eotp_rx_en(instance, 0);\r
121     mipi_dsih_hal_gen_eotp_tx_en(instance, 0);\r
122     mipi_dsih_hal_bta_en(instance, 0);\r
123     mipi_dsih_hal_gen_ecc_rx_en(instance, 0);\r
124     mipi_dsih_hal_gen_crc_rx_en(instance, 0);\r
125     mipi_dsih_hal_power(instance, 0);//Jessica\r
126     mipi_dsih_hal_power(instance, 1);//Jessica\r
127     /* initialize pll so escape clocks could be generated at 864MHz, 1 lane */\r
128     /* however the high speed clock will not be requested */\r
129     //err = mipi_dsih_dphy_configure(&(instance->phy_instance), 1, DEFAULT_BYTE_CLOCK);\r
130     #if 0/*Jessica*/\r
131     err = mipi_dsih_dphy_configure(&(instance->phy_instance), instance->max_lanes, 190*1000);\r
132     if (err)\r
133     {\r
134         return err; /* ERR_DSI_PHY_POWERUP; */\r
135     }\r
136     #endif\r
137     /* dividing by 6 is aimed for max PHY frequency, 1GHz */\r
138     //mipi_dsih_hal_tx_escape_division(instance, 4); //6    //Jessica\r
139     mipi_dsih_set_lp_clock(instance);\r
140     instance->status = INITIALIZED;\r
141     return OK;\r
142 }\r
143 dsih_error_t mipi_dsih_close(dsih_ctrl_t * instance)\r
144 {\r
145     if (instance == 0)\r
146     {\r
147         return ERR_DSI_INVALID_INSTANCE;\r
148     }\r
149     if (instance->status != INITIALIZED)\r
150     {\r
151         return ERR_DSI_INVALID_INSTANCE;\r
152     }\r
153     mipi_dsih_dphy_close(&(instance->phy_instance));\r
154     mipi_dsih_hal_power(instance, 0);\r
155     return OK;\r
156 }\r
157 void mipi_dsih_allow_return_to_lp(dsih_ctrl_t * instance, int hfp, int hbp, int vactive, int vfp, int vbp, int vsync)\r
158 {\r
159     if(0 == instance)\r
160     {\r
161         return;\r
162     }\r
163 \r
164     if (instance->status == INITIALIZED)\r
165     {\r
166         mipi_dsih_hal_dpi_lp_during_hfp(instance, hfp);\r
167         mipi_dsih_hal_dpi_lp_during_hbp(instance, hbp);\r
168         mipi_dsih_hal_dpi_lp_during_vactive(instance, vactive);\r
169         mipi_dsih_hal_dpi_lp_during_vfp(instance, vfp);\r
170         mipi_dsih_hal_dpi_lp_during_vbp(instance, vbp);\r
171         mipi_dsih_hal_dpi_lp_during_vsync(instance, vsync);\r
172         return;\r
173     }\r
174 \r
175     if (instance->log_error != 0)\r
176     {\r
177         instance->log_error("invalid instance");\r
178     }\r
179 }\r
180 void mipi_dsih_dcs_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read)\r
181 {\r
182     if(0 == instance)\r
183     {\r
184         return;\r
185     }\r
186 \r
187     if (instance->status == INITIALIZED)\r
188     {\r
189         mipi_dsih_hal_dcs_wr_tx_type(instance, 0, short_write);\r
190         mipi_dsih_hal_dcs_wr_tx_type(instance, 1, short_write);\r
191         mipi_dsih_hal_dcs_wr_tx_type(instance, 3, long_write); /* long packet*/\r
192         mipi_dsih_hal_dcs_rd_tx_type(instance, 0, short_read);\r
193         return;\r
194     }\r
195     \r
196     if (instance->log_error != 0)\r
197     {\r
198         instance->log_error("invalid instance");\r
199     }\r
200 }\r
201 void mipi_dsih_gen_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read)\r
202 {\r
203     if(0 == instance)\r
204     {\r
205         return;\r
206     }\r
207     \r
208     if (instance->status == INITIALIZED)\r
209     {\r
210         mipi_dsih_hal_gen_wr_tx_type(instance, 0, short_write);\r
211         mipi_dsih_hal_gen_wr_tx_type(instance, 1, short_write);\r
212         mipi_dsih_hal_gen_wr_tx_type(instance, 2, short_write);\r
213         mipi_dsih_hal_gen_wr_tx_type(instance, 3, long_write); /* long packet*/\r
214         mipi_dsih_hal_gen_rd_tx_type(instance, 0, short_read);\r
215         mipi_dsih_hal_gen_rd_tx_type(instance, 1, short_read);\r
216         mipi_dsih_hal_gen_rd_tx_type(instance, 2, short_read);\r
217         return;\r
218     }\r
219     \r
220     if (instance->log_error != 0)\r
221     {\r
222         instance->log_error("invalid instance");\r
223     }\r
224 }\r
225 /* packet handling */\r
226 dsih_error_t mipi_dsih_enable_rx(dsih_ctrl_t * instance, int enable)\r
227 {\r
228     mipi_dsih_hal_bta_en(instance, enable);\r
229     return OK;\r
230 }\r
231 dsih_error_t mipi_dsih_peripheral_ack(dsih_ctrl_t * instance, int enable)\r
232 {\r
233     if (instance != 0)\r
234     {\r
235         if (instance->status == INITIALIZED)\r
236         {\r
237             mipi_dsih_hal_cmd_ack_en(instance, enable);\r
238             if (enable)\r
239             {\r
240                 mipi_dsih_hal_bta_en(instance, 1);\r
241             }\r
242             return OK;\r
243         }\r
244     }\r
245     return ERR_DSI_INVALID_INSTANCE;\r
246 }\r
247 dsih_error_t mipi_dsih_tear_effect_ack(dsih_ctrl_t * instance, int enable)\r
248 {\r
249     if (instance != 0)\r
250     {\r
251         if (instance->status == INITIALIZED)\r
252         {\r
253             mipi_dsih_hal_tear_effect_ack_en(instance, enable);\r
254             if (enable)\r
255             {\r
256                 mipi_dsih_hal_bta_en(instance, 1);\r
257             }\r
258             return OK;\r
259         }\r
260     }\r
261     return ERR_DSI_INVALID_INSTANCE;\r
262 }\r
263 dsih_error_t mipi_dsih_eotp_rx(dsih_ctrl_t * instance, int enable)\r
264 {\r
265     if (instance != 0)\r
266     {\r
267         if (instance->status == INITIALIZED)\r
268         {\r
269             mipi_dsih_hal_gen_eotp_rx_en(instance, enable);\r
270             if (enable)\r
271             {\r
272                 mipi_dsih_hal_bta_en(instance, 1);\r
273             }\r
274             return OK;\r
275         }\r
276     }\r
277     return ERR_DSI_INVALID_INSTANCE;\r
278 }\r
279 dsih_error_t mipi_dsih_ecc_rx(dsih_ctrl_t * instance, int enable)\r
280 {\r
281     if (instance != 0)\r
282     {\r
283         if (instance->status == INITIALIZED)\r
284         {\r
285             mipi_dsih_hal_gen_ecc_rx_en(instance, enable);\r
286             if (enable)\r
287             {\r
288                 mipi_dsih_hal_bta_en(instance, 1);\r
289             }\r
290             return OK;\r
291         }\r
292     }\r
293     return ERR_DSI_INVALID_INSTANCE;\r
294 }\r
295 dsih_error_t mipi_dsih_eotp_tx(dsih_ctrl_t * instance, int enable)\r
296 {\r
297     if (instance != 0)\r
298     {\r
299         if (instance->status == INITIALIZED)\r
300         {\r
301             mipi_dsih_hal_gen_eotp_tx_en(instance, enable);\r
302             return OK;\r
303         }\r
304     }\r
305     return ERR_DSI_INVALID_INSTANCE;\r
306 }\r
307 dsih_error_t mipi_dsih_dpi_video(dsih_ctrl_t * instance, dsih_dpi_video_t * video_params)\r
308 {\r
309     dsih_error_t err_code = OK;\r
310     uint16_t bytes_per_pixel_x100 = 0; /* bpp x 100 because it can be 2.25 */\r
311     uint16_t video_size = 0;\r
312     uint32_t ratio_clock_xPF = 0; /* holds dpi clock/byte clock times precision factor */\r
313     uint16_t null_packet_size = 0;\r
314     uint8_t video_size_step = 1;\r
315     uint32_t hs_timeout = 0;\r
316     uint32_t total_bytes = 0;\r
317     uint32_t bytes_per_chunk = 0;\r
318     uint32_t no_of_chunks = 0;\r
319     uint32_t bytes_left = 0;\r
320     uint32_t chunk_overhead = 0;\r
321     int counter = 0;\r
322     /* check DSI controller instance */\r
323     if ((instance == 0) || (video_params == 0))\r
324     {\r
325         return ERR_DSI_INVALID_INSTANCE;\r
326     }\r
327     if (instance->status != INITIALIZED)\r
328     {\r
329         return ERR_DSI_INVALID_INSTANCE;\r
330     }\r
331     /* set up phy pll to required lane clock */\r
332     //begin--frank \r
333     //err_code = mipi_dsih_dphy_configure(&(instance->phy_instance), video_params->no_of_lanes, video_params->byte_clock * 8);\r
334     //if (err_code)\r
335     //{\r
336     //    return err_code;\r
337     //}\r
338     //end--frank\r
339     ratio_clock_xPF = (video_params->byte_clock * PRECISION_FACTOR) / (video_params->pixel_clock);\r
340     video_size = video_params->h_active_pixels;\r
341     /* set up ACKs and error reporting */\r
342     mipi_dsih_hal_dpi_frame_ack_en(instance, video_params->receive_ack_packets);\r
343     if (video_params->receive_ack_packets)\r
344     { /* if ACK is requested, enable BTA, otherwise leave as is */\r
345         mipi_dsih_hal_bta_en(instance, 1);\r
346     }\r
347     mipi_dsih_hal_gen_cmd_mode_en(instance, 0);\r
348     mipi_dsih_hal_dpi_video_mode_en(instance, 1);\r
349     /* get bytes per pixel and video size step (depending if loosely or not */\r
350     switch (video_params->color_coding)\r
351     {\r
352         case COLOR_CODE_16BIT_CONFIG1:\r
353         case COLOR_CODE_16BIT_CONFIG2:\r
354         case COLOR_CODE_16BIT_CONFIG3:\r
355             bytes_per_pixel_x100 = 200;\r
356             video_size_step = 1;\r
357             break;\r
358         case COLOR_CODE_18BIT_CONFIG1:\r
359         case COLOR_CODE_18BIT_CONFIG2:\r
360             mipi_dsih_hal_dpi_18_loosely_packet_en(instance, video_params->is_18_loosely);\r
361             bytes_per_pixel_x100 = 225;\r
362             if (!video_params->is_18_loosely)\r
363             { /* 18bits per pixel and NOT loosely, packets should be multiples of 4 */\r
364                 video_size_step = 4;\r
365                 /* round up active H pixels to a multiple of 4 */\r
366                 for (; (video_size % 4) != 0; video_size++)\r
367                 {\r
368                     ;\r
369                 }\r
370             }\r
371             else\r
372             {\r
373                 video_size_step = 1;\r
374             }\r
375             break;\r
376         case COLOR_CODE_24BIT:\r
377             bytes_per_pixel_x100 = 300;\r
378             video_size_step = 1;\r
379             break;\r
380         default:\r
381             if (instance->log_error != 0)\r
382             {\r
383                 instance->log_error("invalid color coding");\r
384             }\r
385             err_code = ERR_DSI_COLOR_CODING;\r
386             break;\r
387     }\r
388     if (err_code == OK)\r
389     {\r
390         err_code = mipi_dsih_hal_dpi_color_coding(instance, video_params->color_coding);\r
391     }\r
392     if (err_code != OK)\r
393     {\r
394         return err_code;\r
395     }\r
396     mipi_dsih_hal_dpi_video_mode_type(instance, video_params->video_mode);\r
397     mipi_dsih_hal_dpi_hline(instance, (uint16_t)(((video_params->h_total_pixels) * ratio_clock_xPF) / PRECISION_FACTOR));\r
398     mipi_dsih_hal_dpi_hbp(instance, ((video_params->h_back_porch_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
399     mipi_dsih_hal_dpi_hsa(instance, ((video_params->h_sync_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
400     mipi_dsih_hal_dpi_vactive(instance, video_params->v_active_lines);\r
401     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
402     mipi_dsih_hal_dpi_vbp(instance, video_params->v_back_porch_lines);\r
403     mipi_dsih_hal_dpi_vsync(instance, video_params->v_sync_lines);\r
404     mipi_dsih_hal_dpi_hsync_pol(instance, !video_params->h_polarity);\r
405     mipi_dsih_hal_dpi_vsync_pol(instance, !video_params->v_polarity);\r
406     mipi_dsih_hal_dpi_dataen_pol(instance, !video_params->data_en_polarity);\r
407     /* HS timeout */\r
408     hs_timeout = ((video_params->h_total_pixels * video_params->v_active_lines) + (DSIH_PIXEL_TOLERANCE * bytes_per_pixel_x100) / 100);\r
409     for (counter = 0x80; (counter < hs_timeout) && (counter > 2); counter--)\r
410     {\r
411         if ((hs_timeout % counter) == 0)\r
412         {\r
413             mipi_dsih_hal_timeout_clock_division(instance, counter);\r
414             mipi_dsih_hal_lp_rx_timeout(instance, (uint16_t)(hs_timeout / counter));\r
415             mipi_dsih_hal_hs_tx_timeout(instance, (uint16_t)(hs_timeout / counter));\r
416             break;\r
417         }\r
418     }\r
419     /* TX_ESC_CLOCK_DIV must be less than 20000KHz */\r
420     //mipi_dsih_hal_tx_escape_division(instance, 4); //6 //Jessica\r
421     mipi_dsih_set_lp_clock(instance);\r
422     /* video packetisation */\r
423     if (video_params->video_mode == VIDEO_BURST_WITH_SYNC_PULSES)\r
424     { /* BURST */\r
425         mipi_dsih_hal_dpi_null_packet_en(instance, 0);\r
426         mipi_dsih_hal_dpi_multi_packet_en(instance, 0);\r
427         err_code = mipi_dsih_hal_dpi_null_packet_size(instance, 0);\r
428         err_code = err_code? err_code: mipi_dsih_hal_dpi_chunks_no(instance, 1);\r
429         err_code = err_code? err_code: mipi_dsih_hal_dpi_video_packet_size(instance, video_size);\r
430         if (err_code != OK)\r
431         {\r
432             return err_code;\r
433         }\r
434         /* BURST by default, returns to LP during ALL empty periods - energy saving */\r
435         mipi_dsih_hal_dpi_lp_during_hfp(instance, 1);\r
436 #if (defined(CONFIG_SC8830) ||defined(CONFIG_SC9630)) && (defined(CONFIG_LCD_720P) || defined(CONFIG_LCD_HD))//LiWei add CONFIG_LCD_HD\r
437                 mipi_dsih_hal_dpi_lp_during_hbp(instance, 0);\r
438 #else\r
439                 mipi_dsih_hal_dpi_lp_during_hbp(instance, 1);\r
440 #endif\r
441         mipi_dsih_hal_dpi_lp_during_vactive(instance, 1);\r
442         mipi_dsih_hal_dpi_lp_during_vfp(instance, 1);\r
443         mipi_dsih_hal_dpi_lp_during_vbp(instance, 1);\r
444         mipi_dsih_hal_dpi_lp_during_vsync(instance, 1);\r
445 #if DEBUG\r
446         /*      D E B U G       */\r
447         if (instance->log_info != 0)\r
448         {\r
449             instance->log_info("burst video");\r
450             instance->log_info("h line time %ld", (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
451             instance->log_info("video_size %ld", video_size);\r
452         }\r
453 #endif\r
454     }\r
455     else\r
456     {   /* non burst transmission */\r
457         null_packet_size = 0;\r
458         /* bytes to be sent - first as one chunk*/\r
459         bytes_per_chunk = (bytes_per_pixel_x100 * video_params->h_active_pixels) / 100 + VIDEO_PACKET_OVERHEAD;\r
460         /* bytes being received through the DPI interface per byte clock cycle */\r
461         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
462         /* check if the in pixels actually fit on the DSI link */\r
463         if (total_bytes >= bytes_per_chunk)\r
464         {\r
465             chunk_overhead = total_bytes - bytes_per_chunk;\r
466             /* overhead higher than 1 -> enable multi packets */\r
467             if (chunk_overhead > 1)\r
468             {   /* MULTI packets */\r
469                 for (video_size = video_size_step; video_size < video_params->h_active_pixels; video_size += video_size_step)\r
470                 {   /* determine no of chunks */\r
471                     if ((((video_params->h_active_pixels * PRECISION_FACTOR) / video_size) % PRECISION_FACTOR) == 0)\r
472                     {\r
473                         no_of_chunks = video_params->h_active_pixels / video_size;\r
474                         bytes_per_chunk = (bytes_per_pixel_x100 * video_size) / 100 + VIDEO_PACKET_OVERHEAD;\r
475                         if (total_bytes >= (bytes_per_chunk * no_of_chunks))\r
476                         {\r
477                             bytes_left = total_bytes - (bytes_per_chunk * no_of_chunks);\r
478                             break;\r
479                         }\r
480                     }\r
481                 }\r
482                 /* prevent overflow (unsigned - unsigned) */\r
483                 if (bytes_left > (NULL_PACKET_OVERHEAD * no_of_chunks))\r
484                 {\r
485                     null_packet_size = (bytes_left - (NULL_PACKET_OVERHEAD * no_of_chunks)) / no_of_chunks;\r
486                     if (null_packet_size > MAX_NULL_SIZE)\r
487                     {   /* avoid register overflow */\r
488                         null_packet_size = MAX_NULL_SIZE;\r
489                     }\r
490                 }\r
491             }\r
492             else\r
493             {   /* no multi packets */\r
494                 no_of_chunks = 1;\r
495 #if DEBUG\r
496                 /*      D E B U G       */\r
497                 if (instance->log_info != 0)\r
498                 {\r
499                     instance->log_info("no multi no null video");\r
500                     instance->log_info("h line time %ld", (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));\r
501                     instance->log_info("video_size %ld", video_size);\r
502                 }\r
503                 /************************/\r
504 #endif\r
505                 /* video size must be a multiple of 4 when not 18 loosely */\r
506                 for (video_size = video_params->h_active_pixels; (video_size % video_size_step) != 0; video_size++)\r
507                 {\r
508                     ;\r
509                 }\r
510             }\r
511         }\r
512         else\r
513         {\r
514             instance->log_error("resolution cannot be sent to display through current settings");\r
515             err_code = ERR_DSI_OVERFLOW;\r
516         }\r
517     }\r
518     err_code = err_code? err_code: mipi_dsih_hal_dpi_chunks_no(instance, no_of_chunks);\r
519     err_code = err_code? err_code: mipi_dsih_hal_dpi_video_packet_size(instance, video_size);\r
520     err_code = err_code? err_code: mipi_dsih_hal_dpi_null_packet_size(instance, null_packet_size);\r
521     mipi_dsih_hal_dpi_null_packet_en(instance, null_packet_size > 0? 1: 0);\r
522     mipi_dsih_hal_dpi_multi_packet_en(instance, (no_of_chunks > 1)? 1: 0);\r
523 #if DEBUG\r
524     /*      D E B U G       */\r
525     if (instance->log_info != 0)\r
526     {\r
527         instance->log_info("total_bytes %d", total_bytes);\r
528         instance->log_info("bytes_per_chunk %d", bytes_per_chunk);\r
529         instance->log_info("bytes left %d", bytes_left);\r
530         instance->log_info("null packets %d", null_packet_size);\r
531         instance->log_info("chunks %ld", no_of_chunks);\r
532         instance->log_info("video_size %ld", video_size);\r
533     }\r
534     /************************/\r
535 #endif\r
536     mipi_dsih_hal_dpi_video_vc(instance, video_params->virtual_channel);\r
537     mipi_dsih_dphy_no_of_lanes(&(instance->phy_instance), video_params->no_of_lanes);\r
538     /* enable high speed clock */\r
539 //    mipi_dsih_dphy_enable_hs_clk(&(instance->phy_instance), 1);\r
540     return err_code;\r
541 }\r
542 dsih_error_t mipi_dsih_dcs_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length)\r
543 {\r
544     uint8_t packet_type = 0;\r
545 //    int i = 0;\r
546     if (params == 0)\r
547     {\r
548         return ERR_DSI_OUT_OF_BOUND;\r
549     }\r
550 #if 0\r
551     if (param_length > 2)\r
552     {\r
553         i = 2;\r
554     }\r
555     switch (params[i])\r
556     {\r
557         case 0x39:\r
558         case 0x38:\r
559         case 0x34:\r
560         case 0x29:\r
561         case 0x28:\r
562         case 0x21:\r
563         case 0x20:\r
564         case 0x13:\r
565         case 0x12:\r
566         case 0x11:\r
567         case 0x10:\r
568         case 0x01:\r
569         case 0x00:\r
570             packet_type = 0x05; /* DCS short write no param */\r
571             break;\r
572         case 0x3A:\r
573         case 0x36:\r
574         case 0x35:\r
575         case 0x26:\r
576             packet_type = 0x15; /* DCS short write 1 param */\r
577             break;\r
578         case 0x44:\r
579         case 0x3C:\r
580         case 0x37:\r
581         case 0x33:\r
582         case 0x30:\r
583         case 0x2D:\r
584         case 0x2C:\r
585         case 0x2B:\r
586         case 0x2A:\r
587             packet_type = 0x39; /* DCS long write/write_LUT command packet */\r
588             break;\r
589         default:\r
590             if (instance->log_error != 0)\r
591             {\r
592                 instance->log_error("invalid DCS command");\r
593             }\r
594             return ERR_DSI_INVALID_COMMAND;\r
595     }\r
596 #endif\r
597         switch(param_length)\r
598         {\r
599                 case 1:\r
600                         packet_type = 0x05; /* DCS short write no param */\r
601                         break;\r
602                 case 2:\r
603                         packet_type = 0x15; /* DCS short write 1 param */\r
604                         break;\r
605                 default:\r
606                         packet_type = 0x39; /* DCS long write/write_LUT command packet */\r
607                         break;\r
608         }\r
609 \r
610     return mipi_dsih_gen_wr_packet(instance, vc, packet_type, params, param_length);\r
611 }\r
612 void mipi_dsih_cmd_mode(dsih_ctrl_t * instance, int en)\r
613 {\r
614     if(0 == instance)\r
615     {\r
616         return;\r
617     }\r
618     \r
619     if (instance->status == INITIALIZED)\r
620     {\r
621         if ((!mipi_dsih_hal_gen_is_cmd_mode(instance)) && en)\r
622         {   /* disable video mode first */\r
623             mipi_dsih_hal_dpi_video_mode_en(instance, 0);\r
624             mipi_dsih_hal_gen_cmd_mode_en(instance, 1);\r
625         }\r
626         else if ((mipi_dsih_hal_gen_is_cmd_mode(instance)) && !en)\r
627         {\r
628             mipi_dsih_hal_gen_cmd_mode_en(instance, 0);\r
629         }\r
630         return;\r
631     }\r
632         \r
633     if (instance->log_error != 0)\r
634     {\r
635         instance->log_error("invalid instance");\r
636     }\r
637 }\r
638 void mipi_dsih_video_mode(dsih_ctrl_t * instance, int en)\r
639 {\r
640     if(0 == instance)\r
641     {\r
642         return;\r
643     }\r
644     \r
645     if (instance->status == INITIALIZED)\r
646     {\r
647         if ((!mipi_dsih_hal_dpi_is_video_mode(instance)) && en)\r
648         {   /* disable cmd mode first */\r
649             mipi_dsih_hal_gen_cmd_mode_en(instance, 0);\r
650             mipi_dsih_hal_dpi_video_mode_en(instance, 1);\r
651         }\r
652         else if ((!mipi_dsih_hal_dpi_is_video_mode(instance)) && !en)\r
653         {\r
654             mipi_dsih_hal_dpi_video_mode_en(instance, 0);\r
655         }\r
656         return;\r
657     }\r
658     \r
659     if (instance->log_error != 0)\r
660     {\r
661         instance->log_error("invalid instance");\r
662     }\r
663 }\r
664 int mipi_dsih_active_mode(dsih_ctrl_t * instance)\r
665 {\r
666     if (mipi_dsih_hal_gen_is_cmd_mode(instance))\r
667     {\r
668         return 1;\r
669     }\r
670     else if (mipi_dsih_hal_dpi_is_video_mode(instance))\r
671     {\r
672         return 2;\r
673     }\r
674     return 0;\r
675 }\r
676 dsih_error_t mipi_dsih_gen_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length)\r
677 {\r
678     uint8_t data_type = 0;\r
679     switch(param_length)\r
680     {\r
681         case 0:\r
682             data_type = 0x03;\r
683             break;\r
684         case 1:\r
685             data_type = 0x13;\r
686             break;\r
687         case 2:\r
688             data_type = 0x23;\r
689             break;\r
690         default:\r
691             data_type = 0x29;\r
692             break;\r
693     }\r
694     return mipi_dsih_gen_wr_packet(instance, vc, data_type, params, param_length);\r
695 }\r
696 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
697 {\r
698     dsih_error_t err_code = OK;\r
699     /* active delay iterator */\r
700     int timeout = 0;\r
701     /* iterators */\r
702     int i = 0;\r
703     int j = 0;\r
704     /* holds padding bytes needed */\r
705     int compliment_counter = 0;\r
706     uint8_t* payload = 0;\r
707     /* temporary variable to arrange bytes into words */\r
708     uint32_t temp = 0;\r
709     uint16_t word_count = 0;\r
710     if (instance == 0)\r
711     {\r
712         return ERR_DSI_INVALID_INSTANCE;\r
713     }\r
714     if (instance->status != INITIALIZED)\r
715     {\r
716         return ERR_DSI_INVALID_INSTANCE;\r
717     }\r
718     if ((params == 0) && (param_length != 0)) /* pointer NULL */\r
719     {\r
720         return ERR_DSI_OUT_OF_BOUND;\r
721     }\r
722     if (param_length > 2)\r
723     {   /* long packet - write word count to header, and the rest to payload */\r
724         payload = params + (2 * sizeof(params[0]));\r
725         word_count = (params[1] << 8) | params[0];\r
726         if ((param_length - 2) < word_count)\r
727         {\r
728             if (instance->log_error != 0)\r
729             {\r
730                 instance->log_error("sent > input payload. complemented with zeroes");\r
731             }\r
732             compliment_counter = (param_length - 2) - word_count;\r
733         }\r
734         else if ((param_length - 2) > word_count)\r
735         {\r
736             if (instance->log_error != 0)\r
737             {\r
738                 instance->log_error("Overflow - input > sent. payload truncated");\r
739             }\r
740         }\r
741         for (i = 0; i < (param_length - 2); i += j)\r
742         {\r
743             temp = 0;\r
744             for (j = 0; (j < 4) && ((j + i) < (param_length - 2)); j++)\r
745             {   /* temp = (payload[i + 3] << 24) | (payload[i + 2] << 16) | (payload[i + 1] << 8) | payload[i]; */\r
746                 temp |= payload[i + j] << (j * 8);\r
747             }\r
748             /* check if payload Tx fifo is not full */\r
749             for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
750             {\r
751                 if (!mipi_dsih_hal_gen_packet_payload(instance, temp))\r
752                 {\r
753                     break;\r
754                 }\r
755             }\r
756             if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))\r
757             {\r
758                 return ERR_DSI_TIMEOUT;\r
759             }\r
760         }\r
761         /* if word count entered by the user more than actual parameters received\r
762          * fill with zeroes - a fail safe mechanism, otherwise controller will\r
763          * want to send data from an empty buffer */\r
764         for (i = 0; i < compliment_counter; i++)\r
765         {\r
766             /* check if payload Tx fifo is not full */\r
767             for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
768             {\r
769                 if (!mipi_dsih_hal_gen_packet_payload(instance, 0x00))\r
770                 {\r
771                     break;\r
772                 }\r
773             }\r
774             if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))\r
775             {\r
776                 return ERR_DSI_TIMEOUT;\r
777             }\r
778         }\r
779     }\r
780     for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
781     {\r
782         /* check if payload Tx fifo is not full */\r
783         if (!mipi_dsih_hal_gen_cmd_fifo_full(instance))\r
784         {\r
785             if (param_length == 0)\r
786             {\r
787                 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, 0x0, 0x0);\r
788             }\r
789             else if (param_length == 1)\r
790             {\r
791                 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, 0x0, params[0]);\r
792             }\r
793             else\r
794             {\r
795                 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, params[1], params[0]);\r
796             }\r
797             break;\r
798         }\r
799     }\r
800     if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))\r
801     {\r
802         err_code = ERR_DSI_TIMEOUT;\r
803     }\r
804     return err_code;\r
805 }\r
806 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
807 {\r
808     if (instance == 0)\r
809     {\r
810         return 0;\r
811     }\r
812     if (instance->status != INITIALIZED)\r
813     {\r
814         return 0;\r
815     }\r
816     switch (command)\r
817     {\r
818         case 0xA8:\r
819         case 0xA1:\r
820         case 0x45:\r
821         case 0x3E:\r
822         case 0x2E:\r
823         case 0x0F:\r
824         case 0x0E:\r
825         case 0x0D:\r
826         case 0x0C:\r
827         case 0x0B:\r
828         case 0x0A:\r
829         case 0x08:\r
830         case 0x07:\r
831         case 0x06:\r
832             /* COMMAND_TYPE 0x06 - DCS Read no params refer to DSI spec p.47 */\r
833             return mipi_dsih_gen_rd_packet(instance, vc, 0x06, 0x0, command, bytes_to_read, read_buffer);\r
834         default:\r
835             if (instance->log_error != 0)\r
836             {\r
837                 instance->log_error("invalid DCS command");\r
838             }\r
839             return 0;\r
840     }\r
841     return 0;\r
842 }\r
843 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
844 {\r
845     uint8_t data_type = 0;\r
846     if (instance == 0)\r
847     {\r
848         return 0;\r
849     }\r
850     if (instance->status != INITIALIZED)\r
851     {\r
852         return 0;\r
853     }\r
854     switch(param_length)\r
855     {\r
856         case 0:\r
857             data_type = 0x04;\r
858             return mipi_dsih_gen_rd_packet(instance, vc, data_type, 0x00, 0x00, bytes_to_read, read_buffer);\r
859         case 1:\r
860             data_type = 0x14;\r
861             return mipi_dsih_gen_rd_packet(instance, vc, data_type, 0x00, params[0], bytes_to_read, read_buffer);\r
862         case 2:\r
863             data_type = 0x24;\r
864             return mipi_dsih_gen_rd_packet(instance, vc, data_type, params[1], params[0], bytes_to_read, read_buffer);\r
865         default:\r
866             return 0;\r
867     }\r
868 }\r
869 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
870 {\r
871     dsih_error_t err_code = OK;\r
872     int timeout = 0;\r
873     int counter = 0;\r
874     int i = 0;\r
875     int last_count = 0;\r
876     uint32_t temp[1] = {0};\r
877     if (instance == 0)\r
878     {\r
879         return 0;\r
880     }\r
881     if (instance->status != INITIALIZED)\r
882     {\r
883         return 0;\r
884     }\r
885     if (bytes_to_read < 1)\r
886     {\r
887         return 0;\r
888     }\r
889     if (read_buffer == 0)\r
890     {\r
891         return 0;\r
892     }\r
893     /* make sure command mode is on */\r
894     mipi_dsih_cmd_mode(instance, 1);\r
895     /* make sure receiving is enabled */\r
896     mipi_dsih_hal_bta_en(instance, 1);\r
897     /* listen to the same virtual channel as the one sent to */\r
898     mipi_dsih_hal_gen_rd_vc(instance, vc);\r
899     for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
900     {   /* check if payload Tx fifo is not full */\r
901         if (!mipi_dsih_hal_gen_cmd_fifo_full(instance))\r
902         {\r
903             mipi_dsih_hal_gen_packet_header(instance, vc, data_type, msb_byte, lsb_byte);\r
904             break;\r
905         }\r
906     }\r
907     if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))\r
908     {\r
909         if (instance->log_error != 0)\r
910         {\r
911             instance->log_error("tx rd command timed out");\r
912         }\r
913         return 0;\r
914     }\r
915     /* loop for the number of words to be read */\r
916     for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)\r
917     {   /* check if command transaction is done */\r
918         if (!mipi_dsih_hal_gen_rd_cmd_busy(instance))\r
919         {\r
920             if (!mipi_dsih_hal_gen_read_fifo_empty(instance))\r
921             {\r
922                 for (counter = 0; (!mipi_dsih_hal_gen_read_fifo_empty(instance)); counter += 4)\r
923                 {\r
924                         err_code = mipi_dsih_hal_gen_read_payload(instance, temp);\r
925                         if (err_code)\r
926                         {\r
927                             return 0;\r
928                         }\r
929                     if (counter < bytes_to_read)\r
930                     {\r
931                         for (i = 0; i < 4; i++)\r
932                         {\r
933                             if ((counter + i) < bytes_to_read)\r
934                             {\r
935                                 /* put 32 bit temp in 4 bytes of buffer passed by user*/\r
936                                 read_buffer[counter + i] = (uint8_t)(temp[0] >> (i * 8));\r
937                                 last_count = i + counter;\r
938                             }\r
939                             else\r
940                             {\r
941                                 if ((uint8_t)(temp[0] >> (i * 8)) != 0x00)\r
942                                 {\r
943                                     last_count = i + counter;\r
944                                 }\r
945                             }\r
946                         }\r
947                     }\r
948                     else\r
949                     {\r
950                         last_count = counter;\r
951                         for (i = 0; i < 4; i++)\r
952                         {\r
953                             if ((uint8_t)(temp[0] >> (i * 8)) != 0x00)\r
954                             {\r
955                                 last_count = i + counter;\r
956                             }\r
957                         }\r
958                     }\r
959                 }\r
960                 return last_count + 1;\r
961             }\r
962             else\r
963             {\r
964                 if (instance->log_error != 0)\r
965                 {\r
966                     instance->log_error("rx buffer empty");\r
967                 }\r
968                 return 0;\r
969             }\r
970         }\r
971     }\r
972     if (instance->log_error != 0)\r
973     {\r
974         instance->log_error("rx command timed out");\r
975     }\r
976     return 0;\r
977 }\r
978 uint32_t mipi_dsih_dump_register_configuration(dsih_ctrl_t * instance, int all, register_config_t *config, uint16_t config_length)\r
979 {\r
980     uint32_t current = 0;\r
981     uint16_t count = 0;\r
982     if (instance == 0)\r
983     {\r
984         return ERR_DSI_INVALID_INSTANCE;\r
985     }\r
986     if (instance->status != INITIALIZED)\r
987     {\r
988         return ERR_DSI_INVALID_INSTANCE;\r
989     }\r
990     if (all)\r
991     {   /* dump all registers */\r
992         for (current = R_DSI_HOST_VERSION; current <= R_DSI_HOST_ERROR_MSK1; count++, current += (R_DSI_HOST_PWR_UP - R_DSI_HOST_VERSION))\r
993         {\r
994             if ((config_length == 0) || (config == 0) || count >= config_length)\r
995             {   /* no place to write - write to STD IO */\r
996                 if (instance->log_info != 0)\r
997                 {\r
998                     instance->log_info("DSI 0x%lX:0x%lX", current, mipi_dsih_read_word(instance, current));\r
999                 }\r
1000             }\r
1001             else\r
1002             {\r
1003                 config[count].addr = current;\r
1004                 config[count].data = mipi_dsih_read_word(instance, current);\r
1005             }\r
1006         }\r
1007     }\r
1008     else\r
1009     {\r
1010         if(config == 0)\r
1011         {\r
1012             if (instance->log_error != 0)\r
1013             {\r
1014                 instance->log_error("invalid buffer");\r
1015             }\r
1016         }\r
1017         else\r
1018         {\r
1019             for (count = 0; count < config_length; count++)\r
1020             {\r
1021                 config[count].data = mipi_dsih_read_word(instance, config[count].addr);\r
1022             }\r
1023         }\r
1024     }\r
1025     return count;\r
1026 }\r
1027 uint32_t mipi_dsih_write_register_configuration(dsih_ctrl_t * instance, register_config_t *config, uint16_t config_length)\r
1028 {\r
1029     uint16_t count = 0;\r
1030     if (instance == 0)\r
1031     {\r
1032         return ERR_DSI_INVALID_INSTANCE;\r
1033     }\r
1034     if (instance->status != INITIALIZED)\r
1035     {\r
1036         return ERR_DSI_INVALID_INSTANCE;\r
1037     }\r
1038     for (count = 0; count < config_length; count++)\r
1039     {\r
1040         mipi_dsih_write_word(instance, config[count].addr, config[count].data);\r
1041     }\r
1042     return count;\r
1043 }\r
1044 dsih_error_t mipi_dsih_register_event(dsih_ctrl_t * instance, dsih_event_t event, void (*handler)(dsih_ctrl_t *, void *))\r
1045 {\r
1046     uint32_t mask = 1;\r
1047     uint32_t temp = 0;\r
1048     if (event >= DSI_MAX_EVENT)\r
1049     {\r
1050         return ERR_DSI_INVALID_EVENT;\r
1051     }\r
1052     if (handler == 0)\r
1053     {\r
1054         return ERR_DSI_INVALID_HANDLE;\r
1055     }\r
1056     if (instance == 0)\r
1057     {\r
1058         return ERR_DSI_INVALID_INSTANCE;\r
1059     }\r
1060     if (instance->status != INITIALIZED)\r
1061     {\r
1062         return ERR_DSI_INVALID_INSTANCE;\r
1063     }\r
1064     instance->event_registry[event] = handler;\r
1065     if (event < HS_CONTENTION)\r
1066     {\r
1067         temp = mipi_dsih_hal_get_error_mask_0(instance, 0xffffffff);\r
1068         temp &= ~(mask << event);\r
1069         temp |= (0 & mask) << event;\r
1070         mipi_dsih_hal_error_mask_0(instance, temp);\r
1071     }\r
1072     else\r
1073     {\r
1074         temp = mipi_dsih_hal_get_error_mask_1(instance, 0xffffffff);\r
1075         temp &= ~(mask << (event - HS_CONTENTION));\r
1076         temp |= (0 & mask) << (event - HS_CONTENTION);\r
1077         mipi_dsih_hal_error_mask_1(instance, temp);\r
1078         if (event == RX_CRC_ERR)\r
1079         {   /* automatically enable CRC reporting */\r
1080             mipi_dsih_hal_gen_crc_rx_en(instance, 1);\r
1081         }\r
1082     }\r
1083     return OK;\r
1084 }\r
1085 dsih_error_t mipi_dsih_unregister_event(dsih_ctrl_t * instance, dsih_event_t event)\r
1086 {\r
1087     uint32_t mask = 1;\r
1088     uint32_t temp = 0;\r
1089     if (event >= DSI_MAX_EVENT)\r
1090     {\r
1091         return ERR_DSI_INVALID_EVENT;\r
1092     }\r
1093     if (instance == 0)\r
1094     {\r
1095         return ERR_DSI_INVALID_INSTANCE;\r
1096     }\r
1097     if (instance->status != INITIALIZED)\r
1098     {\r
1099         return ERR_DSI_INVALID_INSTANCE;\r
1100     }\r
1101     instance->event_registry[event] = 0;\r
1102     if (event < HS_CONTENTION)\r
1103     {\r
1104         temp = mipi_dsih_hal_get_error_mask_0(instance, 0xffffffff);\r
1105         temp &= ~(mask << event);\r
1106         temp |= (1 & mask) << event;\r
1107         mipi_dsih_hal_error_mask_0(instance, temp);\r
1108     }\r
1109     else\r
1110     {\r
1111         temp = mipi_dsih_hal_get_error_mask_1(instance, 0xffffffff);\r
1112         temp &= ~(mask << (event - HS_CONTENTION));\r
1113         temp |= (1 & mask) << (event - HS_CONTENTION);\r
1114         mipi_dsih_hal_error_mask_1(instance, temp);\r
1115         if (event == RX_CRC_ERR)\r
1116         {   /* automatically disable CRC reporting */\r
1117             mipi_dsih_hal_gen_crc_rx_en(instance, 0);\r
1118         }\r
1119     }\r
1120     return OK;\r
1121 }\r
1122 dsih_error_t mipi_dsih_unregister_all_events(dsih_ctrl_t * instance)\r
1123 {\r
1124     int i = 0;\r
1125     if (instance == 0)\r
1126     {\r
1127         return ERR_DSI_INVALID_INSTANCE;\r
1128     }\r
1129     if (instance->status != INITIALIZED)\r
1130     {\r
1131         return ERR_DSI_INVALID_INSTANCE;\r
1132     }\r
1133     for (i = 0; i < DSI_MAX_EVENT; i++)\r
1134     {\r
1135         instance->event_registry[i] = 0;\r
1136     }\r
1137     mipi_dsih_hal_error_mask_0(instance, 0xffffff);\r
1138     mipi_dsih_hal_error_mask_1(instance, 0xffffff);\r
1139     /* automatically disable CRC reporting */\r
1140     mipi_dsih_hal_gen_crc_rx_en(instance, 0);\r
1141     return OK;\r
1142 }\r
1143 void mipi_dsih_event_handler(void * param)\r
1144 {\r
1145     dsih_ctrl_t * instance = (dsih_ctrl_t *)(param);\r
1146     uint8_t i = 0;\r
1147     uint32_t status_0;\r
1148     uint32_t status_1;\r
1149     if (instance == 0)\r
1150     {\r
1151         return;\r
1152     }\r
1153 \r
1154     status_0 = mipi_dsih_hal_error_status_0(instance, 0xffffffff);\r
1155     status_1 = mipi_dsih_hal_error_status_1(instance, 0xffffffff);\r
1156 \r
1157     for (i = 0; i < DSI_MAX_EVENT; i++)\r
1158     {\r
1159         if (instance->event_registry[i] != 0)\r
1160         {\r
1161             if (i < HS_CONTENTION)\r
1162             {\r
1163                 if ((status_0 & (1 << i)) != 0)\r
1164                 {\r
1165                     instance->event_registry[i](instance, &i);\r
1166                 }\r
1167             }\r
1168             else\r
1169             {\r
1170                 if ((status_1 & (1 << (i - HS_CONTENTION))) != 0)\r
1171                 {\r
1172                     instance->event_registry[i](instance, &i);\r
1173                 }\r
1174             }\r
1175         }\r
1176     }\r
1177 }\r
1178 void mipi_dsih_reset_controller(dsih_ctrl_t * instance)\r
1179 {\r
1180     mipi_dsih_hal_power(instance, 0);\r
1181     mipi_dsih_hal_power(instance, 1);\r
1182 }\r
1183 void mipi_dsih_shutdown_controller(dsih_ctrl_t * instance, int shutdown)\r
1184 {\r
1185     mipi_dsih_hal_power(instance, !shutdown);\r
1186 }\r
1187 void mipi_dsih_reset_phy(dsih_ctrl_t * instance)\r
1188 {\r
1189     mipi_dsih_dphy_reset(&(instance->phy_instance), 0);\r
1190     mipi_dsih_dphy_reset(&(instance->phy_instance), 1);\r
1191 }\r
1192 void mipi_dsih_shutdown_phy(dsih_ctrl_t * instance, int shutdown)\r
1193 {\r
1194     mipi_dsih_dphy_shutdown(&(instance->phy_instance), !shutdown);\r
1195 }\r
1196 \r